如何在Prestashop中为CMS页面添加特色图像

时间:2015-06-05 04:56:12

标签: php prestashop-1.6

我想为我在Prestashop中添加的每个CMS页面添加一个后端图像,就像我们在Wordpress中为帖子/页面添加精选图片一样。

我在prestashop中找不到任何支持此功能的代码/模块。

5 个答案:

答案 0 :(得分:6)

这是可能的,但并不简单。以下是将图像上载到CMS页面模块所需执行的步骤。这种方法不是在PrestaShop中实现这一点的最优雅方式,但我希望它可以帮助您前进。

步骤1,更新模型,使其包含图像:

首先将'classes / CMS.php'覆盖为'override / classes / CMS.php'。

class CMS extends CMSCore
{    
    // add a public field to store the CMS image
    public $CMS_IMG; 

    /**
    * @see ObjectModel::$definition
    */
    public static $definition = array(
        'table' => 'cms',
        'primary' => 'id_cms',
        'multilang' => true,
        'fields' => array(
        'id_cms_category' =>  array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
        'position' =>    array('type' => self::TYPE_INT),
        'active' =>    array('type' => self::TYPE_BOOL),
        // Lang fields
        'meta_description' =>  array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
        'meta_keywords' =>   array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
        'meta_title' =>   array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128),
        'content' =>    array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString', 'size' => 3999999999999),

        // add one image per page        
        'CMS_IMG' =>   array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isString', 'size' => 3999999999999),  ),
    );
}

第2步,实现在后台上传图片所需的代码:

覆盖'override / controllers / admin / AdminCmsController.php'中的'controllers / admin / AdminCmsController.php'

class AdminCmsController extends AdminCmsControllerCore
{
    public function renderForm()
    {        
        $this->display = 'edit';
        $this->toolbar_btn['save-and-preview'] = array(
            'href' => '#',
            'desc' => $this->l('Save and preview')
        );
        $this->initToolbar();
        if (!$this->loadObject(true))
            return;
        $categories = CMSCategory::getCategories($this->context->language->id, false);
        $html_categories = CMSCategory::recurseCMSCategory($categories, $categories[0][1], 1, $this->getFieldValue($this->object, 'id_cms_category'), 1);

        // Add code to get image url
        $image_url = '';
        $imgName = $this->getImageValue($this->object);
        if($imgName) {
            $image = _PS_IMG_DIR_ . 'cms/' . $imgName;
            $image_url = ImageManager::thumbnail($image, $this->table.'_'.(int)$this->object->id.'.'.$this->imageType, 350,
                $this->imageType, true, true);
        }

        $this->fields_form = array(
            'tinymce' => true,
            'legend' => array(
                'title' => $this->l('CMS Page'),
                'image' => '../img/admin/tab-categories.gif'
            ),
            'input' => array(
                // custom template
                array(
                    'type' => 'select_category',
                    'label' => $this->l('CMS Category'),
                    'name' => 'id_cms_category',
                    'options' => array(
                        'html' => $html_categories,
                    ),
                ),
                array(
                    'type' => 'text',
                    'label' => $this->l('Meta title:'),
                    'name' => 'meta_title',
                    'id' => 'name', // for copy2friendlyUrl compatibility
                    'lang' => true,
                    'required' => true,
                    'class' => 'copy2friendlyUrl',
                    'hint' => $this->l('Invalid characters:').' <>;=#{}',
                    'size' => 50
                ),
                array(
                    'type' => 'text',
                    'label' => $this->l('Meta description'),
                    'name' => 'meta_description',
                    'lang' => true,
                    'hint' => $this->l('Invalid characters:').' <>;=#{}',
                    'size' => 70
                ),
                array(
                    'type' => 'tags',
                    'label' => $this->l('Meta keywords'),
                    'name' => 'meta_keywords',
                    'lang' => true,
                    'hint' => $this->l('Invalid characters:').' <>;=#{}',
                    'size' => 70,
                    'desc' => $this->l('To add "tags" click in the field, write something, then press "Enter"')
                ),
                array(
                    'type' => 'text',
                    'label' => $this->l('Friendly URL'),
                    'name' => 'link_rewrite',
                    'required' => true,
                    'lang' => true,
                    'hint' => $this->l('Only letters and the minus (-) character are allowed')
                ),
                array(
                    'type' => 'textarea',
                    'label' => $this->l('Page content'),
                    'name' => 'content',
                    'autoload_rte' => true,
                    'lang' => true,
                    'rows' => 5,
                    'cols' => 40,
                    'hint' => $this->l('Invalid characters:').' <>;=#{}'
                ),                
                /* Add an fileupload component to the form */
                array(
                    'type' => 'file',
                    'label' => $this->l('Page image'),
                    'name' => 'CMS_IMG',
                    'desc' => $this->l('Upload an image for this page'),
                    'lang' => true,
                    'display_image' => true,
                    'image' => $image_url ? $image_url : false,
                ),                
                array(
                    'type' => 'radio',
                    'label' => $this->l('Displayed:'),
                    'name' => 'active',
                    'required' => false,
                    'class' => 't',
                    'is_bool' => true,
                    'values' => array(
                        array(
                            'id' => 'active_on',
                            'value' => 1,
                            'label' => $this->l('Enabled')
                        ),
                        array(
                            'id' => 'active_off',
                            'value' => 0,
                            'label' => $this->l('Disabled')
                        )
                    ),
                ),
            ),
            'submit' => array(
                'title' => $this->l('   Save   '),
                'class' => 'button'
            )
        );
        if (Shop::isFeatureActive())
        {
            $this->fields_form['input'][] = array(
                'type' => 'shop',
                'label' => $this->l('Shop association:'),
                'name' => 'checkBoxShopAsso',
            );
        }
        $this->tpl_form_vars = array(
            'active' => $this->object->active
        );
        return AdminControllerCore::renderForm();
    }

