PyroCMS Attachment

PyroCMS Attachment

README

The Blog module in PyroCMS has good features and a very interesting interface to create/edit contents in a common (or maybe complex, why not) website, but it missing something: a featured image field. You already know many posts in this blog have an image which represent the content of it, however this field it doesn’t exists in the original PyroCMS Blog module.

This is how to create a new field to add/edit data in an existing module of PyroCMS, I hope this post can help you to understand more the facility of this CMS in a project development, trust me, when you get in touch with CodeIgniter and PyroCMS you won’t use anymore other CMS systems.

Code

I will add a new field called attachment_id into the table of blogs and after the column category_id, I’ll use the Module::upgrade() function to ALTER the table, but to execute this method I need to change the number version of the module; after this I will click the button Upgrade in the Add-ons

…
public $version = '2.6';

public function upgrade($old_version){
    $this->dbforge->add_column(
        'blog',
        array(
            'attachment_id' => array(
                'type' => 'INT',
                'constraint' => 11,
                'default' => 0,
            )
        ),
        'category_id'
    );

    return true;
}
…

Now I will add a validation rule to the admin.php controller of the blog module:

protected $validation_rules = array(
    …
    array(
        'field' => 'attachment_id',
        'label' => 'lang:blog:attachment',
        'rules' => 'trim',
    )
    …
);

In the file views/admin/form.php I’ll write a short HTML code to add a Hidden input field which will keep the identifier of the last attachment file (preventing a data lost if I don’t upload a new file), and a form_upload field to upload new files. Additionally I’ll use an image object to show the current attachment file (if it’s an image) in the edition view using the controller Files and its method Thumb with a numeric parameter specifying the width of the thumbnail:

…
<li>
    <label for="attachment_id">Attachment</label>

    <div class="input">
        <?php echo form_hidden('attachment_id', $post->attachment_id); ?>
        <?php echo form_upload('attachment_id', $post->attachment_id, 'class="width-20" style="float:left"'); ?>
        <?php if ($post->attachment_id > 0) : ?>
            <img src='echo base_url("files/thumb/{$post->attachment_id}/300")' alt="thumb image" style="float:left;margin-left:20px" />
        <?php endif; ?>
    </div>
</li>
…

Load in the constructor of the controller Blog::Admin this code to load some libraries like the Files library:

…
$this->load->library(
    array(
        'keywords/keywords',
        'form_validation',
        'files/files',
    )
);
…

Upload the attachment file with the following code, write it after the $this->form_validation->run() execution and before the $this->blog_m->insert(…); take a look to the variable $this->attachment_folder this should be a protected property in the blog administration controller with the value equal to the identifier of the folder where the Files::upload method will associate the file:

protected $attachment_folder = 1;
…
$attachment = Files::upload(
    $this->attachment_folder,
    $this->input->post('slug'),
    'attachment_id'
);

Add in the $this->blog_m->insert(…) execution of the Blog::Admin::create() function this sentence to add in the database table the value of the identifier associated with the file uploaded:

$this->blog_m->insert(array(
    …
    'attachment_id' => $attachment['status'] ? $attachment['data']['id'] : 0,
    …
));

Finally, I’ll use this code to update the attachment_id field, keeping safe the identifier of the last file uploaded and associated to the post; If the user are uploading a new attachment file, the code will check the filesize of it and will upload/replace the last file associated; but I need to add a new index in the array which are being updated in the Blog::Admin::edit() function:

$attachment_id = $this->input->post('attachment_id');
if( $_FILES['attachment_id']['size']>0 ){
    $attachment = Files::upload(
        $this->attachment_folder,
        $this->input->post('slug'),
        'attachment_id'
    );
    if( $attachment['status'] ){
        $attachment_id = $attachment['data']['id'];
    }
}
…
$result = $this->blog_m->update($id, array(
    …
    'attachment_id' => $attachment_id,
    …
));
Do you have a project idea? Let's make it together!