add purchase guide module - backoffice only

This commit is contained in:
Rodney Figaro 2016-08-30 18:10:44 +02:00
parent 1ed3c9df79
commit 4808607e56
15 changed files with 1419 additions and 0 deletions

View File

@ -0,0 +1,13 @@
<?php
class AdminGuide extends AdminTab
{
public function __construct()
{
parent::__construct();
}
public function display()
{
}
}

View File

@ -0,0 +1,236 @@
<?php
include(__DIR__.'/classes/GuideCategory.php');
include(__DIR__.'/classes/FormBuilder.php');
class AdminGuideCategories extends AdminTab
{
private static $current_category = 0;
private static $category_parent = 0;
public function __construct()
{
global $cookie;
$this->table = 'guide_category';
$this->className = 'GuideCategory';
$this->lang = true;
$this->edit = true;
$this->delete = true;
$this->view = true;
$this->fieldsDisplay = array(
'id_guide_category' => array(
'title' => $this->l('ID'),
'align' => 'center',
'width' => 30
),
'name' => array(
'title' => $this->l('Title'),
'width' => 100
),
'description' => array(
'title' => $this->l('Description'),
'width' => 500,
'maxlength' => 90,
'orderby' => false
),
'position' => array(
'title' => $this->l('Position'),
'width' => 40,
'filter_key' => 'position',
'align' => 'center',
'position' => 'position'
),
'active' => array(
'title' => $this->l('Displayed'),
'active' => 'status',
'align' => 'center',
'type' => 'bool',
'orderby' => false
)
);
self::$current_category = new GuideCategory(
(int)(Tools::getValue('id_guide_category',
(int)(Tools::getValue('id_guide_category_parent', 0)
)
)
));
$this->_select = 'position ';
$this->_filter = 'AND a.`id_parent` = '.(int)(self::$current_category->id);
$this->_orderBy = 'position';
$this->_orderWay = 'DESC';
$this->identifiersDnd['id_guide_category'] = 'id_guide_category';
parent::__construct();
}
public static function getCurrentCategory()
{
return self::$current_category;
}
public function displayForm($token = NULL)
{
global $currentIndex, $cookie, $smarty;
parent::displayForm();
if (!($obj = $this->loadObject(true)))
return;
$langs = Language::getLanguages(false);
$form = new FormBuilder('AdminGuideCategories', $this->table, 'id_guide_category', 'Add');
$this->fieldsForm = array(
'id_parent' => array(
'title' => $this->l('Catégorie parent'),
'type' => 'select',
'options_raw' => GuideCategory::findCategoriesTree($cookie->id_lang, $obj->id),
'options_map' => ['id_guide_category', 'name', 'level'],
'empty_option' => ['value'=>'0', 'label'=>$this->l('No parent category')],
'initial_value' => $obj->id_parent?$obj->id_parent:self::$current_category->id
),
'id_category_family' => array(
'title' => $this->l('Famille'),
'type' => 'select',
'options_raw' => GuideCategory::findFamiliesTree($cookie->id_lang),
'options_map' => ['id_category_family', 'name', 'level'],
'initial_value' => $obj->id_category_family
),
'name' => array(
'title' => $this->l('Title'),
'type' => 'text',
'required' => true,
'translatable' => true,
'attrs' => [
'onkeyup' => 'copy2friendlyURL();'
]
),
'description' => array(
'title' => $this->l('Description'),
'type' => 'textarea',
'translatable' => true,
),
'active' => array(
'title' => $this->l('Displayed'),
'type' => 'yesno',
'required' => true,
),
'link_rewrite' => array(
'title' => $this->l('Simplified URL'),
'type' => 'text',
'required' => true,
),
'meta_title' => array(
'title' => $this->l('Title (META)'),
'type' => 'text',
'translatable' => true,
),
'meta_description' => array(
'title' => $this->l('Description (META)'),
'type' => 'textarea',
'translatable' => true,
),
);
$form->setTitle($this->l('Purchase guide category'));
$form->setFields($this->fieldsForm);
$form->enableSubmitAndBackToParent();
$form->setSubmitButton($this->l('Save'));
$form->display($smarty, $langs, $obj);
$currentIndex .= '&id_guide_category='.($obj->id?$obj->id_parent:self::$current_category->id);
}
public function displayTop()
{
global $currentIndex, $cookie;
$clean_currentIndex = $currentIndex;
$parent_category = 0;
if (Validate::isLoadedObject(self::$current_category)) {
$parent_category = new GuideCategory(self::$current_category->id_parent);
if (Validate::isLoadedObject($parent_category)) {
echo '<a href="'.$clean_currentIndex.'&token='.$this->token.'&id_guide_category='.$parent_category->id.'"><img src="../img/admin/arrow2.gif" /> '.$this->l('back to').' '.$parent_category->name[$cookie->id_lang].'</a><br /><br />';
}
else {
echo '<a href="'.$clean_currentIndex.'&token='.$this->token.'"><img src="../img/admin/arrow2.gif" /> '.$this->l('back').'</a><br /><br />';
}
echo $this->l('Current category').' : '.self::$current_category->name[$cookie->id_lang].'<br /><br />';
}
}
public function displayList()
{
global $currentIndex;
$this->displayTop();
if ($this->edit AND (!isset($this->noAdd) OR !$this->noAdd))
echo '<br /><a href="'.$currentIndex.'&id_guide_category_parent='.self::$current_category->id.'&add'.$this->table.'&token='.$this->token.'"><img src="../img/admin/add.gif" border="0" /> '.$this->l('Add new').'</a><br /><br />';
// Append when we get a syntax error in SQL query
if ($this->_list === false)
{
$this->displayWarning($this->l('Bad SQL query'));
return false;
}
// Display list header (filtering, pagination and column names)
$this->displayListHeader();
if (!sizeof($this->_list))
echo '<tr><td class="center" colspan="'.(sizeof($this->fieldsDisplay) + 2).'">'.$this->l('No items found').'</td></tr>';
// Show the content of the table
$this->displayListContent();
// Close list table and submit button
$this->displayListFooter();
}
public function viewguide_category()
{
global $cookie;
$this->getList((int)($cookie->id_lang));
$this->displayList();
$this->displayOptionsList();
$this->displayRequiredFields();
$this->includeSubTab('display');
}
protected function _displayEditLink($token = NULL, $id)
{
global $currentIndex;
$_cacheLang['Edit'] = $this->l('Edit');
echo '
<a href="'.$currentIndex.'&'.$this->identifier.'='.$id.'&update'.$this->table.'&token='.($token!=NULL ? $token : $this->token).'&id_guide_category_parent='.self::$current_category->id.'">
<img src="../img/admin/edit.gif" alt="" title="'.$_cacheLang['Edit'].'" /></a>';
}
protected function _displayDeleteLink($token = NULL, $id)
{
global $currentIndex;
$_cacheLang['Delete'] = $this->l('Delete');
$_cacheLang['DeleteItem'] = $this->l('Delete item #', __CLASS__, TRUE, FALSE);
echo '
<a href="'.$currentIndex.'&'.$this->identifier.'='.$id.'&delete'.$this->table.'&token='.($token!=NULL ? $token : $this->token).'&id_guide_category_parent='.self::$current_category->id.'" onclick="return confirm(\''.$_cacheLang['DeleteItem'].$id.' ?'.
(!is_null($this->specificConfirmDelete) ? '\r'.$this->specificConfirmDelete : '').'\');">
<img src="../img/admin/delete.gif" alt="'.$_cacheLang['Delete'].'" title="'.$_cacheLang['Delete'].'" /></a>';
}
}