    public function postProcess()
    {
        $languages = Language::getLanguages(false);
        $update_images_values = false;

        foreach ($languages as $lang)
        {
            if (isset($_FILES['CMS_IMG'])
                && isset($_FILES['CMS_IMG']['tmp_name'])
                && !empty($_FILES['CMS_IMG']['tmp_name']))
            {
                if ($error = ImageManager::validateUpload($_FILES['CMS_IMG'], 4000000))
                    return $error;
                else
                {
                    $ext = substr($_FILES['CMS_IMG']['name'], strrpos($_FILES['CMS_IMG']['name'], '.') + 1);
                    $file_name = md5($_FILES['CMS_IMG']['name']).'.'.$ext;

                    if (!move_uploaded_file($_FILES['CMS_IMG']['tmp_name'],
                        _PS_IMG_DIR_ .'cms'.DIRECTORY_SEPARATOR.$file_name))
                        return Tools::displayError($this->l('An error occurred while attempting to upload the file.'));
                    else
                    {
                        $values['CMS_IMG'][$lang['id_lang']] = $file_name;
                    }
                }

                $update_images_values = true;
                $cms = new CMS((int)Tools::getValue('id_cms'));
                $cms->CMS_IMG = $file_name;
                $cms->update();
            }
        }

        parent::postProcess();
    }

    public function getImageValue()
    {
        $db = Db::getInstance();
        $sql = 'SELECT CMS_IMG FROM '._DB_PREFIX_.'cms_lang WHERE id_cms = ' . $this->object->id;
        return $db->getValue($sql);
    }
}

第3步,实施前端代码

覆盖'override / controllers / front / CmsController.php'中的'controllers / front / CmsController.php'

class CmsController extends CmsControllerCore
{

    /**
     * Assign template vars related to page content
     * @see CmsControllerCore::initContent()
     */
    public function initContent()
    {
        if(!empty($this->cms->CMS_IMG)) {
            $this->context->smarty->assign('cms_image', _PS_IMG_ . 'cms/' . $this->cms->CMS_IMG);
        }

        parent::initContent();
    }
}

第4步,在模板中使用您的图片

现在你可以,例如在cms.tpl中使用以下代码:

{if $cms_image != ''}
    <img src="{$cms_image}">
{/if}

基于:https://www.prestashop.com/forums/topic/141903-add-custom-field-to-cms-module/

答案 1 :(得分:3)

将所有这些添加为单独的答案,因为一些主持人似乎拒绝最简单的修复/更改原始答案为&#34; 此编辑偏离帖子的原始意图&#34 ;或&#34; 此编辑旨在解决帖子的作者&#34; ..right。

