Resource Library

To manage resources use resource library. It is designed to

  • upload files
  • add resource code ( youtube html, image html etc )
  • manage resources
  • assign resources to different objects like products, manufacturers, categories, downloads etc

We have following resource types

  • image
  • audio
  • video
  • pdf
  • archive


Example of extension that use resource library

We will create slideshow extension. It will have following features:

  • manage slides
  • slides will use image resources from resource library
  • add block to layout
  • example of how to add styles/scripts that needed for extension

Here we will have a part of extension source. You can take a look at full code by downloading our free template. This extension is a part of template.

- create extensions/slideshow folder - create extensions/slideshow/config.xml

<?xml version="1.0"?>
<extension>
  	<id>slideshow</id>
  	<version>1.0</version>
  	<cartversions>
        	<item>0.9</item>
        <item>1.0</item>
  	</cartversions>
  	<priority>30</priority>
  	<type>extension</type>
  	<category>blocks</category>
  	<settings>
        	<item id="slideshow_status">
              	<type>checkbox</type>
              	<default_value>0</default_value>
        	</item>
        	<item id="slideshow_x">
              	<type>input</type>
              	<default_value>544</default_value>
        	</item>
        	<item id="slideshow_y">
              	<type>input</type>
              	<default_value>305</default_value>
        	</item>
  	</settings>
  	<additional_settings><![CDATA[blocks/slideshow]]></additional_settings>
  	<note>true</note>
  	<install>
        	<sql>install.sql</sql>
        	<trigger>install.php</trigger>
  	</install>
  	<uninstall>
        <sql>uninstall.sql</sql>
        	<trigger>uninstall.php</trigger>
  	</uninstall>
</extension>

In config we define size of slide ( slideshow_x, slideshow_y ) <additional_settings> tag define link for extension controller that will manage slides <note>true</note> - mean that will have description note for extension that will be shown on extension edit page. Note text is defined in language file with definition key = slideshow_note

- create install.sql. Table will keep slide img and slide url