View File

@ -0,0 +1,139 @@
<?php
include(__DIR__.'/classes/GuidePost.php');
include(__DIR__.'/classes/GuideCategory.php');
include(__DIR__.'/classes/FormBuilder.php');
class AdminGuidePosts extends AdminTab
{
public function __construct()
{
$this->table = 'guide_post';
$this->identifier = 'id_guide_post';
$this->className = 'GuidePost';
$this->lang = true;
$this->edit = true;
$this->view = true;
$this->delete = true;
$this->fieldsDisplay = array(
'id_guide_post' => array(
'title' => $this->l('ID'),
'align' => 'center',
'width' => 25
),
'link_rewrite' => array(
'title' => $this->l('URL'),
'width' => 200
),
'meta_title' => array(
'title' => $this->l('Title'),
'width' => 300
),
'position' => array(
'title' => $this->l('Position'),
'width' => 40,
'filter_key' => 'position',
'align' => 'center',
'position' => 'position'
),
'active' => array(
'title' => $this->l('Enabled'),
'width' => 25,
'align' => 'center',
'active' => 'status',
'type' => 'bool',
'orderby' => false
)
);
$this->_select = 'position ';
$this->_orderBy = 'position';
$this->_orderWay = 'ASC';
$this->identifiersDnd['id_guide_post'] = 'id_guide_post';
parent::__construct();
}
public function displayForm($token = NULL)
{
global $currentIndex, $cookie, $smarty;
parent::displayForm();
if (!($obj = $this->loadObject(true)))
return;
$langs = Language::getLanguages(false);
$form = new FormBuilder('AdminGuidePosts', $this->table, 'id_guide_post', 'Add');
$this->fieldsForm = array(
'id_guide_category' => array(
'title' => $this->l('Catégorie du guide'),
'type' => 'select',
'options_raw' => GuideCategory::findCategoriesTree($cookie->id_lang),
'options_map' => ['id_guide_category', 'name', 'level'],
'initial_value' => $obj->id_guide_category
),
'meta_title' => array(
'title' => $this->l('Title (META)'),
'type' => 'text',
'translatable' => true,
'attrs' => [
'onkeyup' => "copyField2friendlyURL('meta_title', 'link_rewrite');"
]
),
'meta_description' => array(
'title' => $this->l('Description (META)'),
'type' => 'textarea',
'translatable' => true,
),
'link_rewrite' => array(
'title' => $this->l('Simplified URL'),
'type' => 'text',
'required' => true,
),
'content' => array(
'title' => $this->l('Contenu de la page'),
'type' => 'textarea_tinymce',
'translatable' => true
),
'active' => array(
'title' => $this->l('Displayed'),
'type' => 'yesno',
'required' => true,
),
);
$form->setTitle($this->l('Purchase guide page'));
$form->setFields($this->fieldsForm);
$form->setSubmitButton($this->l('Save'));
$form->display($smarty, $langs, $obj);
}
public function postProcess()
{
global $cookie, $currentIndex;
$link = new Link();
if (Tools::isSubmit('viewguide_post') AND ($id_guide_post = (int)(Tools::getValue('id_guide_post'))) AND $guide_post = new GuidePost($id_guide_post, (int)($cookie->id_lang)) AND Validate::isLoadedObject($guide_post))
{
$redir = $link->getGuideLink($guide_post, null, null,
$cookie->id_lang);
if (!$guide_post->active)
{
$admin_dir = dirname($_SERVER['PHP_SELF']);
$admin_dir = substr($admin_dir, strrpos($admin_dir,'/') + 1);
$redir .= '?adtoken='.Tools::encrypt('PreviewGuidePost'.$guide_post->id).'&ad='.$admin_dir;
}
Tools::redirectAdmin($redir);
}
else {
parent::postProcess();
}
}
}