<小时/>

通过 11mb

改善答案

步骤0,注意需要在SQL表中手动添加新字段(使用SQL或PhpMyAdmin结构编辑):

ALTER TABLE `ps_cms_lang` ADD `CMS_IMG` TEXT NULL DEFAULT NULL;

步骤1.2,需要删除类缓存文件以使更改生效:

/cache/class_index.php

第4步,在模板中使用您的图片
..
或者更通用的表单(也可用于类别子页面 - 使用CMS_IMG属性(->.取决于代码):

{if isset($cms->CMS_IMG) && $cms->CMS_IMG}
    <img src="{$img_ps_dir}/cms/{$cms->CMS_IMG}">
{/if}

1。对于非多字段字段 - 进行以下调整:

ALTER TABLE `ps_cms` ADD `CMS_IMG` TEXT NULL DEFAULT NULL;

'CMS_IMG' =>   array('type' => self::TYPE_STRING, 'lang' => false, ..

'lang' => false,

$sql = 'SELECT CMS_IMG FROM '._DB_PREFIX_.'cms WHERE id_cms = ' . $this->object->id;

+删除postProcess()

中的所有内容

2。多次修复postProcess()

  • 代码无法正确保存数据 - 不应在$cms->update();中使用postProcess()作为添加新页面的触发器异常,因为部分数据=仅设置$_POST['CMS_IMG']值..
  • 应为每个页面生成唯一的文件名(以id开头)。
  • 应检查isSubmit以避免在错误的链中处理(如果CMS类别中使用相同的字段名称)。

更新的代码:

public function postProcess()
{
    if ( (Tools::isSubmit('submitAddcms') || Tools::isSubmit('viewcms'))
        && isset($_FILES['CMS_IMG'])
        && isset($_FILES['CMS_IMG']['tmp_name'])
        && !empty($_FILES['CMS_IMG']['tmp_name']))
    {
        $id = (int)Tools::getValue('id_cms');

        if ($error = ImageManager::validateUpload($_FILES['CMS_IMG'], 4000000))
            return $error;
        else
        {
            $ext = substr($_FILES['CMS_IMG']['name'], strrpos($_FILES['CMS_IMG']['name'], '.') + 1);
            $file_name = $id .'_cms_'. md5($_FILES['CMS_IMG']['name']).'.'.$ext;

            if (!move_uploaded_file($_FILES['CMS_IMG']['tmp_name'],
                _PS_IMG_DIR_.'cms'.DIRECTORY_SEPARATOR.$file_name))
                return Tools::displayError($this->l('An error occurred while attempting to upload the file.'));
            else {
                $_POST['CMS_IMG'] = $file_name;
                @chmod(_PS_IMG_DIR_.'cms'.DIRECTORY_SEPARATOR.$file_name, 0666);
            }
        }
    }

    parent::postProcess();
}

答案 2 :(得分:2)

上述解决方案不符合PrestaShop的理念。

为CMS页面添加特色图像应模仿现有的机制(请参阅类别或供应商徽标的创建/编辑)。

以下是我的解决方案,为PrestaShop 1.6.1.7工作。它将添加一个图像字段,将图像上传到img / cms文件夹并创建所有缩略图。

我还没弄清楚如何删除图片,非常欢迎您评论我的回答。 更新PrestaShop时要小心,可能会更新覆盖文件夹中的文件。

1 /将以下内容添加到 defines.inc.php (第137行之后):

define('_PS_CMS_IMG_DIR_', _PS_IMG_DIR_.'cms/');

2 /将以下内容添加到 defines_uri.inc.php (第61行之后):

define('_THEME_CMS_DIR_', _PS_IMG_.'cms/');

3 /将规则添加到 .htaccess 文件:

RewriteRule ^cms/([0-9]+)(\-[\.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/cms/$1$2$3.jpg [L]
RewriteRule ^cms/([a-zA-Z_-]+)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/cms/$1$2.jpg [L]

4 /将 classes / CMS.php 覆盖为覆盖/ classes / CMS.php

<?php
class CMS extends CMSCore
{    
    // Add an id_image attribute to allow further tests in cms.tpl
    public $id_image = 'default';

    public function __construct($id = null, $id_lang = null, $id_shop = null)
    {
        parent::__construct($id, $id_lang, $id_shop);
        $this->id_image = ($this->id && file_exists(_PS_CMS_IMG_DIR_.(int)$this->id.'.jpg')) ? (int)$this->id : false;
        $this->image_dir = _PS_CMS_IMG_DIR_;
    }
}
?>

5 /覆盖 classes / ImageType.php 覆盖/ classes / ImageType.php

  • 向班级添加公共属性:public $cms

  • 附加到$definition=>fields'cms' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool')

  • 在getByNameNType中,追加到$types var:'cms'

6 /将 classes / Link.php 覆盖为覆盖/ classes / Link.php

class Link extends LinkCore
{
    public function getCmsImageLink($name, $id_cms, $type = null)
    {
        if ($this->allow == 1 && $type) {
            $uri_path = __PS_BASE_URI__.'cms/'.$id_cms.'-'.$type.'/'.$name.'.jpg';
        } else {
            $uri_path = _THEME_CAT_DIR_.$id_cms.($type ? '-'.$type : '').'.jpg';
        }
        return $this->protocol_content.Tools::getMediaServer($uri_path).$uri_path;
    }
}

7 /覆盖 controllers / AdminCmsController.php 覆盖/ controllers / AdminCmsController.php

  • 将以下内容附加到__contruct方法,就在parent :: __ construct()之前:

    $this->fieldImageSettings = array(
        'name' => 'banner_img',
        'dir' => 'cms',
    );
    
  • 将以下内容追加到postProcess方法,紧接在第351行之后(在其中一个elseif块中,查找submitAddcms和submitAddcmsAndPreview上的条件):

    $object = $this->loadObject();
    $image_is_posted = $this->postImage($object->id);
    if (! $image_is_posted) {
        throw new PrestaShopException("image not posted...");
    }
    
  • 在renderForm方法中,以:

    开头
    if (!($obj = $this->loadObject(true))) {
        return;
    }
    
    $image = _PS_CMS_IMG_DIR_.$obj->id.'.jpg';
    $image_url = ImageManager::thumbnail($image, $this->table.'_'.$obj->id.'.'.$this->imageType, 350,
        $this->imageType, true, true);
    
    $image_size = file_exists($image) ? filesize($image) / 1000 : false;
    
    if (Validate::isLoadedObject($this->object)) {
        $this->display = 'edit';
    } else {
        $this->display = 'add';
    }
    

并将以下内容附加到属性$this->fields_form,例如在内容字段之后:

array(
    'type' => 'file',
    'label' => $this->l('Banner image'),
    'name' => 'banner_img',
    'display_image' => true,
    'image' => $image_url ? $image_url : false,
    'size' => $image_size,
    'hint' => $this->l('Upload a banner image from your computer.')
)
  • 添加和afterImageUpload方法:

    afterImageUpload()后的受保护函数 {     $ return = true;     $ generate_hight_dpi_images =(bool)Configuration :: get(&#39; PS_HIGHT_DPI&#39;);

    $object = $this->loadObject(true);
    
    /* Generate image with differents size */
    if (($object->id = (int)Tools::getValue('id_cms')) &&
         isset($_FILES) && count($_FILES) && file_exists(_PS_CMS_IMG_DIR_.$object->id.'.jpg')) {
        $images_types = ImageType::getImagesTypes('cms');
        foreach ($images_types as $k => $image_type) {
            $file = _PS_CMS_IMG_DIR_.$object->id.'.jpg';
            if (!ImageManager::resize($file, _PS_CMS_IMG_DIR_.$object->id.'-'.stripslashes($image_type['name']).'.jpg', (int)$image_type['width'], (int)$image_type['height'])) {
                $return = false;
            }
    
            if ($generate_hight_dpi_images) {
                if (!ImageManager::resize($file, _PS_CMS_IMG_DIR_.$object->id.'-'.stripslashes($image_type['name']).'2x.jpg', (int)$image_type['width']*2, (int)$image_type['height']*2)) {
                    $return = false;
                }
            }
        }
    
        $current_logo_file = _PS_CMS_IMG_DIR_.'cms_mini_'.$object->id.'_'.$this->context->shop->id.'.jpg';
    
        if (file_exists($current_logo_file)) {
            unlink($current_logo_file);
        }
    }
    return $return;
    }
    

8 /覆盖 controllers / admin / AdminImagesController.php 覆盖/ controllers / admin / AdminImagesController.php

  • 在__construct方法中,附加到$ this-&gt; fields_list:'cms' => array('title' => $this->l('CMS'), 'align' => 'center', 'type' => 'bool', 'callback' => 'printEntityActiveIcon', 'orderby' => false)

  • __contruct方法中,附加到$this->fields_form=>input

    array(
        'type' => 'switch',
        'label' => $this->l('Pages CMS'),
        'name' => 'cms',
        'required' => false,
        'is_bool' => true,
        'hint' => $this->l('This type will be used for CMS banner images.'),
        'values' => array(
            array(
                'id' => 'cms_on',
                'value' => 1,
                'label' => $this->l('Enabled')
            ),
            array(
                'id' => 'cms_off',
                'value' => 0,
                'label' => $this->l('Disabled')
            ),
        )
    ),
    
  • initRegenerate方法中,附加到$types var:'cms' => $this->l('CMS pages')

  • _regenerateThumbnails方法中,附加到$process数组:array('type' => 'cms', 'dir' => _PS_CMS_IMG_DIR_)

9 /使用以下内容更新您的CMS页面模板 cms.tpl

<!-- Check out the default theme's category_header.tpl for original PrestaShop code -->
<div class="cms_banner"{if $cms->id_image} style="background:url({$link->getCmsImageLink($cms->link_rewrite, $cms->id_image, 'large')|escape:'html':'UTF-8'}) right center no-repeat; background-size:cover; "{/if}>
    <div class="container">
        <!-- Your content here -->
    </div>
</div>

答案 3 :(得分:1)

为防止在更新数据时图像松动。 (这是1.7的补充),我建议对postProcess方法进行以下改进:

public function postProcess()
{
    $languages = Language::getLanguages(false);
    $update_images_values = false;
    $cms = new CMS((int)Tools::getValue('id_cms'));

    foreach ($languages as $lang)
    {
        if (isset($_FILES['CMS_IMG'])
            && isset($_FILES['CMS_IMG']['tmp_name'])
            && !empty($_FILES['CMS_IMG']['tmp_name']))
        {
            if ($error = ImageManager::validateUpload($_FILES['CMS_IMG'], 4000000))
                return $error;
            else
            {
                $ext = substr($_FILES['CMS_IMG']['name'], strrpos($_FILES['CMS_IMG']['name'], '.') + 1);
                $file_name = md5($_FILES['CMS_IMG']['name']).'.'.$ext;

                if (!move_uploaded_file($_FILES['CMS_IMG']['tmp_name'],
                    _PS_IMG_DIR_ .'cms'.DIRECTORY_SEPARATOR.$file_name))
                    return Tools::displayError($this->l('An error occurred while attempting to upload the file.'));
                else
                {
                    $values['CMS_IMG'][$lang['id_lang']] = $file_name;
                }
            }

            $update_images_values = true;
            $cms->CMS_IMG = $file_name;
            $cms->update();
        }
        else
        {
            $_POST['CMS_IMG'] = $cms->CMS_IMG;
        }
    }

    self::saveProducts();
    parent::postProcess();
}

这会在原始条件上增加一个条件

答案 4 :(得分:0)

 // add one image per page        
    'CMS_IMG' =>   array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isString', 'size' => 3999999999999),  ),

 Above argument can not create a field on cms_lang table.

 So system can gives the following error

 Unknown column 'cms_image' in 'field list'

 if ($webservice_call && $errno) {
        $dbg = debug_backtrace();
         WebserviceRequest::getInstance()->setError(500, '[SQL Error] '.$this->getMsgError().'. From '.(isset($dbg[3]['class']) ? $dbg[3]['class'] : '').'->'.$dbg[3]['function'].'() Query was : '.$sql, 97);
     } elseif (_PS_DEBUG_SQL_ && $errno && !defined('PS_INSTALLATION_IN_PROGRESS')) {
         if ($sql) {
             throw new PrestaShopDatabaseException($this->getMsgError().'<br /><br /><pre>'.$sql.'</pre>');
         }

         throw new PrestaShopDatabaseException($this->getMsgError());
     }
 }