PageRenderTime 60ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/controllers/admin/AdminFeaturesController.php

https://github.com/netplayer/PrestaShop
PHP | 616 lines | 472 code | 67 blank | 77 comment | 83 complexity | 41b2b29eef54470a102b807547056f88 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /*
  3. * 2007-2014 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2014 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class AdminFeaturesControllerCore extends AdminController
  27. {
  28. public $bootstrap = true;
  29. protected $position_identifier = 'id_feature';
  30. protected $feature_name;
  31. public function __construct()
  32. {
  33. $this->table = 'feature';
  34. $this->className = 'Feature';
  35. $this->list_id = 'feature';
  36. $this->identifier = 'id_feature';
  37. $this->lang = true;
  38. $this->fields_list = array(
  39. 'id_feature' => array(
  40. 'title' => $this->l('ID'),
  41. 'align' => 'center',
  42. 'class' => 'fixed-width-xs'
  43. ),
  44. 'name' => array(
  45. 'title' => $this->l('Name'),
  46. 'width' => 'auto',
  47. 'filter_key' => 'b!name'
  48. ),
  49. 'value' => array(
  50. 'title' => $this->l('Values'),
  51. 'orderby' => false,
  52. 'search' => false,
  53. 'align' => 'center',
  54. 'class' => 'fixed-width-xs'
  55. ),
  56. 'position' => array(
  57. 'title' => $this->l('Position'),
  58. 'filter_key' => 'a!position',
  59. 'align' => 'center',
  60. 'class' => 'fixed-width-xs',
  61. 'position' => 'position'
  62. )
  63. );
  64. $this->bulk_actions = array(
  65. 'delete' => array(
  66. 'text' => $this->l('Delete selected'),
  67. 'icon' => 'icon-trash',
  68. 'confirm' => $this->l('Delete selected items?')
  69. )
  70. );
  71. parent::__construct();
  72. }
  73. /**
  74. * AdminController::renderList() override
  75. * @see AdminController::renderList()
  76. */
  77. public function renderList()
  78. {
  79. $this->addRowAction('view');
  80. $this->addRowAction('edit');
  81. $this->addRowAction('delete');
  82. return parent::renderList();
  83. }
  84. /**
  85. * Change object type to feature value (use when processing a feature value)
  86. */
  87. protected function setTypeValue()
  88. {
  89. $this->table = 'feature_value';
  90. $this->className = 'FeatureValue';
  91. $this->identifier = 'id_feature_value';
  92. }
  93. /**
  94. * Change object type to feature (use when processing a feature)
  95. */
  96. protected function setTypeFeature()
  97. {
  98. $this->table = 'feature';
  99. $this->className = 'Feature';
  100. $this->identifier = 'id_feature';
  101. }
  102. public function renderView()
  103. {
  104. if (($id = Tools::getValue('id_feature')))
  105. {
  106. $this->setTypeValue();
  107. $this->list_id = 'feature_value';
  108. $this->lang = true;
  109. // Action for list
  110. $this->addRowAction('edit');
  111. $this->addRowAction('delete');
  112. if (!Validate::isLoadedObject($obj = new Feature((int)$id)))
  113. {
  114. $this->errors[] = Tools::displayError('An error occurred while updating the status for an object.').' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
  115. return;
  116. }
  117. $this->feature_name = $obj->name;
  118. $this->toolbar_title = $this->feature_name[$this->context->employee->id_lang];
  119. $this->fields_list = array(
  120. 'id_feature_value' => array(
  121. 'title' => $this->l('ID'),
  122. 'align' => 'center',
  123. 'class' => 'fixed-width-xs'
  124. ),
  125. 'value' => array(
  126. 'title' => $this->l('Value')
  127. )
  128. );
  129. $this->_where = sprintf('AND `id_feature` = %d', (int)$id);
  130. self::$currentIndex = self::$currentIndex.'&id_feature='.(int)$id.'&viewfeature';
  131. $this->processFilter();
  132. return parent::renderList();
  133. }
  134. }
  135. /**
  136. * AdminController::renderForm() override
  137. * @see AdminController::renderForm()
  138. */
  139. public function renderForm()
  140. {
  141. $this->toolbar_title = $this->l('Add a new feature');
  142. $this->fields_form = array(
  143. 'legend' => array(
  144. 'title' => $this->l('Feature'),
  145. 'icon' => 'icon-info-sign'
  146. ),
  147. 'input' => array(
  148. array(
  149. 'type' => 'text',
  150. 'label' => $this->l('Name'),
  151. 'name' => 'name',
  152. 'lang' => true,
  153. 'size' => 33,
  154. 'hint' => $this->l('Invalid characters:').' <>;=#{}',
  155. 'required' => true
  156. )
  157. )
  158. );
  159. if (Shop::isFeatureActive())
  160. {
  161. $this->fields_form['input'][] = array(
  162. 'type' => 'shop',
  163. 'label' => $this->l('Shop association'),
  164. 'name' => 'checkBoxShopAsso',
  165. );
  166. }
  167. $this->fields_form['submit'] = array(
  168. 'title' => $this->l('Save'),
  169. );
  170. return parent::renderForm();
  171. }
  172. public function initPageHeaderToolbar()
  173. {
  174. if (empty($this->display))
  175. {
  176. $this->page_header_toolbar_btn['new_feature'] = array(
  177. 'href' => self::$currentIndex.'&addfeature&token='.$this->token,
  178. 'desc' => $this->l('Add new feature', null, null, false),
  179. 'icon' => 'process-icon-new'
  180. );
  181. $this->page_header_toolbar_btn['new_feature_value'] = array(
  182. 'href' => self::$currentIndex.'&addfeature_value&id_feature='.(int)Tools::getValue('id_feature').'&token='.$this->token,
  183. 'desc' => $this->l('Add new feature value', null, null, false),
  184. 'icon' => 'process-icon-new'
  185. );
  186. }
  187. if ($this->display == 'view')
  188. $this->page_header_toolbar_btn['new_feature_value'] = array(
  189. 'href' => self::$currentIndex.'&addfeature_value&id_feature='.(int)Tools::getValue('id_feature').'&token='.$this->token,
  190. 'desc' => $this->l('Add new feature value', null, null, false),
  191. 'icon' => 'process-icon-new'
  192. );
  193. parent::initPageHeaderToolbar();
  194. }
  195. /**
  196. * AdminController::initToolbar() override
  197. * @see AdminController::initToolbar()
  198. */
  199. public function initToolbar()
  200. {
  201. switch ($this->display)
  202. {
  203. case 'editFeatureValue':
  204. case 'add':
  205. case 'edit':
  206. $this->toolbar_btn['save'] = array(
  207. 'href' => '#',
  208. 'desc' => $this->l('Save')
  209. );
  210. if ($this->display == 'editFeatureValue')
  211. $this->toolbar_btn['save-and-stay'] = array(
  212. 'short' => 'SaveAndStay',
  213. 'href' => '#',
  214. 'desc' => $this->l('Save and add another value'),
  215. 'force_desc' => true,
  216. );
  217. // Default cancel button - like old back link
  218. $back = Tools::safeOutput(Tools::getValue('back', ''));
  219. if (empty($back))
  220. $back = self::$currentIndex.'&token='.$this->token;
  221. $this->toolbar_btn['back'] = array(
  222. 'href' => $back,
  223. 'desc' => $this->l('Back to the list')
  224. );
  225. break;
  226. case 'view':
  227. $this->toolbar_btn['newAttributes'] = array(
  228. 'href' => self::$currentIndex.'&addfeature_value&id_feature='.(int)Tools::getValue('id_feature').'&token='.$this->token,
  229. 'desc' => $this->l('Add new feature values')
  230. );
  231. $this->toolbar_btn['back'] = array(
  232. 'href' => self::$currentIndex.'&token='.$this->token,
  233. 'desc' => $this->l('Back to the list')
  234. );
  235. break;
  236. default:
  237. parent::initToolbar();
  238. }
  239. }
  240. public function initToolbarTitle()
  241. {
  242. $bread_extended = $this->breadcrumbs;
  243. switch ($this->display)
  244. {
  245. case 'edit':
  246. $bread_extended[] = $this->l('Edit New Feature');
  247. break;
  248. case 'add':
  249. $bread_extended[] = $this->l('Add New Feature');
  250. break;
  251. case 'view':
  252. $bread_extended[] = $this->feature_name[$this->context->employee->id_lang];
  253. break;
  254. case 'editFeatureValue':
  255. if (($id_feature_value = Tools::getValue('id_feature_value')))
  256. {
  257. if (($id = Tools::getValue('id_feature')))
  258. {
  259. if (Validate::isLoadedObject($obj = new Feature((int)$id)))
  260. $bread_extended[] = '<a href="'.Context::getContext()->link->getAdminLink('AdminFeatures').'&id_feature='.$id.'&viewfeature">'.$obj->name[$this->context->employee->id_lang].'</a>';
  261. if (Validate::isLoadedObject($obj = new FeatureValue((int)Tools::getValue('id_feature_value'))))
  262. $bread_extended[] = sprintf($this->l('Edit: %s'), $obj->value[$this->context->employee->id_lang]);
  263. }
  264. else
  265. $bread_extended[] = $this->l('Edit Value');
  266. }
  267. else
  268. $bread_extended[] = $this->l('Add New Value');
  269. break;
  270. }
  271. $this->toolbar_title = $bread_extended;
  272. }
  273. /**
  274. * AdminController::renderForm() override
  275. * @see AdminController::renderForm()
  276. */
  277. public function initFormFeatureValue()
  278. {
  279. $this->setTypeValue();
  280. $this->fields_form[0]['form'] = array(
  281. 'legend' => array(
  282. 'title' => $this->l('Feature value'),
  283. 'icon' => 'icon-info-sign'
  284. ),
  285. 'input' => array(
  286. array(
  287. 'type' => 'select',
  288. 'label' => $this->l('Feature'),
  289. 'name' => 'id_feature',
  290. 'options' => array(
  291. 'query' => Feature::getFeatures($this->context->language->id),
  292. 'id' => 'id_feature',
  293. 'name' => 'name'
  294. ),
  295. 'required' => true
  296. ),
  297. array(
  298. 'type' => 'text',
  299. 'label' => $this->l('Value'),
  300. 'name' => 'value',
  301. 'lang' => true,
  302. 'size' => 33,
  303. 'hint' => $this->l('Invalid characters:').' <>;=#{}',
  304. 'required' => true
  305. ),
  306. ),
  307. 'submit' => array(
  308. 'title' => $this->l('Save'),
  309. ),
  310. 'buttons' => array(
  311. 'save-and-stay' => array(
  312. 'title' => $this->l('Save then add another value'),
  313. 'name' => 'submitAdd'.$this->table.'AndStay',
  314. 'type' => 'submit',
  315. 'class' => 'btn btn-default pull-right',
  316. 'icon' => 'process-icon-save'
  317. )
  318. )
  319. );
  320. $this->fields_value['id_feature'] = (int)Tools::getValue('id_feature');
  321. // Create Object FeatureValue
  322. $feature_value = new FeatureValue(Tools::getValue('id_feature_value'));
  323. $this->tpl_vars = array(
  324. 'feature_value' => $feature_value,
  325. );
  326. $this->getlanguages();
  327. $helper = new HelperForm();
  328. $helper->show_cancel_button = true;
  329. $back = Tools::safeOutput(Tools::getValue('back', ''));
  330. if (empty($back))
  331. $back = self::$currentIndex.'&token='.$this->token;
  332. if (!Validate::isCleanHtml($back))
  333. die(Tools::displayError());
  334. $helper->back_url = $back;
  335. $helper->currentIndex = self::$currentIndex;
  336. $helper->token = $this->token;
  337. $helper->table = $this->table;
  338. $helper->identifier = $this->identifier;
  339. $helper->override_folder = 'feature_value/';
  340. $helper->id = $feature_value->id;
  341. $helper->toolbar_scroll = false;
  342. $helper->tpl_vars = $this->tpl_vars;
  343. $helper->languages = $this->_languages;
  344. $helper->default_form_language = $this->default_form_language;
  345. $helper->allow_employee_form_lang = $this->allow_employee_form_lang;
  346. $helper->fields_value = $this->getFieldsValue($feature_value);
  347. $helper->toolbar_btn = $this->toolbar_btn;
  348. $helper->title = $this->l('Add a new feature value');
  349. $this->content .= $helper->generateForm($this->fields_form);
  350. }
  351. /**
  352. * AdminController::initContent() override
  353. * @see AdminController::initContent()
  354. */
  355. public function initContent()
  356. {
  357. if (Feature::isFeatureActive())
  358. {
  359. // toolbar (save, cancel, new, ..)
  360. $this->initTabModuleList();
  361. $this->initToolbar();
  362. $this->initPageHeaderToolbar();
  363. if ($this->display == 'edit' || $this->display == 'add')
  364. {
  365. if (!$this->loadObject(true))
  366. return;
  367. $this->content .= $this->renderForm();
  368. }
  369. else if ($this->display == 'view')
  370. {
  371. // Some controllers use the view action without an object
  372. if ($this->className)
  373. $this->loadObject(true);
  374. $this->content .= $this->renderView();
  375. }
  376. else if ($this->display == 'editFeatureValue')
  377. {
  378. if (!$this->object = new FeatureValue((int)Tools::getValue('id_feature_value')))
  379. return;
  380. $this->content .= $this->initFormFeatureValue();
  381. }
  382. else if (!$this->ajax)
  383. {
  384. // If a feature value was saved, we need to reset the values to display the list
  385. $this->setTypeFeature();
  386. $this->content .= $this->renderList();
  387. }
  388. }
  389. else
  390. {
  391. $url = '<a href="index.php?tab=AdminPerformance&token='.Tools::getAdminTokenLite('AdminPerformance').'#featuresDetachables">'.$this->l('Performance').'</a>';
  392. $this->displayWarning(sprintf($this->l('This feature has been disabled. You can activate it here: %s.'), $url));
  393. }
  394. $this->context->smarty->assign(array(
  395. 'content' => $this->content,
  396. 'url_post' => self::$currentIndex.'&token='.$this->token,
  397. 'show_page_header_toolbar' => $this->show_page_header_toolbar,
  398. 'page_header_toolbar_title' => $this->page_header_toolbar_title,
  399. 'page_header_toolbar_btn' => $this->page_header_toolbar_btn
  400. ));
  401. }
  402. public function initProcess()
  403. {
  404. // Are we working on feature values?
  405. if (Tools::getValue('id_feature_value')
  406. || Tools::isSubmit('deletefeature_value')
  407. || Tools::isSubmit('submitAddfeature_value')
  408. || Tools::isSubmit('addfeature_value')
  409. || Tools::isSubmit('updatefeature_value')
  410. || Tools::isSubmit('submitBulkdeletefeature_value'))
  411. $this->setTypeValue();
  412. if (Tools::getIsset('viewfeature'))
  413. {
  414. $this->list_id = 'feature_value';
  415. if (isset($_POST['submitReset'.$this->list_id]))
  416. $this->processResetFilters();
  417. }
  418. else
  419. {
  420. $this->list_id = 'feature';
  421. $this->_defaultOrderBy = 'position';
  422. $this->_defaultOrderWay = 'ASC';
  423. }
  424. parent::initProcess();
  425. }
  426. public function postProcess()
  427. {
  428. if (!Feature::isFeatureActive())
  429. return;
  430. if ($this->table == 'feature_value' && ($this->action == 'save' || $this->action == 'delete' || $this->action == 'bulkDelete'))
  431. Hook::exec('displayFeatureValuePostProcess',
  432. array('errors' => &$this->errors)); // send errors as reference to allow displayFeatureValuePostProcess to stop saving process
  433. else
  434. Hook::exec('displayFeaturePostProcess',
  435. array('errors' => &$this->errors)); // send errors as reference to allow displayFeaturePostProcess to stop saving process
  436. parent::postProcess();
  437. if ($this->table == 'feature_value' && ($this->display == 'edit' || $this->display == 'add'))
  438. $this->display = 'editFeatureValue';
  439. }
  440. /**
  441. * Override processAdd to change SaveAndStay button action
  442. * @see classes/AdminControllerCore::processAdd()
  443. */
  444. public function processAdd()
  445. {
  446. $object = parent::processAdd();
  447. if (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && !count($this->errors))
  448. {
  449. if( $this->table == 'feature_value' && ($this->display == 'edit' || $this->display == 'add') )
  450. $this->redirect_after = self::$currentIndex.'&addfeature_value&id_feature='.(int)Tools::getValue('id_feature').'&token='.$this->token;
  451. else
  452. $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'=&conf=3&update'.$this->table.'&token='.$this->token;
  453. }
  454. elseif (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && count($this->errors))
  455. $this->display = 'editFeatureValue';
  456. return $object;
  457. }
  458. /**
  459. * Override processUpdate to change SaveAndStay button action
  460. * @see classes/AdminControllerCore::processUpdate()
  461. */
  462. public function processUpdate()
  463. {
  464. $object = parent::processUpdate();
  465. if (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && !count($this->errors))
  466. $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'=&conf=3&update'.$this->table.'&token='.$this->token;
  467. return $object;
  468. }
  469. /**
  470. * Call the right method for creating or updating object
  471. *
  472. * @return mixed
  473. */
  474. public function processSave()
  475. {
  476. if ($this->table == 'feature')
  477. {
  478. $id_feature = (int)Tools::getValue('id_feature');
  479. // Adding last position to the feature if not exist
  480. if ($id_feature <= 0)
  481. {
  482. $sql = 'SELECT `position`+1
  483. FROM `'._DB_PREFIX_.'feature`
  484. ORDER BY position DESC';
  485. // set the position of the new feature in $_POST for postProcess() method
  486. $_POST['position'] = DB::getInstance()->getValue($sql);
  487. }
  488. // clean \n\r characters
  489. foreach ($_POST as $key => $value)
  490. if (preg_match('/^name_/Ui', $key))
  491. $_POST[$key] = str_replace ('\n', '', str_replace('\r', '', $value));
  492. }
  493. return parent::processSave();
  494. }
  495. /**
  496. * AdminController::getList() override
  497. * @see AdminController::getList()
  498. */
  499. public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = false, $id_lang_shop = false)
  500. {
  501. if ($this->table == 'feature_value')
  502. $this->_where .= ' AND (a.custom = 0 OR a.custom IS NULL)';
  503. parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
  504. if ($this->table == 'feature')
  505. {
  506. $nb_items = count($this->_list);
  507. for ($i = 0; $i < $nb_items; ++$i)
  508. {
  509. $item = &$this->_list[$i];
  510. $query = new DbQuery();
  511. $query->select('COUNT(fv.id_feature_value) as count_values');
  512. $query->from('feature_value', 'fv');
  513. $query->where('fv.id_feature ='.(int)$item['id_feature']);
  514. $query->where('(fv.custom=0 OR fv.custom IS NULL)');
  515. $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
  516. $item['value'] = (int)$res;
  517. unset($query);
  518. }
  519. }
  520. }
  521. public function ajaxProcessUpdatePositions()
  522. {
  523. if ($this->tabAccess['edit'] === '1')
  524. {
  525. $way = (int)Tools::getValue('way');
  526. $id_feature = (int)Tools::getValue('id');
  527. $positions = Tools::getValue('feature');
  528. $new_positions = array();
  529. foreach ($positions as $k => $v)
  530. if (!empty($v))
  531. $new_positions[] = $v;
  532. foreach ($new_positions as $position => $value)
  533. {
  534. $pos = explode('_', $value);
  535. if (isset($pos[2]) && (int)$pos[2] === $id_feature)
  536. {
  537. if ($feature = new Feature((int)$pos[2]))
  538. if (isset($position) && $feature->updatePosition($way, $position, $id_feature))
  539. echo 'ok position '.(int)$position.' for feature '.(int)$pos[1].'\r\n';
  540. else
  541. echo '{"hasError" : true, "errors" : "Can not update feature '.(int)$id_feature.' to position '.(int)$position.' "}';
  542. else
  543. echo '{"hasError" : true, "errors" : "This feature ('.(int)$id_feature.') can t be loaded"}';
  544. break;
  545. }
  546. }
  547. }
  548. }
  549. }