View File

@ -0,0 +1,190 @@
<?php
class FormBuilder
{
const FORM_DIR = __DIR__.'/../templates/form/';
private $class_name;
private $table_name;
private $identifier;
private $title;
private $form_inputs;
private $form_action;
private $submit_button_title;
private $bt_action_suffix = '';
public function __construct($class_name, $table_name, $identifier, $form_action)
{
$this->class_name = $class_name;
$this->table_name = $table_name;
$this->identifier = $identifier;
$this->form_action = $form_action;
}
public function setTitle($title)
{
$this->title = $title;
}
public function setSubmitButton($title)
{
$this->submit_button_title = $title;
}
public function setFields($fields)
{
$this->form_inputs = $fields;
}
public function display(&$smarty, $langs, $obj)
{
global $cookie;
$this->prepareFieldsToDisplay($obj, $langs);
$smarty_params = [
'current_id_lang' => $cookie->id_lang,
'langs' => $langs,
'page_title' => $this->title,
'form_action'=> $this->urlFormAction($this->form_action),
'form_inputs'=> $this->form_inputs,
'id_name' => $this->identifier,
'id' => $obj->id,
'module_dir' => _MODULE_DIR_,
'button_submit' => [
'name' => $this->submitName($this->form_action),
'value' => $this->submit_button_title
]
];
$smarty->assign($smarty_params);
echo $smarty->fetch(self::FORM_DIR.'form_edit.tpl');
}
private function prepareFieldsToDisplay($obj, $langs)
{
global $cookie;
foreach ($this->form_inputs as $key => &$field) {
$field['name'] = $key;
$field['value'] = '';
$field['html_attrs'] = '';
$this->prepareTemplatePath($field);
$this->prepareInputHtmlAttributes($field);
$this->prepareSelectOptions($field);
$this->prepareTinyMCE($field, $cookie);
$this->updateValueFields($field, $obj, $key, $langs);
}
}
private function prepareTemplatePath(&$field)
{
$field['template'] = self::FORM_DIR.$field['type'].'.tpl';
}
private function prepareInputHtmlAttributes(&$field)
{
if (isset($field['attrs']) && is_array($field['attrs'])) {
$html_attrs = '';
foreach($field['attrs'] as $key => $value) {
$html_attrs .= " $key = \"".$value."\"";
}
$field['html_attrs'] = $html_attrs;
}
}
private function prepareSelectOptions(&$field)
{
if (isset($field['options_raw']) && isset($field['options_map'])) {
$level_prefix = '&mdash;';
if (isset($field['level_prefix'])) {
$level_prefix = $field['level_prefix'];
}
$rows = $field['options_raw'];
$keys = $field['options_map'];
$options = [];
foreach($rows as $row) {
$options_row['value'] = $row[$keys[0]];
$options_row['label'] = $row[$keys[1]];
if (!empty($level_prefix) && $row[$keys[2]]) {
$options_row['label'] = str_repeat($level_prefix, $row[$keys[2]])
.' '.$options_row['label'];
}
$options[] = $options_row;
}
$field['options'] = $options;
}
}
private function updateValueFields(&$field, $obj, $key, $langs)
{
if (!isset($field['initial_value'])) {
$field['initial_value'] = '';
}
$value = &$field['value'];
if (isset($field['translatable']) && $field['translatable']==true) {
foreach ($langs as $lang) {
$val = $this->getFieldValue($obj, $key, $field['initial_value'], $lang['id_lang']);
$value[$lang['id_lang']] = htmlentities(
$val,
ENT_COMPAT,
'UTF-8'
);
}
}
else {
$field['value'] = $this->getFieldValue($obj, $key, $field['initial_value'], null);
}
}
private function prepareTinyMCE(&$field, $cookie)
{
if ('textarea_tinymce' == $field['type']) {
$iso = Language::getIsoById((int)($cookie->id_lang));
$field['iso'] = (file_exists(_PS_ROOT_DIR_.'/js/tiny_mce/langs/'.$iso.'.js') ? $iso : 'en');
$field['ad'] = dirname($_SERVER["PHP_SELF"]);
$field['path_theme_css'] = _THEME_CSS_DIR_;
$field['base_uri'] = __PS_BASE_URI__;
}
}
private function urlFormAction($submit_action)
{
global $currentIndex;
return $currentIndex
.'&token='.Tools::getAdminTokenLite($this->class_name)
.'&submit'.$submit_action.$this->table_name.'=1'
;
}
private function submitName($submit_action)
{
return 'submit'.$submit_action.$this->table_name.$this->bt_action_suffix;
}
public function enableSubmitAndBackToParent()
{
$this->bt_action_suffix = 'AndBackToParent';
}
private function getFieldValue($obj, $key, $initial_value, $id_lang = NULL)
{
if ($id_lang)
$defaultValue = ($obj->id AND isset($obj->{$key}[$id_lang])) ? $obj->{$key}[$id_lang] : $initial_value;
else
$defaultValue = isset($obj->{$key}) ? $obj->{$key} : $initial_value;
return Tools::getValue($key.($id_lang ? '_'.$id_lang : ''), $defaultValue);
}
}