CREATE TABLE IF NOT EXISTS `ac_slides` (
  	`slide_id` int(11) NOT NULL AUTO_INCREMENT,
  	`slide_img` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '',
  	`slide_url` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '',
  	PRIMARY KEY (`slide_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1;

INSERT INTO `ac_slides` ( `slide_img`, `slide_url` ) VALUES ( 'slides/slide1.jpg', 'http://google.com' );
INSERT INTO `ac_slides` ( `slide_img`, `slide_url` ) VALUES ( 'slides/slide2.jpg', 'http://bing.com' );
INSERT INTO `ac_slides` ( `slide_img`, `slide_url` ) VALUES ( 'slides/slide3.jpg', 'http://msn.com' );


- create uninstall.sql


DROP TABLE IF EXISTS `ac_slides`;


- create install.php. Here we will add block to layout. Container for our block will be content_top


<?php
if ( !defined ( 'DIR_CORE' )) {
  	header ( 'Location: static_pages/' );
}

$layout = new ALayoutManager();
$block_data = array(
    'block_txt_id' => 'slideshow',
    'controller' => 'blocks/slideshow',
    'templates' => array(
        array(
            'parent_block_txt_id' => 'content_top',
            'template' => 'blocks/slideshow.tpl',
        ),
	),
);
$layout->saveBlock( $block_data );


- create uninstall.php

<?php
if ( !defined ( 'DIR_CORE' )) {
  	header ( 'Location: static_pages/' );
}

// delete block
$layout = new ALayoutManager();
$layout->deleteBlock('slideshow');


- create image folder. Here we will have o icon.png – extension icon 
slides/slide1.jpg, slides/slide2.jpg, slides/slide3.jpg – default slides

- create main.php. Here we will define extension resources

<?php
if ( !defined ( 'DIR_CORE' )) {
  	header ( 'Location: static_pages/' );
}

$controllers = array(
    'storefront' => array(
        'blocks/slideshow',
	),
    'admin' => array(
        'pages/blocks/slideshow',
	),
);

$models = array(
    'storefront' => array(
        'slideshow/slideshow',
	),
    'admin' => array(
        'slideshow/slideshow',
	),
);

$languages = array(
    'storefront' => array(),
    'admin' => array(
        'slideshow/slideshow',
	),
);

$templates = array(
    'storefront' => array(
        'blocks/slideshow.tpl',
	),
    'admin' => array(
        'pages/blocks/slideshow_list.tpl',
        'pages/blocks/slideshow_form.tpl',
	),
);

 

Our extension will have

  • 2 controllers – one for admin to manage slides, one for storefront to prepare data for slideshow
  • One language file
  • A couple of templates
  • Two models. Model for storefront has only methods to retrieve data. Model for admin has methods to add/edit/delete items


  • Create language file – extensions/slideshow/admin/language/english/slideshow/slideshow.xml
<?xml version="1.0"?>
<definitions>
  	<definition>
        	<key>slideshow_name</key>
        	<value><![CDATA[slideshow]]></value>
  	</definition>
    <definition>
        	<key>slides_title</key>
        	<value><![CDATA[Edit Slides]]></value>
  	</definition>
    <definition>
        	<key>button_remove</key>
        	<value><![CDATA[Remove]]></value>
  	</definition>
    <definition>
        	<key>button_edit</key>
        	<value><![CDATA[Edit]]></value>
  	</definition>
    <definition>
        	<key>button_add_slide</key>
        	<value><![CDATA[Add Slide]]></value>
  	</definition>
    <definition>
        	<key>text_slide</key>
        	<value><![CDATA[Slide]]></value>
  	</definition>
    <definition>
        	<key>text_success</key>
        	<value><![CDATA[You successfully modified slides]]></value>
  	</definition>
    <definition>
        	<key>entry_img</key>
        	<value><![CDATA[Image]]></value>
  	</definition>
    <definition>
        	<key>entry_url</key>
        	<value><![CDATA[Url]]></value>
  	</definition>
  	<definition>
        	<key>slideshow_status</key>
        	<value><![CDATA[Status]]></value>
  	</definition>
  	<definition>
        	<key>slideshow_status_0</key>
        	<value><![CDATA[Disabled]]></value>
  	</definition>
  	<definition>
        	<key>slideshow_status_1</key>
        	<value><![CDATA[Enabled]]></value>
  	</definition>
  	<definition>
        	<key>slideshow_x</key>
        	<value><![CDATA[Slide Width]]></value>
  	</definition>
  	<definition>
        	<key>slideshow_y</key>
        	<value><![CDATA[Slide Height]]></value>
  	</definition>
    <definition>
        	<key>text_additional_settings</key>
        	<value><![CDATA[ Edit Slides]]></value>
  	</definition>
  	<definition>
        	<key>slideshow_note</key>
        	<value><![CDATA[To add slideshow to your template : <br/>
        	- go to Design > <a href="#admin#rt=design/layout" target="_layout">Layout</a> <br/>
        	- choose layout you want to add slideshow to<br/>
        	- add it to content_top section
        	<br/>
        	<br/>
        	<b>To access 'Edit slides' page you need to enable extension</b><br/>
        	To edit slides:
        	- click on 'Edit slides' button in top bar<br/>
        	- or <a href="#admin#rt=blocks/slideshow" target="_slideshow">click here</a>
        	]]></value>
  	</definition>
</definitions>

Please note that we have definition key for every extension setting. We also override advanced settings button text and add note. 
In note we use link

<a href="#admin#rt=design/layout" target="_layout">Layout</a>

This link contain two parts
- #admin – application section
- #rt=design/layout – route path

- Now add models. First create model for storefront
extensions\slideshow\storefront\model\slideshow\slideshow.php

if (! defined ( 'DIR_CORE' )) {
  	header ( 'Location: static_pages/' );
}
class ModelSlideshowSlideshow extends Model {

    protected $model_tool_image;
    protected $slide;
    protected $rm;

    public function __construct($registry) {
        parent::__construct($registry);
        $this->model_tool_image = $this->registry->get('model_tool_image');
  		$this->slide = array(
        		'x' => $this->registry->get('config')->get('slideshow_x'),
        		'y' => $this->registry->get('config')->get('slideshow_y'),
  		);
        $this->rm = new AResource('image');
  	}

    public function getSlides() {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "slides");
  		$result = $query->rows;
  		foreach ( $result as $key => $img ) {
              	$result[$key]['slide_img'] = $this->_getSlideUrl($img['slide_img']);
        }

        	return $result;
	}

    public function getSlide($slide_id) {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "slides WHERE slide_id = '".(int)$slide_id."' ");
  		$query->row['preview'] = $this->_getSlideUrl($query->row['slide_img']);
        	return $query->row;
	}

  	private function _getSlideUrl( $img ) {

        	if(!is_file(DIR_RESOURCE . $img)){
              	if(!is_file(DIR_EXT . 'slideshow/image/' . $img)){
                    	$result = $this->model_tool_image->resize('no_image.jpg', $this->slide['x'], $this->slide['y']);
              	}else{
                    	$result = HTTP_EXT.'slideshow/image/' . $img;
              	}
        	}else{

            $id = $this->rm->getIdFromHexPath( str_replace($this->rm->getTypeDir(), '', $img) );
            $result = $this->rm->getResourceThumb($id, $this->slide['x'], $this->slide['y']);
            if ( !$result )
              		$result = $this->model_tool_image->resize('no_image.jpg', $this->slide['x'], $this->slide['y']);
        	}

        	return $result;
  	}

}

This model has two methods to fetch data
also note _getSlideUrl method. Since we have default images we should check if image passed in function is exist in resource directory. If so we try to get resource id from its path and create a thumbnail with width/height defined in extension settings

- Now add model for admin - extensions\slideshow\admin\model\slideshow\slideshow.php

<?php
if (! defined ( 'DIR_CORE' )) {
  	header ( 'Location: static_pages/' );
}
class ModelSlideshowSlideshow extends Model {

    protected $model_tool_image;
    protected $slide;
    protected $rm;

    public function __construct($registry) {
        parent::__construct($registry);
        $this->model_tool_image = $this->registry->get('model_tool_image');
  		$this->slide = array(
        		'x' => $this->registry->get('config')->get('slideshow_x'),
        		'y' => $this->registry->get('config')->get('slideshow_y'),
  		);
        $this->rm = new AResource('image');
  	}

    public function getSlides() {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "slides");
  		$result = $query->rows;
  		foreach ( $result as $key => $img ) {
              	$result[$key]['slide_img'] = $this->_getSlideUrl($img['slide_img']);
        }

        	return $result;
	}

    public function addSlide($data) {
        $this->db->query(
            "INSERT INTO " . DB_PREFIX . "slides
            SET slide_img = '".$this->db->escape( $data['slide_img'] )."',
                slide_url = '".$this->db->escape( $data['slide_url'] )."'  ");
	}

    public function editSlide($slide_id, $data) {
        $this->db->query(
            "UPDATE " . DB_PREFIX . "slides
            SET slide_img = '".$this->db->escape( $data['slide_img'] )."',
                slide_url = '".$this->db->escape( $data['slide_url'] )."'
            WHERE slide_id = '".(int)$slide_id."' ");
	}

    public function getSlide($slide_id) {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "slides WHERE slide_id = '".(int)$slide_id."' ");
  		$query->row['preview'] = $this->_getSlideUrl($query->row['slide_img']);
        	return $query->row;
	}

    public function deleteSlide($slide_id) {
        $this->db->query("DELETE FROM " . DB_PREFIX . "slides WHERE slide_id = '".(int)$slide_id."' ");
	}

  	private function _getSlideUrl( $img ) {

        	if(!is_file(DIR_RESOURCE . $img)){
              	if(!is_file(DIR_EXT . 'slideshow/image/' . $img)){
        	        	$result = $this->model_tool_image->resize('no_image.jpg', $this->slide['x'], $this->slide['y']);
              	}else{
                    	$result = HTTP_EXT.'slideshow/image/' . $img;
              	}
        	}else{

            $id = $this->rm->getIdFromHexPath( str_replace($this->rm->getTypeDir(), '', $img) );
            $result = $this->rm->getResourceThumb($id, $this->slide['x'], $this->slide['y']);
            if ( !$result )
              		$result = $this->model_tool_image->resize('no_image.jpg', $this->slide['x'], $this->slide['y']);
        	}

        	return $result;
  	}

}

This model has methods to manage slideshow items – add / edit / delete
Now all ready to create a controller to manage slides in admin
extensions\slideshow\admin\controller\pages\blocks\slideshow.php

if ( !defined ( 'DIR_CORE' )) {
  	header ( 'Location: static_pages/' );
}

class ControllerPagesBlocksSlideshow extends AController {

  	private $error = array();
  	public $data = array();

  	public function main() {

          //init controller data
        $this->extensions->hk_InitData($this);

	  $this->loadLanguage('extension/extensions');
	  $this->loadLanguage('slideshow/slideshow');
	  $this->loadModel('slideshow/slideshow');
        $this->document->setTitle( $this->language->get('heading_title') );

        	$this->view->assign('error_warning', $this->error['warning']);
        	$this->view->assign('success', $this->session->data['success']);
        	if (isset($this->session->data['success'])) {
              	unset($this->session->data['success']);
        	}

	  $this->document->initBreadcrumb( array (
   	       	'href'  	=> $this->html->getSecureURL('index/home'),
   	       	'text'  	=> $this->language->get('text_home'),
  	        	'separator' => FALSE
        	 ));
        $this->document->addBreadcrumb(array(
            'href' => $this->html->getSecureURL('extension/extensions/'.$this->session->data['extension_filter']),
            'text' => $this->language->get('heading_title'),
            'separator' => ' :: '
        ));
        	$this->document->addBreadcrumb(array(
            'href' => $this->html->getSecureURL('extension/extensions/edit', '&extension=slideshow'),
   	     'text' => $this->language->get('slideshow_name'),
            'separator' => ' :: '
        ));
        	$this->document->addBreadcrumb( array (
   	       	'href'  	=> $this->html->getSecureURL('blocks/slideshow'),
   	       	'text'  	=> $this->language->get('slides_title'),
  	        	'separator' => ' :: '
        	 ));

        	$this->data['images'] = $this->model_slideshow_slideshow->getSlides();

        	$this->data['delete'] = $this->html->getSecureURL('blocks/slideshow/delete', '&slide_id=%ID%' );
        	$this->data['update'] = $this->html->getSecureURL('blocks/slideshow/update', '&slide_id=%ID%' );
        	$this->data['insert'] = $this->html->getSecureURL('blocks/slideshow/insert' );

        	$this->data['button_remove'] = $this->html->buildButton(array(
              	'text' => $this->language->get('button_remove'),
              	'style' => 'button2',
        	));
        	$this->data['button_edit'] = $this->html->buildButton(array(
              	'text' => $this->language->get('button_edit'),
              	'style' => 'button2',
        	));
        	$this->data['button_add_slide'] = $this->html->buildButton(array(
              	'text' => $this->language->get('button_add_slide'),
              	'style' => 'button1',
        	));

        $this->view->batchAssign(  $this->language->getASet() );
        	$this->view->batchAssign( $this->data );

        	$this->processTemplate('pages/blocks/slideshow_list.tpl' );

          //update controller data
        $this->extensions->hk_UpdateData($this);
  	}

  	public function insert() {

        //init controller data
        $this->extensions->hk_InitData($this);

	  $this->loadLanguage('slideshow/slideshow');
        $this->loadModel('slideshow/slideshow');
	  $this->document->setTitle($this->language->get('heading_title'));

	  if (($this->request->server['REQUEST_METHOD'] == 'POST')) {
    	    $this->request->post['slide_img'] = html_entity_decode($this->request->post['slide_img'], ENT_COMPAT, 'UTF-8');
            $this->model_slideshow_slideshow->addSlide($this->request->post);
            $this->session->data['success'] = $this->language->get('text_success');
              	$this->redirect( $this->html->getSecureURL('blocks/slideshow') );
	  }
	  $this->_getForm();

        //update controller data
        $this->extensions->hk_UpdateData($this);
  	}

  	public function update() {

        //init controller data
        $this->extensions->hk_InitData($this);

	  $this->loadLanguage('slideshow/slideshow');
        $this->loadModel('slideshow/slideshow');
	  $this->document->setTitle($this->language->get('heading_title'));
	  if (($this->request->server['REQUEST_METHOD'] == 'POST')) {
            $this->request->post['slide_img'] = html_entity_decode($this->request->post['slide_img'], ENT_COMPAT, 'UTF-8');
              	$this->model_slideshow_slideshow->editSlide($this->request->get['slide_id'], $this->request->post);
              	$this->session->data['success'] = $this->language->get('text_success');
              	$this->redirect( $this->html->getSecureURL('blocks/slideshow') );
        	}
	  $this->_getForm();

   	 //update controller data
        $this->extensions->hk_UpdateData($this);
  	}

  	public function delete() {

        //init controller data
        $this->extensions->hk_InitData($this);

	  $this->loadLanguage('slideshow/slideshow');
        $this->loadModel('slideshow/slideshow');
	  $this->model_slideshow_slideshow->deleteSlide($this->request->get['slide_id']);
        $this->session->data['success'] = $this->language->get('text_success');
        	$this->redirect( $this->html->getSecureURL('blocks/slideshow') );

        	//update controller data
        $this->extensions->hk_UpdateData($this);
  	}

  	private function _getForm() {

        	$this->view->assign('error_warning', $this->error['warning']);
        	$this->view->assign('success', $this->session->data['success']);
        	if (isset($this->session->data['success'])) {
              	unset($this->session->data['success']);
        	}
        	$this->view->batchAssign(  $this->language->getASet() );

	  $this->data = array();
        	$this->data['error'] = $this->error;
        	$this->data['cancel'] = $this->html->getSecureURL('blocks/slideshow');

        	$this->data['heading_title'] = $this->language->get('slides_title');

        	$this->document->initBreadcrumb( array (
   	       	'href'  	=> $this->html->getSecureURL('index/home'),
   	       	'text'  	=> $this->language->get('text_home'),
  	        	'separator' => FALSE
        	 ));
        $this->document->addBreadcrumb(array(
            'href' => $this->html->getSecureURL('extension/extensions/'.$this->session->data['extension_filter']),
            'text' => $this->language->get('heading_title'),
            'separator' => ' :: '
        ));
        	$this->document->addBreadcrumb(array(
            'href' => $this->html->getSecureURL('extension/extensions/edit', '&extension=slideshow'),
	        'text' => $this->language->get('slideshow_name'),
            'separator' => ' :: '
        ));
        	$this->document->addBreadcrumb( array (
   	       	'href'  	=> $this->html->getSecureURL('blocks/slideshow'),
   	       	'text'  	=> $this->language->get('slides_title'),
  	        	'separator' => ' :: '
        	 ));


        	if (isset($this->request->get['slide_id']) && ($this->request->server['REQUEST_METHOD'] != 'POST')) {
  	        	$item_info = $this->model_slideshow_slideshow->getSlide($this->request->get['slide_id']);
	  }

        	$fields = array('slide_img', 'slide_url');
        	foreach ( $fields as $f ) {
              	if (isset ( $this->request->post [$f] )) {
                    	$this->data [$f] = $this->request->post [$f];
              	} elseif (isset($item_info[$f])) {
                    	$this->data[$f] = $item_info[$f];
              	} else {
                    	$this->data[$f] = '';
              	}
        	}

        if (!isset($this->request->get['slide_id'])) {
              	$this->data['action'] = $this->html->getSecureURL('blocks/slideshow/insert' );
              	$this->data['form_title'] = $this->language->get('text_insert') . $this->language->get('text_slide');
        	} else {
              	$this->data['action'] = $this->html->getSecureURL('blocks/slideshow/update', '&slide_id=' . $this->request->get['slide_id'] );
              	$this->data['form_title'] = $this->language->get('text_edit') . $this->language->get('text_slide');
        	}

        $form = new AForm('ST');

        	$this->document->addBreadcrumb( array (
              	'href'  	=> $this->data['action'],
              	'text'  	=> $this->data['form_title'],
              	'separator' => ' :: '
        	 ));

        	$form->setForm(array(
        		'form_name' => 'frm',
              	'update' => '',
  		));

        $this->data['form']['id'] = 'frm';
        $this->data['form']['form_open'] = $form->getFieldHtml(array(
        		'type' => 'form',
        		'name' => 'frm',
        		'action' => $this->data['action'],
  		));
        $this->data['form']['submit'] = $form->getFieldHtml(array(
        		'type' => 'button',
        		'name' => 'submit',
        		'text' => $this->language->get('button_save'),
        		'style' => 'button1',
  		));
        	$this->data['form']['cancel'] = $form->getFieldHtml(array(
        		'type' => 'button',
        		'name' => 'cancel',
        		'text' => $this->language->get('button_cancel'),
        		'style' => 'button2',
  		));

        $this->data['form']['fields']['img'] = $form->getFieldHtml(
            array(
                'type' => 'hidden',
                'name' => 'slide_img',
                'value' => htmlspecialchars($this->data['slide_img'], ENT_COMPAT, 'UTF-8'),
        		)
        );
        $this->data['form']['fields']['url'] = $form->getFieldHtml(
            array(
                'type' => 'input',
                'name' => 'slide_url',
                'value' => $this->data['slide_url'],
                'attr' => 'class="large-field"',
        		)
        );

        $resources_scripts = $this->dispatch(
            'responses/common/resource_library/get_resources_scripts',
            array(
                'object_name' => '',
                'object_id' => '',
                'types' => 'image',
                'mode' => 'url',
            )
        );
        $this->data['resources_scripts'] = $resources_scripts->dispatchGetOutput();
        if ( isset($this->request->get['slide_id']) && is_file( DIR_RESOURCE . $item_info['slide_img']) ) {
            $rm = new AResourceManager();
            $rm->setType('image');
            $id = $rm->getIdFromHexPath( str_replace($rm->getTypeDir(), '', $item_info['slide_img']) );
            $thumb = $rm->getResourceThumb(
                $id,
                $this->config->get('config_image_product_width'),
                $this->config->get('config_image_product_height')
            );
            $this->view->assign( 'thumb', $thumb);
        	}

        $this->view->batchAssign( $this->data );
        $this->processTemplate('pages/blocks/slideshow_form.tpl' );
  	}


}

This controller is work as usual application controller
Main method – fetch all slides and give ability to add/edit/delete slides
Insert – insert new slide
Update – edit slide image/url
Delete – delete slide

Lets look in details how we include resource library scripts

$resources_scripts = $this->dispatch(
            'responses/common/resource_library/get_resources_scripts',
            array(
                'object_name' => '',
                'object_id' => '',
                'types' => 'image',
                'mode' => 'url',
            )
        );
        $this->data['resources_scripts'] = $resources_scripts->dispatchGetOutput();

$this->dispatch – call controller with arguments and return dispatch object $resources_scripts->dispatchGetOutput(); - return controller output, which is passed to template later

This controller use two templates

  • slideshow_list.tpl – show all slides
  • slideshow_form.tpl – create/update form

Now lets create storefront controller
extensions\slideshow\storefront\controller\blocks\slideshow.php

<?php
if (! defined ( 'DIR_CORE' )) {
  	header ( 'Location: static_pages/' );
}

class ControllerBlocksSlideshow extends AController {
  	public function main() {

        //init controller data
        $this->extensions->hk_InitData($this);
        $this->loadModel('slideshow/slideshow');

        if ( !$this->registry->has('jcycle') ) {
            $this->document->addScript( $this->view->templateResource('/javascript/jquery/jquery.cycle.js') );
            $this->registry->set('jcycle', true);
        }
        	$this->document->addStyle(
              	array(
                    	 'href' => $this->view->templateResource('/stylesheet/slideshow.css'),
                    	 'rel' => 'stylesheet',
                    	 'media' => 'screen',
              	)
        	);

        	$this->view->assign('images', $this->model_slideshow_slideshow->getSlides());

        $this->processTemplate('blocks/slideshow.tpl');

        //init controller data
        $this->extensions->hk_UpdateData($this);

  	}
}

$this->document->addScript & $this->document->addStyle methods add styles and scripts in document object and will be added in head tag

Please note that

$this->registry->set('jcycle', true);

Used to avoid loading multiple instances of scripts in order you will have several slideshows on one page

Storefront template include simple slideshow html.

You can take a look at full code by downloading our free template. This extension is a part of template.