View File

@ -0,0 +1,240 @@
<?php
class GuideCategory extends ObjectModel
{
public $id;
public $id_guide_category;
public $name;
public $active = 1;
public $description;
public $id_parent;
public $id_category_family;
public $position;
public $level_depth;
public $link_rewrite;
public $meta_title;
public $meta_keywords;
public $meta_description;
protected $table = 'guide_category';
protected $identifier = 'id_guide_category';
protected $tables = array ('guide_category', 'guide_category_lang');
protected $fieldsRequired = array('id_parent', 'active');
protected $fieldsSize = array('id_parent' => 10, 'active' => 1);
protected $fieldsValidate = array('active' => 'isBool', 'id_parent' => 'isUnsignedInt');
protected $fieldsRequiredLang = array('name', 'link_rewrite');
protected $fieldsSizeLang = array(
'name' => 64,
'link_rewrite' => 64,
'meta_title' => 128,
'meta_description' => 255,
'meta_keywords' => 255
);
protected $fieldsValidateLang = array(
'name' => 'isCatalogName',
'link_rewrite' => 'isLinkRewrite',
'description' => 'isCleanHtml',
'meta_title' => 'isGenericName',
'meta_description' => 'isGenericName',
'meta_keywords' => 'isGenericName'
);
public function getFields()
{
parent::validateFields();
if (isset($this->id))
$fields['id_guide_category'] = (int)($this->id);
$fields['id_category_family'] = (int)($this->id_category_family);
$fields['active'] = (int)($this->active);
$fields['id_parent'] = (int)($this->id_parent);
$fields['position'] = (int)($this->position);
$fields['level_depth'] = (int)($this->level_depth);
return $fields;
}
public static function findCategoriesTree($id_lang, $exclude_id=0)
{
$sql = "SELECT DISTINCT a.`id_guide_category` as id_guide_category, `name`
FROM `"._DB_PREFIX_."guide_category` a
JOIN `"._DB_PREFIX_."guide_category_lang` b
ON a.`id_guide_category` = b.`id_guide_category`
WHERE b.id_lang = '".intval($id_lang)."'
AND a.`id_parent` = '%s'
";
if ($exclude_id!='0') {
$sql .= " AND a.`id_guide_category` <> '".intval($exclude_id)."'";
}
$rows = [];
self::findRecursiveData(
$rows,
$sql,
array(
'id_parent' => 0,
'identifier' => 'id_guide_category',
'level' => -1
)
);
return $rows;
}
public static function findFamiliesTree($id_lang, $exclude_id=0)
{
$sql = "SELECT DISTINCT a.`id_category_family` as id_category_family, `name`
FROM `"._DB_PREFIX_."category_family` a
JOIN `"._DB_PREFIX_."category_family_lang` b
ON a.`id_category_family` = b.`id_category_family`
WHERE b.id_lang = '".intval($id_lang)."'
AND a.`id_parent` = '%d'
";
if ($exclude_id!='0') {
$sql .= " AND a.`id_category_family` <> '".intval($exclude_id)."'";
}
$rows = [];
self::findRecursiveData(
$rows,
$sql,
array(
'id_parent' => 0,
'identifier' => 'id_category_family',
'level' => -1
)
);
return $rows;
}
private static function findRecursiveData(
&$rows,
$sql,
array $params
)
{
$level = $params['level'];
$level++;
$resuts = Db::getInstance()->ExecuteS(sprintf($sql, intval($params['id_parent'])));
foreach($resuts as &$row) {
$row['level'] = $level;
$rows[] = $row;
self::findRecursiveData(
$rows,
$sql,
array(
'id_parent' => $row[$params['identifier']],
'identifier' => $params['identifier'],
'level' => $level
)
);
}
}
/////
// Check then return multilingual fields for database interaction
//
// @return array Multilingual fields
///
public function getTranslationsFieldsChild()
{
parent::validateFieldsLang();
return parent::getTranslationsFields(array('name', 'description', 'link_rewrite', 'meta_title', 'meta_keywords', 'meta_description'));
}
public function delete()
{
// transfert all posts to
// the category's parent.
$sql = 'UPDATE `'._DB_PREFIX_.'guide_post`
SET `id_guide_category` = '.intval($this->id_parent).'
WHERE `id_guide_category` = '.intval($this->id);
Db::getInstance()->Execute($sql);
// transfert all categorie's children to
// the category's parent.
$sql = 'UPDATE `'._DB_PREFIX_.'guide_category`
SET `id_parent` = '.intval($this->id_parent).'
WHERE `id_parent` = '.intval($this->id);
Db::getInstance()->Execute($sql);
$id_parent = $this->id_parent;
parent::delete();
$this->cleanupPositions($id_parent);
}
public function add($autodate = true, $nullValues = false)
{
$this->position = self::getLastPosition((int)$this->id_parent);
return parent::add($autodate, $nullValues);
}
public function update($autodate = true, $nullValues = false)
{
$this->position = self::cleanupPositions((int)$this->id_parent);
return parent::update($autodate, $nullValues);
}
public function updatePosition($way, $position)
{
if (!$res = Db::getInstance()->ExecuteS('
SELECT cp.`id_guide_category`, cp.`position`, cp.`id_parent`
FROM `'._DB_PREFIX_.'guide_category` cp
WHERE cp.`id_parent` = '.(int)$this->id_parent.'
ORDER BY cp.`position` ASC'
))
return false;
foreach ($res AS $category)
if ((int)($category['id_guide_category']) == (int)($this->id))
$movedCategory = $category;
if (!isset($movedCategory) || !isset($position))
return false;
// < and > statements rather than BETWEEN operator
// since BETWEEN is treated differently according to databases
return (Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'guide_category`
SET `position`= `position` '.($way ? '- 1' : '+ 1').'
WHERE `position`
'.($way
? '> '.(int)($movedCategory['position']).' AND `position` <= '.(int)($position)
: '< '.(int)($movedCategory['position']).' AND `position` >= '.(int)($position)).'
AND `id_parent`='.(int)($movedCategory['id_parent']))
AND Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'guide_category`
SET `position` = '.(int)($position).'
WHERE `id_parent` = '.(int)($movedCategory['id_parent']).'
AND `id_guide_category`='.(int)($movedCategory['id_guide_category'])));
}
public static function getLastPosition($id_parent)
{
return (Db::getInstance()->getValue('SELECT MAX(position)+1 FROM `'._DB_PREFIX_.'guide_category` WHERE `id_parent` = '.(int)($id_parent)));
}
private function cleanupPositions($id_parent)
{
$sql = 'SELECT `id_guide_category`
FROM `'._DB_PREFIX_.'guide_category`
WHERE `id_parent` = '.intval($id_parent).'
ORDER BY `position` ASC';
$rows = Db::getInstance()->ExecuteS($sql);
$position = 1;
foreach($rows as $row) {
$sql = 'UPDATE `'._DB_PREFIX_.'guide_category`
SET `position` = '.$position.'
WHERE `id_guide_category` = '.$row['id_guide_category'];
Db::getInstance()->Execute($sql);
$position++;
}
return $position;
}
}

View File

@ -0,0 +1,138 @@
<?php
class GuidePost extends ObjectModel
{
public $id;
public $id_guide_post;
public $id_guide_category;
public $position;
public $active;
public $meta_title;
public $meta_description;
public $meta_keywords;
public $content;
public $link_rewrite;
protected $fieldsValidate = array('id_guide_category' => 'isUnsignedInt');
protected $fieldsRequiredLang = array('meta_title', 'link_rewrite');
protected $fieldsSizeLang = array('meta_description' => 255, 'meta_keywords' => 255, 'meta_title' => 128, 'link_rewrite' => 128, 'content' => 3999999999999);
protected $fieldsValidateLang = array('meta_description' => 'isGenericName', 'meta_keywords' => 'isGenericName', 'meta_title' => 'isGenericName', 'link_rewrite' => 'isLinkRewrite', 'content' => 'isString');
protected $table = 'guide_post';
protected $identifier = 'id_guide_post';
protected $webserviceParameters = array(
'objectNodeName' => 'content',
'objectsNodeName' => 'content_management_system',
);
public function getFields()
{
parent::validateFields();
$fields['id_guide_post'] = (int)($this->id);
$fields['id_guide_category'] = (int)($this->id_guide_category);
$fields['position'] = (int)($this->position);
$fields['active'] = (int)($this->active);
return $fields;
}
public function getTranslationsFieldsChild()
{
parent::validateFieldsLang();
$fieldsArray = array('meta_title', 'meta_description', 'meta_keywords', 'link_rewrite');
$fields = array();
$languages = Language::getLanguages(false);
$defaultLanguage = (int)(Configuration::get('PS_LANG_DEFAULT'));
foreach ($languages as $language)
{
$fields[$language['id_lang']]['id_lang'] = (int)($language['id_lang']);
$fields[$language['id_lang']][$this->identifier] = (int)($this->id);
$fields[$language['id_lang']]['content'] = (isset($this->content[$language['id_lang']])) ? pSQL($this->content[$language['id_lang']], true) : '';
foreach ($fieldsArray as $field)
{
if (!Validate::isTableOrIdentifier($field))
die(Tools::displayError());
if (isset($this->{$field}[$language['id_lang']]) AND !empty($this->{$field}[$language['id_lang']]))
$fields[$language['id_lang']][$field] = pSQL($this->{$field}[$language['id_lang']]);
elseif (in_array($field, $this->fieldsRequiredLang))
$fields[$language['id_lang']][$field] = pSQL($this->{$field}[$defaultLanguage]);
else
$fields[$language['id_lang']][$field] = '';
}
}
return $fields;
}
public function updatePosition($way, $position)
{
if (!$res = Db::getInstance()->ExecuteS('
SELECT cp.`id_guide_post`, cp.`position`, cp.`id_guide_category`
FROM `'._DB_PREFIX_.'guide_post` cp
WHERE cp.`id_guide_category` = '.(int)$this->id_guide_category.'
ORDER BY cp.`position` ASC'
))
return false;
foreach ($res AS $guide_post)
if ((int)($guide_post['id_guide_post']) == (int)($this->id))
$movedPost = $guide_post;
if (!isset($movedPost) || !isset($position))
return false;
// < and > statements rather than BETWEEN operator
// since BETWEEN is treated differently according to databases
return (Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'guide_post`
SET `position`= `position` '.($way ? '- 1' : '+ 1').'
WHERE `position`
'.($way
? '> '.(int)($movedPost['position']).' AND `position` <= '.(int)($position)
: '< '.(int)($movedPost['position']).' AND `position` >= '.(int)($position)).'
AND `id_guide_category`='.(int)($movedPost['id_guide_category']))
AND Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'guide_post`
SET `position` = '.(int)($position).'
WHERE `id_guide_post` = '.(int)($movedPost['id_guide_post']).'
AND `id_guide_category`='.(int)($movedPost['id_guide_category'])));
}
public function add($autodate = true, $nullValues = false)
{
$this->position = self::getLastPosition((int)$this->id_guide_category);
return parent::add($autodate, $nullValues);
}
public function update($autodate = true, $nullValues = false)
{
$this->position = self::cleanupPositions((int)$this->id_guide_category);
return parent::update($autodate, $nullValues);
}
public static function getLastPosition($id_guide_category)
{
$position = Db::getInstance()->getValue('SELECT MAX(position)+1 FROM `'._DB_PREFIX_.'guide_post` WHERE `id_guide_category` = '.(int)($id_guide_category));
return $position?:1;
}
private function cleanupPositions($id_guide_category)
{
$sql = 'SELECT `id_guide_post`
FROM `'._DB_PREFIX_.'guide_post`
WHERE `id_guide_category` = '.intval($id_guide_category).'
ORDER BY `position` ASC';
$rows = Db::getInstance()->ExecuteS($sql);
$position = 1;
foreach($rows as $row) {
$sql = 'UPDATE `'._DB_PREFIX_.'guide_post`
SET `position` = '.$position.'
WHERE `id_guide_post` = '.$row['id_guide_post'];
Db::getInstance()->Execute($sql);
$position++;
}
return $position;
}
}

View File

@ -0,0 +1,15 @@
<?php
include(dirname(__FILE__).'/../../config/config.inc.php');
require_once(__DIR__.'/classes/GuidePost.php');
$id_lang = Tools::getValue('id_lang', 1);
$post = new GuidePost((int)(Tools::getValue('id_guide_post')));
if (Validate::isLoadedObject($post)) {
global $cookie;
echo $post->meta_title[$id_lang];
echo $post->content[$id_lang];
}

View File

@ -0,0 +1,270 @@
<?php
if (!defined('_PS_VERSION_'))
exit;
class PurchaseGuide extends Module
{
const MODULE_NAME = 'purchaseguide';
public function __construct() {
$this->name = self::MODULE_NAME;
$this->tab = 'front_office_features';
$this->author = 'Antadis';
$this->version = '1.0';
parent::__construct();
$this->displayName = $this->l('Purchase Guide');
$this->description = $this->l('Purchase Guide editor for Prestashop');
}
public function install()
{
if(!parent::install()
|| !$this->installTabs()
|| !$this->createTables()
//|| !$this->addInHtAccess()
) {
$this->uninstall();
return FALSE;
}
return TRUE;
}
public function uninstall()
{
$this->uninstallTabs();
$this->dropTables();
//$this->removeFromHtAccess();
return parent::uninstall();
}
private function installTabs()
{
$tab_params = [
'class_name' => 'AdminGuide',
'id_parent' => 0,
'tabs_i18n' => array(
'en' => 'Purchase guide',
'fr' => 'Guide d\'achat',
)
];
$id_tab_guide = $this->addTab($tab_params);
$tab_params = [
'class_name' => 'AdminGuideCategories',
'id_parent' => $id_tab_guide,
'tabs_i18n' => array(
'en' => 'Guide categories',
'fr' => 'Catégories',
)
];
$this->addTab($tab_params);
$tab_params = [
'class_name' => 'AdminGuidePosts',
'id_parent' => $id_tab_guide,
'tabs_i18n' => array(
'en' => 'Pages',
'fr' => 'Pages',
)
];
$this->addTab($tab_params);
return TRUE;
}
private function addTab($param)
{
$last_position = Db::getInstance()->getValue(
'SELECT MAX(position)
FROM `'._DB_PREFIX_.'tab`
WHERE `id_parent` = '.$param['id_parent'].'
');
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'tab`
VALUES (DEFAULT, "'.$param['id_parent'].'", "'.$param['class_name'].'", "'.self::MODULE_NAME.'", '.($last_position+1).')
');
$tab_id = Db::getInstance()->Insert_ID();
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'access`
VALUES (1, '.$tab_id.', 1, 1, 1, 1)
');
$langs = Db::getInstance()->ExecuteS('
SELECT `id_lang`, `iso_code`
FROM `'._DB_PREFIX_.'lang`
');
foreach($langs as $lang) {
if(isset($param['tabs_i18n'][$lang['iso_code']])) {
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'tab_lang`
VALUES ('.$tab_id.', '.$lang['id_lang'].', "'.$param['tabs_i18n'][$lang['iso_code']].'")
');
} else {
Db::getInstance()->Execute('
INSERT INTO `'._DB_PREFIX_.'tab_lang`
VALUES ('.$tab_id.', '.$lang['id_lang'].', "'.$param['tabs_i18n']['en'].'")
');
}
}
return $tab_id;
}
private function uninstallTabs()
{
$rows = Db::getInstance()->ExecuteS('
SELECT `id_tab`
FROM `'._DB_PREFIX_.'tab`
WHERE `module` = "'.self::MODULE_NAME.'"
');
foreach ($rows as $row) {
Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'tab_lang`
WHERE `id_tab` = '.$row['id_tab']
);
Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'access`
WHERE `id_tab` = '.$row['id_tab']
);
}
Db::getInstance()->Execute('
DELETE FROM `'._DB_PREFIX_.'tab`
WHERE `module` = "'.self::MODULE_NAME.'"
');
}
private function getHtAccessRewriteRules()
{
return "\nRewriteRule ^guide/([0-9]+)-([a-zA-Z0-9-]*) /modules/".self::MODULE_NAME."/page.php?id_guide_post=$1 [QSA,L]";
}
private function addInHtAccess()
{
$_htFile = dirname(__FILE__).'/../../.htaccess';
$value = Configuration::get('PS_HTACCESS_SPECIFIC');
$value .= $this->getHtAccessRewriteRules();
Configuration::updateValue('PS_HTACCESS_SPECIFIC', $value, true);
if (Tools::generateHtaccess($_htFile,
Configuration::get('PS_REWRITING_SETTINGS'),
Configuration::get('PS_HTACCESS_CACHE_CONTROL'),
Configuration::get('PS_HTACCESS_SPECIFIC'),
Configuration::get('PS_HTACCESS_DISABLE_MULTIVIEWS'))) {
return true;
}
$this->_errors[] = $this->l('Cannot write into file:').' <b>'.$_htFile.'</b><br />'.$this->l('Please check write permissions.');
return false;
}
private function removeFromHtAccess()
{
$_htFile = dirname(__FILE__).'/../../.htaccess';
$value = Configuration::get('PS_HTACCESS_SPECIFIC');
$value = str_replace('', $this->getHtAccessRewriteRules(), $value);
Configuration::updateValue('PS_HTACCESS_SPECIFIC', $value, true);
if (Tools::generateHtaccess($_htFile,
Configuration::get('PS_REWRITING_SETTINGS'),
Configuration::get('PS_HTACCESS_CACHE_CONTROL'),
Configuration::get('PS_HTACCESS_SPECIFIC'),
Configuration::get('PS_HTACCESS_DISABLE_MULTIVIEWS'))) {
return true;
}
$this->_errors[] = $this->l('Cannot write into file:').' <b>'.$_htFile.'</b><br />'.$this->l('Please check write permissions.');
return false;
}
private function createTables()
{
$queries[] = '
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'guide_category` (
`id_guide_category` INTEGER NOT NULL AUTO_INCREMENT,
`id_parent` INTEGER NOT NULL,
`id_category_family` INTEGER NOT NULL,
`level_depth` tinyint(3) not null default 0,
`position` int(10) unsigned not null default 0,
`active` tinyint(1) not null default 0,
PRIMARY KEY(`id_guide_category`),
INDEX(`id_parent`)
) ENGINE=MyIsam DEFAULT CHARSET=utf8
';
$queries[] = '
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'guide_category_lang` (
`id_guide_category` INTEGER NOT NULL,
`id_lang` INTEGER NOT NULL,
`name` varchar(128) null,
`description` text null,
`link_rewrite` varchar(128) not null,
`meta_title` varchar(128) not null,
`meta_description` varchar(255) null,
`meta_keywords` varchar(255) null,
PRIMARY KEY(`id_guide_category`, `id_lang`)
) ENGINE=MyIsam DEFAULT CHARSET=utf8
';
$queries[] = '
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'guide_post` (
`id_guide_post` INTEGER NOT NULL AUTO_INCREMENT,
`id_guide_category` INTEGER NOT NULL,
`position` int(10) unsigned not null default 0,
`active` tinyint(1) not null default 0,
PRIMARY KEY(`id_guide_post`),
INDEX(`id_guide_category`)
) ENGINE=MyIsam DEFAULT CHARSET=utf8
';
$queries[] = '
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'guide_post_lang` (
`id_guide_post` INTEGER NOT NULL,
`id_lang` INTEGER NOT NULL,
`meta_title` varchar(255) not null,
`meta_description` varchar(255) null,
`meta_keywords` varchar(255) null,
`content` longtext null,
`link_rewrite` varchar(128) not null,
PRIMARY KEY(`id_guide_post`, `id_lang`)
) ENGINE=MyIsam DEFAULT CHARSET=utf8
';
foreach ($queries as $query) {
if (!Db::getInstance()->Execute($query)) {
return FALSE;
}
}
return TRUE;
}
private function dropTables()
{
$queries[] = 'DROP TABLE `'._DB_PREFIX_.'guide_post_lang`';
$queries[] = 'DROP TABLE `'._DB_PREFIX_.'guide_post`';
$queries[] = 'DROP TABLE `'._DB_PREFIX_.'guide_category_lang`';
$queries[] = 'DROP TABLE `'._DB_PREFIX_.'guide_category`';
foreach ($queries as $query) {
Db::getInstance()->Execute($query);
}
}
}

View File

@ -0,0 +1,37 @@
<form action="{$form_action}" method="post" enctype="multipart/form-data">
<input name="{$id_name}" value="{$id}" type="hidden">
<fieldset style="width:520px"><legend><img src="../img/admin/tab-categories.gif">{$page_title}</legend>
{foreach from=$form_inputs key=input_name item=input_data}
{include file=$input_data.template
input=$input_data
langs=$langs
current_id_lang=$current_id_lang}
{/foreach}
<div class="margin-form">
<input class="button" name="{$button_submit.name}" value="{$button_submit.value}" type="submit">
</div>
<div class="small"><sup>*</sup> {l s='Required fields'}</div>
</fieldset>
</form>
<link type="text/css" rel="stylesheet" href="{$module_dir}/bulkupdate/chosen.min.css" />
<script type="text/javascript" src="{$module_dir}/bulkupdate/chosen.jquery.min.js"></script>
<script type="text/javascript">
$(".chosen-select").chosen(
{
allow_single_deselect:true,
placeholder_text_single : "",
no_results_text : "",
enable_split_word_search : true,
search_contains : true,
}
);
var copyField2friendlyURL = function(id_source, id_target)
{
$('#'+ id_target +'_'+ id_language).val(str2url($('#'+id_source+'_' + id_language).val().replace(/^[0-9]+\./, ''), 'UTF-8'));
}
</script>

View File

@ -0,0 +1,25 @@
<label>{$input.title} : </label>
<div class="margin-form">
<select id="{$input.name}" name="{$input.name}" class="chosen-select" {$input.html_attrs} >
{if isset($input.empty_option) && $input.empty_option}
<option value="{$input.empty_option.value}" {if $input.value == '0'}selected="selected"{/if}>{$input.empty_option.label}</option>
{/if}
{foreach from=$input.options item=option}
<option value="{$option.value}" {if $input.value == $option.value}selected="selected"{/if}>
{$option.label}
</option>
{/foreach}
</select>
{if isset($input.required) && $input.required}
<sup> *</sup>
{/if}
</div>

View File

@ -0,0 +1,23 @@
<label>{$input.title} : </label>
<div class="margin-form translatable">
{foreach from=$langs item=lang}
<div class="lang_{$lang.id_lang}" style="display: {if $lang.id_lang == $current_id_lang}block {else} none{/if}; float: left;">
<input style="width: 260px" name="{$input.name}_{$lang.id_lang}" id="{$input.name}_{$lang.id_lang}" value="{if isset($input.value[$lang.id_lang])}{$input.value[$lang.id_lang]}{/if}" type="text"
{$input.html_attrs} class="test"
>
{if isset($input.required) && $input.required}
<sup> *</sup>
{/if}
<span class="hint" name="help_box">Caractères interdits : &lt;&gt;;=#{}<span class="hint-pointer">&nbsp;</span></span>
</div>
{/foreach}
<p class="clear"></p>
</div>

View File

@ -0,0 +1,20 @@
<label>{$input.title} : </label>
<div class="margin-form translatable">
{foreach from=$langs item=lang}
<div class="lang_{$lang.id_lang}" style="display: {if $lang.id_lang == $current_id_lang}block {else} none{/if}; float: left;">
<textarea {if isset($input.enable_rte) && $input.enable_rte}class="rte"{/if} name="{$input.name}_{$lang.id_lang}" rows="5" cols="40" {$input.html_attrs} >{if isset($input.value[$lang.id_lang])}{$input.value[$lang.id_lang]}{/if}</textarea>
</div>
{/foreach}
{if isset($input.required) && $input.required}
<sup> *</sup>
{/if}
<p class="clear"></p>
</div>
<div class="clear"><br></div>

View File

@ -0,0 +1,27 @@
<label>{$input.title} : </label>
<div class="margin-form translatable">
{foreach from=$langs item=lang}
<div class="lang_{$lang.id_lang}" style="display: {if $lang.id_lang == $current_id_lang}block {else} none{/if}; float: left;">
<textarea class="rte" name="{$input.name}_{$lang.id_lang}" rows="30" cols="80" {$input.html_attrs} >{if isset($input.value[$lang.id_lang])}{$input.value[$lang.id_lang]}{/if}</textarea>
</div>
{/foreach}
{if isset($input.required) && $input.required}
<sup> *</sup>
{/if}
<p class="clear"></p>
</div>
<div class="clear"><br></div>
<script type="text/javascript">
var iso = '{$input.iso}';
var pathCSS = '{$input.path_theme_css}';
var ad = '{$input.ad}' ;
</script>
<script type="text/javascript" src="{$input.base_uri}js/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript" src="{$input.base_uri}js/tinymce.inc.js"></script>'

View File

@ -0,0 +1,15 @@
<label>{$input.title} : </label>
<div class="margin-form">
<input name="{$input.name}" id="{$input.name}_on" value="1" type="radio" {if $input.value == '1'}checked="checked"{/if} {$input.html_attrs} >
<label class="t" for="{$input.name}_on" ><img src="../img/admin/enabled.gif" alt="Activé" title="Activé"></label>
<input name="{$input.name}" id="{$input.name}_off" value="0" type="radio" {if $input.value != '1'}checked="checked"{/if} {$input.html_attrs} >
<label class="t" for="{$input.name}_off"><img src="../img/admin/disabled.gif" alt="Désactivé" title="Désactivé"></label>
{if isset($input.required) && $input.required}
<sup> *</sup>
{/if}
</div>

31
override/classes/Link.php Normal file
View File

@ -0,0 +1,31 @@
<?php
class Link extends LinkCore
{
public function getGuideLink($guide_post, $alias = null, $ssl = false, $id_lang = NULL)
{
if (is_object($guide_post)) {
$id = (int)($guide_post->id);
$alias = $guide_post->link_rewrite;
}
else {
$id = (int)($guide_post);
}
if ($this->allow == 1) {
$url = __PS_BASE_URI__.$this->getLangLink((int)($id_lang)).'guide/';
$url .= $id.($alias?'-'.$alias:'');
}
else {
$url = $this->moduleGuideDir($ssl).'page.php?id_guide_post='.$id.'&id_lang='.$id_lang;
}
return $url;
}
private function moduleGuideDir($ssl)
{
$base = (($ssl AND Configuration::get('PS_SSL_ENABLED')) ? Tools::getShopDomainSsl(true) : Tools::getShopDomain(true));
return $base._MODULE_DIR_.'/'.Module::getModuleNameFromClass('AdminGuidePosts').'/';
}
}