Initial commit

This commit is contained in:
2020-10-07 10:37:15 +02:00
commit ce5f440392
28157 changed files with 4429172 additions and 0 deletions

View File

@@ -0,0 +1,235 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Profile $object
*/
class AdminAccessControllerCore extends AdminController
{
/** @var array : Black list of id_tab that do not have access */
public $accesses_black_list = array();
public function __construct()
{
$this->bootstrap = true;
$this->show_toolbar = false;
$this->table = 'access';
$this->className = 'Profile';
$this->multishop_context = Shop::CONTEXT_ALL;
$this->lang = false;
$this->context = Context::getContext();
// Blacklist AdminLogin
$this->accesses_black_list[] = Tab::getIdFromClassName('AdminLogin');
parent::__construct();
}
/**
* AdminController::renderForm() override.
*
* @see AdminController::renderForm()
*/
public function renderForm()
{
$current_profile = (int) $this->getCurrentProfileId();
$profiles = Profile::getProfiles($this->context->language->id);
$tabs = Tab::getTabs($this->context->language->id);
$accesses = array();
foreach ($profiles as $profile) {
$accesses[$profile['id_profile']] = Profile::getProfileAccesses($profile['id_profile']);
}
// Deleted id_tab that do not have access
foreach ($tabs as $key => $tab) {
// Don't allow permissions for unnamed tabs (ie. AdminLogin)
if (empty($tab['name'])) {
unset($tabs[$key]);
}
foreach ($this->accesses_black_list as $id_tab) {
if ($tab['id_tab'] == (int) $id_tab) {
unset($tabs[$key]);
}
}
}
$modules = array();
foreach ($profiles as $profile) {
$modules[$profile['id_profile']] = Module::getModulesAccessesByIdProfile($profile['id_profile']);
uasort($modules[$profile['id_profile']], array($this, 'sortModuleByName'));
}
$this->fields_form = array('');
$this->tpl_form_vars = array(
'profiles' => $profiles,
'accesses' => $accesses,
'id_tab_parentmodule' => (int) Tab::getIdFromClassName('AdminParentModules'),
'id_tab_module' => (int) Tab::getIdFromClassName('AdminModules'),
'tabs' => $this->displayTabs($tabs),
'current_profile' => (int) $current_profile,
'admin_profile' => (int) _PS_ADMIN_PROFILE_,
'access_edit' => $this->access('edit'),
'perms' => array('view', 'add', 'edit', 'delete'),
'id_perms' => array('view' => 0, 'add' => 1, 'edit' => 2, 'delete' => 3, 'all' => 4),
'modules' => $modules,
'link' => $this->context->link,
'employee_profile_id' => (int) $this->context->employee->id_profile,
);
return parent::renderForm();
}
/**
* AdminController::initContent() override.
*
* @see AdminController::initContent()
*/
public function initContent()
{
$this->display = 'edit';
if (!$this->loadObject(true)) {
return;
}
$this->content .= $this->renderForm();
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
public function initToolbarTitle()
{
$this->toolbar_title = array_unique($this->breadcrumbs);
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
unset($this->page_header_toolbar_btn['cancel']);
}
public function ajaxProcessUpdateAccess()
{
if (_PS_MODE_DEMO_) {
throw new PrestaShopException($this->trans('This functionality has been disabled.', array(), 'Admin.Notifications.Error'));
}
if ($this->access('edit') != '1') {
throw new PrestaShopException($this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error'));
}
if (Tools::isSubmit('submitAddAccess')) {
$access = new Access();
$perm = Tools::getValue('perm');
if (!in_array($perm, array('view', 'add', 'edit', 'delete', 'all'))) {
throw new PrestaShopException('permission does not exist');
}
$enabled = (int) Tools::getValue('enabled');
$id_tab = (int) Tools::getValue('id_tab');
$id_profile = (int) Tools::getValue('id_profile');
$addFromParent = (int) Tools::getValue('addFromParent');
die($access->updateLgcAccess((int) $id_profile, $id_tab, $perm, $enabled, $addFromParent));
}
}
public function ajaxProcessUpdateModuleAccess()
{
if (_PS_MODE_DEMO_) {
throw new PrestaShopException($this->trans('This functionality has been disabled.', array(), 'Admin.Notifications.Error'));
}
if ($this->access('edit') != '1') {
throw new PrestaShopException($this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error'));
}
if (Tools::isSubmit('changeModuleAccess')) {
$access = new Access();
$perm = Tools::getValue('perm');
$enabled = (int) Tools::getValue('enabled');
$id_module = (int) Tools::getValue('id_module');
$id_profile = (int) Tools::getValue('id_profile');
if (!in_array($perm, array('view', 'configure', 'uninstall'))) {
throw new PrestaShopException('permission does not exist');
}
die($access->updateLgcModuleAccess((int) $id_profile, $id_module, $perm, $enabled));
}
}
/**
* Get the current profile id.
*
* @return int the $_GET['profile'] if valid, else 1 (the first profile id)
*/
public function getCurrentProfileId()
{
return (isset($_GET['id_profile']) && !empty($_GET['id_profile']) && is_numeric($_GET['id_profile'])) ? (int) $_GET['id_profile'] : 1;
}
/**
* @param array $a module data
* @param array $b module data
*
* @return int
*/
protected function sortModuleByName($a, $b)
{
$moduleAName = isset($a['name']) ? $a['name'] : null;
$moduleBName = isset($b['name']) ? $b['name'] : null;
return strnatcmp($moduleAName, $moduleBName);
}
/**
* return human readable Tabs hierarchy for display.
*/
protected function displayTabs(array $tabs)
{
$tabsTree = $this->getChildrenTab($tabs);
return $tabsTree;
}
protected function getChildrenTab(array &$tabs, $id_parent = 0)
{
$children = [];
foreach ($tabs as &$tab) {
$id = $tab['id_tab'];
if ($tab['id_parent'] == $id_parent) {
$children[$id] = $tab;
$children[$id]['children'] = $this->getChildrenTab($tabs, $id);
}
}
return $children;
}
}

View File

@@ -0,0 +1,571 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Address $object
*/
class AdminAddressesControllerCore extends AdminController
{
/** @var array countries list */
protected $countries_array = array();
public function __construct()
{
$this->bootstrap = true;
$this->required_database = true;
$this->required_fields = array('company', 'address2', 'postcode', 'other', 'phone', 'phone_mobile', 'vat_number', 'dni');
$this->table = 'address';
$this->className = 'CustomerAddress';
$this->lang = false;
$this->addressType = 'customer';
$this->explicitSelect = true;
parent::__construct();
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Notifications.Info'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Info'),
'icon' => 'icon-trash',
),
);
$this->allow_export = true;
if (!Tools::getValue('realedit')) {
$this->deleted = true;
}
$countries = Country::getCountries($this->context->language->id);
foreach ($countries as $country) {
$this->countries_array[$country['id_country']] = $country['name'];
}
$this->fields_list = array(
'id_address' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'firstname' => array(
'title' => $this->trans('First Name', array(), 'Admin.Global'),
'filter_key' => 'a!firstname',
'maxlength' => 30,
),
'lastname' => array(
'title' => $this->trans('Last Name', array(), 'Admin.Global'),
'filter_key' => 'a!lastname',
'maxlength' => 30,
),
'address1' => array(
'title' => $this->trans('Address', array(), 'Admin.Global'),
),
'postcode' => array(
'title' => $this->trans('Zip/postal code', array(), 'Admin.Global'),
'align' => 'right',
),
'city' => array(
'title' => $this->trans('City', array(), 'Admin.Global'),
),
'country' => array(
'title' => $this->trans('Country', array(), 'Admin.Global'),
'type' => 'select',
'list' => $this->countries_array,
'filter_key' => 'cl!id_country',
),
);
$this->_select = 'cl.`name` as country';
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'country_lang` cl ON (cl.`id_country` = a.`id_country` AND cl.`id_lang` = ' . (int) $this->context->language->id . ')
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON a.id_customer = c.id_customer
';
$this->_where = 'AND a.id_customer != 0 ' . Shop::addSqlRestriction(Shop::SHARE_CUSTOMER, 'c');
$this->_use_found_rows = false;
}
public function initToolbar()
{
parent::initToolbar();
if (!$this->display && $this->can_import) {
$this->toolbar_btn['import'] = array(
'href' => $this->context->link->getAdminLink('AdminImport', true, array(), array('import_type' => 'addresses')),
'desc' => $this->trans('Import', array(), 'Admin.Actions'),
);
}
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_address'] = array(
'href' => $this->context->link->getAdminLink('AdminAddresses', true, array(), array('addaddress' => 1)),
'desc' => $this->trans('Add new address', array(), 'Admin.Orderscustomers.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Addresses', array(), 'Admin.Orderscustomers.Feature'),
'icon' => 'icon-envelope-alt',
),
'input' => array(
array(
'type' => 'text_customer',
'label' => $this->trans('Customer', array(), 'Admin.Global'),
'name' => 'id_customer',
'required' => false,
),
array(
'type' => 'text',
'label' => $this->trans('Identification number', array(), 'Admin.Orderscustomers.Feature'),
'name' => 'dni',
'required' => false,
'col' => '4',
'hint' => $this->trans('The national ID card number of this person, or a unique tax identification number.', array(), 'Admin.Orderscustomers.Feature'),
),
array(
'type' => 'text',
'label' => $this->trans('Address alias', array(), 'Admin.Orderscustomers.Feature'),
'name' => 'alias',
'required' => true,
'col' => '4',
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'textarea',
'label' => $this->trans('Other', array(), 'Admin.Global'),
'name' => 'other',
'required' => false,
'cols' => 15,
'rows' => 3,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'hidden',
'name' => 'id_order',
),
array(
'type' => 'hidden',
'name' => 'address_type',
),
array(
'type' => 'hidden',
'name' => 'back',
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
$this->fields_value['address_type'] = (int) Tools::getValue('address_type', 1);
$id_customer = (int) Tools::getValue('id_customer');
if (!$id_customer && Validate::isLoadedObject($this->object)) {
$id_customer = $this->object->id_customer;
}
if ($id_customer) {
$customer = new Customer((int) $id_customer);
}
$this->tpl_form_vars = array(
'customer' => isset($customer) ? $customer : null,
'customer_view_url' => $this->context->link->getAdminLink('AdminCustomers', true, [], [
'viewcustomer' => 1,
'id_customer' => $id_customer,
]),
'back_url' => urldecode(Tools::getValue('back')),
);
// Order address fields depending on country format
$addresses_fields = $this->processAddressFormat();
// we use delivery address
$addresses_fields = $addresses_fields['dlv_all_fields'];
// get required field
$required_fields = AddressFormat::getFieldsRequired();
// Merge with field required
$addresses_fields = array_unique(array_merge($addresses_fields, $required_fields));
$temp_fields = array();
foreach ($addresses_fields as $addr_field_item) {
if ($addr_field_item == 'company') {
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('Company', array(), 'Admin.Global'),
'name' => 'company',
'required' => in_array('company', $required_fields),
'col' => '4',
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
);
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('VAT number', array(), 'Admin.Orderscustomers.Feature'),
'col' => '2',
'name' => 'vat_number',
'required' => in_array('vat_number', $required_fields),
);
} elseif ($addr_field_item == 'lastname') {
if (isset($customer) &&
!Tools::isSubmit('submit' . strtoupper($this->table)) &&
Validate::isLoadedObject($customer) &&
!Validate::isLoadedObject($this->object)) {
$default_value = $customer->lastname;
} else {
$default_value = '';
}
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('Last Name', array(), 'Admin.Global'),
'name' => 'lastname',
'required' => true,
'col' => '4',
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' 0-9!&amp;lt;&amp;gt;,;?=+()@#"<22>{}_$%:',
'default_value' => $default_value,
);
} elseif ($addr_field_item == 'firstname') {
if (isset($customer) &&
!Tools::isSubmit('submit' . strtoupper($this->table)) &&
Validate::isLoadedObject($customer) &&
!Validate::isLoadedObject($this->object)) {
$default_value = $customer->firstname;
} else {
$default_value = '';
}
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('First Name', array(), 'Admin.Global'),
'name' => 'firstname',
'required' => true,
'col' => '4',
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' 0-9!&amp;lt;&amp;gt;,;?=+()@#"<22>{}_$%:',
'default_value' => $default_value,
);
} elseif ($addr_field_item == 'address1') {
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('Address', array(), 'Admin.Global'),
'name' => 'address1',
'col' => '6',
'required' => true,
);
} elseif ($addr_field_item == 'address2') {
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('Address', array(), 'Admin.Global') . ' (2)',
'name' => 'address2',
'col' => '6',
'required' => in_array('address2', $required_fields),
);
} elseif ($addr_field_item == 'postcode') {
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('Zip/postal code', array(), 'Admin.Global'),
'name' => 'postcode',
'col' => '2',
'required' => true,
);
} elseif ($addr_field_item == 'city') {
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('City', array(), 'Admin.Global'),
'name' => 'city',
'col' => '4',
'required' => true,
);
} elseif ($addr_field_item == 'country' || $addr_field_item == 'Country:name') {
$temp_fields[] = array(
'type' => 'select',
'label' => $this->trans('Country', array(), 'Admin.Global'),
'name' => 'id_country',
'required' => in_array('Country:name', $required_fields) || in_array('country', $required_fields),
'col' => '4',
'default_value' => (int) $this->context->country->id,
'options' => array(
'query' => Country::getCountries($this->context->language->id),
'id' => 'id_country',
'name' => 'name',
),
);
$temp_fields[] = array(
'type' => 'select',
'label' => $this->trans('State', array(), 'Admin.Global'),
'name' => 'id_state',
'required' => false,
'col' => '4',
'options' => array(
'query' => array(),
'id' => 'id_state',
'name' => 'name',
),
);
} elseif ($addr_field_item == 'phone') {
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('Home phone', array(), 'Admin.Global'),
'name' => 'phone',
'required' => in_array('phone', $required_fields),
'col' => '4',
);
} elseif ($addr_field_item == 'phone_mobile') {
$temp_fields[] = array(
'type' => 'text',
'label' => $this->trans('Mobile phone', array(), 'Admin.Global'),
'name' => 'phone_mobile',
'required' => in_array('phone_mobile', $required_fields),
'col' => '4',
);
}
}
// merge address format with the rest of the form
array_splice($this->fields_form['input'], 3, 0, $temp_fields);
return parent::renderForm();
}
public function processSave()
{
if (Tools::getValue('submitFormAjax')) {
$this->redirect_after = false;
}
// Transform e-mail in id_customer for parent processing
if (Validate::isEmail(Tools::getValue('email'))) {
$customer = new Customer();
$customer->getByEmail(Tools::getValue('email'), null, false);
if (Validate::isLoadedObject($customer)) {
$_POST['id_customer'] = $customer->id;
} else {
$this->errors[] = $this->trans('This email address is not registered.', array(), 'Admin.Orderscustomers.Notification');
}
} elseif ($id_customer = Tools::getValue('id_customer')) {
$customer = new Customer((int) $id_customer);
if (Validate::isLoadedObject($customer)) {
$_POST['id_customer'] = $customer->id;
} else {
$this->errors[] = $this->trans('This customer ID is not recognized.', array(), 'Admin.Orderscustomers.Notification');
}
} else {
$this->errors[] = $this->trans('This email address is not valid. Please use an address like bob@example.com.', array(), 'Admin.Orderscustomers.Notification');
}
if (Country::isNeedDniByCountryId(Tools::getValue('id_country')) && !Tools::getValue('dni')) {
$this->errors[] = $this->trans('The identification number is incorrect or has already been used.', array(), 'Admin.Orderscustomers.Notification');
}
/* If the selected country does not contain states */
$id_state = (int) Tools::getValue('id_state');
$id_country = (int) Tools::getValue('id_country');
$country = new Country((int) $id_country);
if ($country && !(int) $country->contains_states && $id_state) {
$this->errors[] = $this->trans('You have selected a state for a country that does not contain states.', array(), 'Admin.Orderscustomers.Notification');
}
/* If the selected country contains states, then a state have to be selected */
if ((int) $country->contains_states && !$id_state) {
$this->errors[] = $this->trans('An address located in a country containing states must have a state selected.', array(), 'Admin.Orderscustomers.Notification');
}
$postcode = Tools::getValue('postcode');
/* Check zip code format */
if ($country->zip_code_format && !$country->checkZipCode($postcode)) {
$this->errors[] = $this->trans('Your Zip/postal code is incorrect.', array(), 'Admin.Notifications.Error') . '<br />' . $this->trans('It must be entered as follows:', array(), 'Admin.Notifications.Error') . ' ' . str_replace('C', $country->iso_code, str_replace('N', '0', str_replace('L', 'A', $country->zip_code_format)));
} elseif (empty($postcode) && $country->need_zip_code) {
$this->errors[] = $this->trans('A Zip/postal code is required.', array(), 'Admin.Notifications.Error');
} elseif ($postcode && !Validate::isPostCode($postcode)) {
$this->errors[] = $this->trans('The Zip/postal code is invalid.', array(), 'Admin.Notifications.Error');
}
/* If this address come from order's edition and is the same as the other one (invoice or delivery one)
** we delete its id_address to force the creation of a new one */
if ((int) Tools::getValue('id_order')) {
$this->_redirect = false;
if (isset($_POST['address_type'])) {
$_POST['id_address'] = '';
$this->id_object = null;
}
}
// Check the requires fields which are settings in the BO
$address = new Address();
$this->errors = array_merge($this->errors, $address->validateFieldsRequiredDatabase());
$return = false;
if (empty($this->errors)) {
$return = parent::processSave();
} else {
// if we have errors, we stay on the form instead of going back to the list
$this->display = 'edit';
}
/* Reassignation of the order's new (invoice or delivery) address */
$address_type = (int) Tools::getValue('address_type') == 2 ? 'invoice' : 'delivery';
if ($this->action == 'save' && ($id_order = (int) Tools::getValue('id_order')) && !count($this->errors) && !empty($address_type)) {
if (!Db::getInstance()->execute('UPDATE ' . _DB_PREFIX_ . 'orders SET `id_address_' . bqSQL($address_type) . '` = ' . (int) $this->object->id . ' WHERE `id_order` = ' . (int) $id_order)) {
$this->errors[] = $this->trans('An error occurred while linking this address to its order.', array(), 'Admin.Orderscustomers.Notification');
} else {
//update order shipping cost
$order = new Order($id_order);
$order->refreshShippingCost();
// update cart
$cart = Cart::getCartByOrderId($id_order);
if (Validate::isLoadedObject($cart)) {
if ($address_type == 'invoice') {
$cart->id_address_invoice = (int) $this->object->id;
} else {
$cart->id_address_delivery = (int) $this->object->id;
}
$cart->update();
}
// redirect
Tools::redirectAdmin(urldecode(Tools::getValue('back')) . '&conf=4');
}
}
return $return;
}
public function processAdd()
{
if (Tools::getValue('submitFormAjax')) {
$this->redirect_after = false;
}
return parent::processAdd();
}
/**
* Get Address formats used by the country where the address id retrieved from POST/GET is.
*
* @return array address formats
*/
protected function processAddressFormat()
{
$tmp_addr = new CustomerAddress((int) Tools::getValue('id_address'));
$selected_country = ($tmp_addr && $tmp_addr->id_country) ? $tmp_addr->id_country : (int) Configuration::get('PS_COUNTRY_DEFAULT');
$adr_fields = AddressFormat::getOrderedAddressFields($selected_country, false, true);
$all_fields = array();
$out = array();
foreach ($adr_fields as $fields_line) {
foreach (explode(' ', $fields_line) as $field_item) {
$all_fields[] = trim($field_item);
}
}
foreach (array('inv', 'dlv') as $adr_type) {
$out[$adr_type . '_adr_fields'] = $adr_fields;
$out[$adr_type . '_all_fields'] = $all_fields;
}
return $out;
}
/**
* Method called when an ajax request is made.
*
* @see AdminController::postProcess()
*/
public function ajaxProcess()
{
if (Tools::isSubmit('email')) {
$email = pSQL(Tools::getValue('email'));
$customer = Customer::searchByName($email);
if (!empty($customer)) {
$customer = $customer['0'];
echo json_encode(array('infos' => pSQL($customer['firstname']) . '_' . pSQL($customer['lastname']) . '_' . pSQL($customer['company'])));
}
}
if (Tools::isSubmit('dni_required')) {
echo json_encode(['dni_required' => Address::dniRequired((int) Tools::getValue('id_country'))]);
}
die;
}
/**
* Object Delete.
*/
public function processDelete()
{
if (Validate::isLoadedObject($object = $this->loadObject())) {
/** @var Address $object */
if (!$object->isUsed()) {
$this->deleted = false;
}
}
$res = parent::processDelete();
if ($back = Tools::getValue('back')) {
$this->redirect_after = urldecode($back) . '&conf=1';
}
return $res;
}
/**
* Delete multiple items.
*
* @return bool true if succcess
*/
protected function processBulkDelete()
{
if (is_array($this->boxes) && !empty($this->boxes)) {
$deleted = false;
foreach ($this->boxes as $id) {
$to_delete = new Address((int) $id);
if ($to_delete->isUsed()) {
$deleted = true;
break;
}
}
$this->deleted = $deleted;
}
return parent::processBulkDelete();
}
}

View File

@@ -0,0 +1,264 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Attachment $object
*/
class AdminAttachmentsControllerCore extends AdminController
{
public $bootstrap = true;
protected $product_attachements = array();
public function __construct()
{
$this->table = 'attachment';
$this->className = 'Attachment';
$this->lang = true;
$this->addRowAction('edit');
$this->addRowAction('view');
$this->addRowAction('delete');
$this->_select = 'IFNULL(virtual_product_attachment.products, 0) as products';
$this->_join = 'LEFT JOIN (SELECT id_attachment, COUNT(*) as products FROM ' . _DB_PREFIX_ . 'product_attachment GROUP BY id_attachment) virtual_product_attachment ON a.id_attachment = virtual_product_attachment.id_attachment';
$this->_use_found_rows = false;
parent::__construct();
$this->fields_list = array(
'id_attachment' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
),
'file' => array(
'title' => $this->trans('File', array(), 'Admin.Global'),
'orderby' => false,
'search' => false,
),
'file_size' => array(
'title' => $this->trans('Size', array(), 'Admin.Global'),
'callback' => 'displayHumanReadableSize',
),
'products' => array(
'title' => $this->trans('Associated with', array(), 'Admin.Catalog.Feature'),
'suffix' => $this->trans('product(s)', array(), 'Admin.Catalog.Feature'),
'filter_key' => 'virtual_product_attachment!products',
),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Notifications.Info'),
'icon' => 'icon-trash',
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Info'),
),
);
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJs(_PS_JS_DIR_ . '/admin/attachments.js');
Media::addJsDefL('confirm_text', $this->trans('This file is associated with the following products, do you really want to delete it?', array(), 'Admin.Catalog.Notification'));
}
public static function displayHumanReadableSize($size)
{
return Tools::formatBytes($size);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_attachment'] = array(
'href' => self::$currentIndex . '&addattachment&token=' . $this->token,
'desc' => $this->trans('Add new file', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderView()
{
if (($obj = $this->loadObject(true)) && Validate::isLoadedObject($obj)) {
$link = $this->context->link->getPageLink('attachment', true, null, 'id_attachment=' . $obj->id);
Tools::redirectLink($link);
}
return $this->displayWarning($this->trans('File not found', array(), 'Admin.Catalog.Notification'));
}
public function renderForm()
{
if (($obj = $this->loadObject(true)) && Validate::isLoadedObject($obj)) {
/** @var Attachment $obj */
$link = $this->context->link->getPageLink('attachment', true, null, 'id_attachment=' . $obj->id);
if (file_exists(_PS_DOWNLOAD_DIR_ . $obj->file)) {
$size = round(filesize(_PS_DOWNLOAD_DIR_ . $obj->file) / 1024);
}
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Add new file', array(), 'Admin.Catalog.Feature'),
'icon' => 'icon-paper-clip',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Filename', array(), 'Admin.Global'),
'name' => 'name',
'required' => true,
'lang' => true,
'col' => 4,
),
array(
'type' => 'textarea',
'label' => $this->trans('Description', array(), 'Admin.Global'),
'name' => 'description',
'lang' => true,
'col' => 6,
),
array(
'type' => 'file',
'file' => isset($link) ? $link : null,
'size' => isset($size) ? $size : null,
'label' => $this->trans('File', array(), 'Admin.Global'),
'name' => 'file',
'required' => true,
'col' => 6,
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
return parent::renderForm();
}
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
parent::getList((int) $id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
if (count($this->_list)) {
$this->product_attachements = Attachment::getProductAttached((int) $id_lang, $this->_list);
$list_product_list = array();
foreach ($this->_list as $list) {
$product_list = '';
if (isset($this->product_attachements[$list['id_attachment']])) {
foreach ($this->product_attachements[$list['id_attachment']] as $product) {
$product_list .= $product . ', ';
}
$product_list = rtrim($product_list, ', ');
}
$list_product_list[$list['id_attachment']] = $product_list;
}
// Assign array in list_action_delete.tpl
$this->tpl_delete_link_vars = array(
'product_list' => $list_product_list,
'product_attachements' => $this->product_attachements,
);
}
}
public function postProcess()
{
if (_PS_MODE_DEMO_) {
$this->errors[] = $this->trans('This functionality has been disabled.', array(), 'Admin.Notifications.Error');
return;
}
if (Tools::isSubmit('submitAdd' . $this->table)) {
$id = (int) Tools::getValue('id_attachment');
if ($id && $a = new Attachment($id)) {
$_POST['file'] = $a->file;
$_POST['mime'] = $a->mime;
}
if (!count($this->errors)) {
if (isset($_FILES['file']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
if ($_FILES['file']['size'] > (Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024 * 1024)) {
$this->errors[] = $this->trans(
'The file is too large. Maximum size allowed is: %1$d kB. The file you are trying to upload is %2$d kB.',
array(
'%1$d' => (Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024),
'%2$d' => number_format(($_FILES['file']['size'] / 1024), 2, '.', ''),
),
'Admin.Notifications.Error'
);
} else {
do {
$uniqid = sha1(microtime());
} while (file_exists(_PS_DOWNLOAD_DIR_ . $uniqid));
if (!move_uploaded_file($_FILES['file']['tmp_name'], _PS_DOWNLOAD_DIR_ . $uniqid)) {
$this->errors[] = $this->trans('Failed to copy the file.', array(), 'Admin.Catalog.Notification');
}
$_POST['file_name'] = $_FILES['file']['name'];
@unlink($_FILES['file']['tmp_name']);
if (!count($this->errors) && isset($a) && file_exists(_PS_DOWNLOAD_DIR_ . $a->file)) {
unlink(_PS_DOWNLOAD_DIR_ . $a->file);
}
$_POST['file'] = $uniqid;
$_POST['mime'] = $_FILES['file']['type'];
}
} elseif (array_key_exists('file', $_FILES) && (int) $_FILES['file']['error'] === 1) {
$max_upload = (int) ini_get('upload_max_filesize');
$max_post = (int) ini_get('post_max_size');
$upload_mb = min($max_upload, $max_post);
$this->errors[] = $this->trans(
'The file %file% exceeds the size allowed by the server. The limit is set to %size% MB.',
array('%file%' => '<b>' . $_FILES['file']['name'] . '</b> ', '%size%' => '<b>' . $upload_mb . '</b>'),
'Admin.Catalog.Notification'
);
} elseif (!isset($a) || (isset($a) && !file_exists(_PS_DOWNLOAD_DIR_ . $a->file))) {
$this->errors[] = $this->trans('Upload error. Please check your server configurations for the maximum upload size allowed.', array(), 'Admin.Catalog.Notification');
}
}
$this->validateRules();
}
$return = parent::postProcess();
if (!$return && isset($uniqid) && file_exists(_PS_DOWNLOAD_DIR_ . $uniqid)) {
unlink(_PS_DOWNLOAD_DIR_ . $uniqid);
}
return $return;
}
}

View File

@@ -0,0 +1,273 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
@ini_set('max_execution_time', 3600);
/**
* @property Product $object
*/
class AdminAttributeGeneratorControllerCore extends AdminController
{
protected $combinations = array();
/** @var Product */
protected $product;
public function __construct()
{
$this->bootstrap = true;
$this->table = 'product_attribute';
$this->className = 'Product';
$this->multishop_context_group = false;
parent::__construct();
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJS(_PS_JS_DIR_ . 'admin/attributes.js');
}
protected function addAttribute($attributes, $price = 0, $weight = 0)
{
foreach ($attributes as $attribute) {
$price += (float) preg_replace('/[^0-9.-]/', '', str_replace(',', '.', Tools::getValue('price_impact_' . (int) $attribute)));
$weight += (float) preg_replace('/[^0-9.]/', '', str_replace(',', '.', Tools::getValue('weight_impact_' . (int) $attribute)));
}
if ($this->product->id) {
return array(
'id_product' => (int) $this->product->id,
'price' => (float) $price,
'weight' => (float) $weight,
'ecotax' => 0,
'quantity' => (int) Tools::getValue('quantity'),
'reference' => pSQL($_POST['reference']),
'default_on' => 0,
'available_date' => '0000-00-00',
);
}
return array();
}
public static function createCombinations($list)
{
if (count($list) <= 1) {
return count($list) ? array_map(function ($v) { return array($v); }, $list[0]) : $list;
}
$res = array();
$first = array_pop($list);
foreach ($first as $attribute) {
$tab = AdminAttributeGeneratorController::createCombinations($list);
foreach ($tab as $to_add) {
$res[] = is_array($to_add) ? array_merge($to_add, array($attribute)) : array($to_add, $attribute);
}
}
return $res;
}
public function initProcess()
{
if (!defined('PS_MASS_PRODUCT_CREATION')) {
define('PS_MASS_PRODUCT_CREATION', true);
}
if (Tools::isSubmit('generate')) {
if ($this->access('edit')) {
$this->action = 'generate';
} else {
$this->errors[] = $this->trans('You do not have permission to add this.', array(), 'Admin.Notifications.Error');
}
}
parent::initProcess();
}
public function postProcess()
{
$this->product = new Product((int) Tools::getValue('id_product'));
$this->product->loadStockData();
parent::postProcess();
}
public function processGenerate()
{
if (!is_array(Tools::getValue('options'))) {
$this->errors[] = $this->trans('Please select at least one attribute.', array(), 'Admin.Catalog.Notification');
} else {
$tab = array_values(Tools::getValue('options'));
if (count($tab) && Validate::isLoadedObject($this->product)) {
AdminAttributeGeneratorController::setAttributesImpacts($this->product->id, $tab);
$this->combinations = array_values(AdminAttributeGeneratorController::createCombinations($tab));
$values = array_values(array_map(array($this, 'addAttribute'), $this->combinations));
// @since 1.5.0
if ($this->product->depends_on_stock == 0) {
$attributes = Product::getProductAttributesIds($this->product->id, true);
foreach ($attributes as $attribute) {
StockAvailable::removeProductFromStockAvailable($this->product->id, $attribute['id_product_attribute'], Context::getContext()->shop);
}
}
SpecificPriceRule::disableAnyApplication();
$this->product->deleteProductAttributes();
$this->product->generateMultipleCombinations($values, $this->combinations);
// Reset cached default attribute for the product and get a new one
Product::getDefaultAttribute($this->product->id, 0, true);
Product::updateDefaultAttribute($this->product->id);
// @since 1.5.0
if ($this->product->depends_on_stock == 0) {
$attributes = Product::getProductAttributesIds($this->product->id, true);
$quantity = (int) Tools::getValue('quantity');
foreach ($attributes as $attribute) {
if (Shop::getContext() == Shop::CONTEXT_ALL) {
$shops_list = Shop::getShops();
if (is_array($shops_list)) {
foreach ($shops_list as $current_shop) {
if (isset($current_shop['id_shop']) && (int) $current_shop['id_shop'] > 0) {
StockAvailable::setQuantity($this->product->id, (int) $attribute['id_product_attribute'], $quantity, (int) $current_shop['id_shop']);
}
}
}
} else {
StockAvailable::setQuantity($this->product->id, (int) $attribute['id_product_attribute'], $quantity);
}
}
} else {
StockAvailable::synchronize($this->product->id);
}
SpecificPriceRule::enableAnyApplication();
SpecificPriceRule::applyAllRules(array((int) $this->product->id));
Tools::redirectAdmin($this->context->link->getAdminLink('AdminProducts') . '&id_product=' . (int) Tools::getValue('id_product') . '&updateproduct&key_tab=Combinations&conf=4');
} else {
$this->errors[] = $this->trans('Unable to initialize these parameters. A combination is missing or an object cannot be loaded.', array(), 'Admin.Catalog.Notification');
}
}
}
protected static function setAttributesImpacts($id_product, $tab)
{
$attributes = array();
foreach ($tab as $group) {
foreach ($group as $attribute) {
$price = preg_replace('/[^0-9.]/', '', str_replace(',', '.', Tools::getValue('price_impact_' . (int) $attribute)));
$weight = preg_replace('/[^0-9.]/', '', str_replace(',', '.', Tools::getValue('weight_impact_' . (int) $attribute)));
$attributes[] = '(' . (int) $id_product . ', ' . (int) $attribute . ', ' . (float) $price . ', ' . (float) $weight . ')';
}
}
return Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'attribute_impact` (`id_product`, `id_attribute`, `price`, `weight`)
VALUES ' . implode(',', $attributes) . '
ON DUPLICATE KEY UPDATE `price` = VALUES(price), `weight` = VALUES(weight)');
}
public function initGroupTable()
{
$combinations_groups = $this->product->getAttributesGroups($this->context->language->id);
$attributes = array();
$impacts = Product::getAttributesImpacts($this->product->id);
foreach ($combinations_groups as &$combination) {
$target = &$attributes[$combination['id_attribute_group']][$combination['id_attribute']];
$target = $combination;
if (isset($impacts[$combination['id_attribute']])) {
$target['price'] = $impacts[$combination['id_attribute']]['price'];
$target['weight'] = $impacts[$combination['id_attribute']]['weight'];
}
}
$this->context->smarty->assign(array(
'currency_sign' => $this->context->currency->sign,
'weight_unit' => Configuration::get('PS_WEIGHT_UNIT'),
'attributes' => $attributes,
));
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
$this->page_header_toolbar_title = $this->trans('Attributes generator', array(), 'Admin.Catalog.Feature');
$this->page_header_toolbar_btn['back'] = array(
'href' => $this->context->link->getAdminLink('AdminProducts') . '&id_product=' . (int) Tools::getValue('id_product') . '&updateproduct&key_tab=Combinations',
'desc' => $this->trans('Back to the product', array(), 'Admin.Catalog.Feature'),
);
}
public function initBreadcrumbs($tab_id = null, $tabs = null)
{
$this->display = 'generator';
return parent::initBreadcrumbs();
}
public function initContent()
{
if (!Combination::isFeatureActive()) {
$adminPerformanceUrl = $this->context->link->getAdminLink('AdminPerformance');
$url = '<a href="' . $adminPerformanceUrl . '#featuresDetachables">' .
$this->trans('Performance', array(), 'Admin.Global') . '</a>';
$this->displayWarning($this->trans('This feature has been disabled. You can activate it here: %link%.', array('%link%' => $url), 'Admin.Catalog.Notification'));
return;
}
// Init toolbar
$this->initPageHeaderToolbar();
$this->initGroupTable();
$attributes = Attribute::getAttributes(Context::getContext()->language->id, true);
$attribute_js = array();
foreach ($attributes as $k => $attribute) {
$attribute_js[$attribute['id_attribute_group']][$attribute['id_attribute']] = $attribute['name'];
}
$attribute_groups = AttributeGroup::getAttributesGroups($this->context->language->id);
$this->product = new Product((int) Tools::getValue('id_product'));
$this->context->smarty->assign(array(
'tax_rates' => $this->product->getTaxesRate(),
'generate' => isset($_POST['generate']) && !count($this->errors),
'combinations_size' => count($this->combinations),
'product_name' => $this->product->name[$this->context->language->id],
'product_reference' => $this->product->reference,
'url_generator' => self::$currentIndex . '&id_product=' . (int) Tools::getValue('id_product') . '&attributegenerator&token=' . Tools::getValue('token'),
'attribute_groups' => $attribute_groups,
'attribute_js' => $attribute_js,
'toolbar_btn' => $this->toolbar_btn,
'toolbar_scroll' => true,
'show_page_header_toolbar' => $this->show_page_header_toolbar,
'page_header_toolbar_title' => $this->page_header_toolbar_title,
'page_header_toolbar_btn' => $this->page_header_toolbar_btn,
));
}
}

View File

@@ -0,0 +1,974 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property AttributeGroup $object
*/
class AdminAttributesGroupsControllerCore extends AdminController
{
public $bootstrap = true;
protected $id_attribute;
protected $position_identifier = 'id_attribute_group';
protected $attribute_name;
public function __construct()
{
$this->bootstrap = true;
$this->table = 'attribute_group';
$this->list_id = 'attribute_group';
$this->identifier = 'id_attribute_group';
$this->className = 'AttributeGroup';
$this->lang = true;
$this->_defaultOrderBy = 'position';
parent::__construct();
$this->fields_list = array(
'id_attribute_group' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'filter_key' => 'b!name',
'align' => 'left',
),
'count_values' => array(
'title' => $this->trans('Values', array(), 'Admin.Catalog.Feature'),
'align' => 'center',
'class' => 'fixed-width-xs',
'orderby' => false,
'search' => false,
),
'position' => array(
'title' => $this->trans('Position', array(), 'Admin.Global'),
'filter_key' => 'a!position',
'position' => 'position',
'align' => 'center',
'class' => 'fixed-width-xs',
),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Notifications.Info'),
'icon' => 'icon-trash',
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Info'),
),
);
$this->fieldImageSettings = array('name' => 'texture', 'dir' => 'co');
$this->image_dir = 'co';
}
/**
* AdminController::renderList() override.
*
* @see AdminController::renderList()
*/
public function renderList()
{
$this->addRowAction('view');
$this->addRowAction('edit');
$this->addRowAction('delete');
return parent::renderList();
}
public function renderView()
{
if (($id = (int) Tools::getValue('id_attribute_group'))) {
$this->table = 'attribute';
$this->className = 'Attribute';
$this->identifier = 'id_attribute';
$this->position_identifier = 'id_attribute';
$this->position_group_identifier = 'id_attribute_group';
$this->list_id = 'attribute_values';
$this->lang = true;
$this->context->smarty->assign(array(
'current' => self::$currentIndex . '&id_attribute_group=' . (int) $id . '&viewattribute_group',
));
if (!Validate::isLoadedObject($obj = new AttributeGroup((int) $id))) {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Catalog.Notification') .
' <b>' . $this->table . '</b> ' .
$this->trans('(cannot load object)', array(), 'Admin.Catalog.Notification');
return;
}
$this->attribute_name = $obj->name;
$this->fields_list = array(
'id_attribute' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Value', array(), 'Admin.Catalog.Feature'),
'width' => 'auto',
'filter_key' => 'b!name',
),
);
if ($obj->group_type == 'color') {
$this->fields_list['color'] = array(
'title' => $this->trans('Color', array(), 'Admin.Catalog.Feature'),
'filter_key' => 'a!color',
);
}
$this->fields_list['position'] = array(
'title' => $this->trans('Position', array(), 'Admin.Global'),
'filter_key' => 'a!position',
'position' => 'position',
'class' => 'fixed-width-md',
);
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_where = 'AND a.`id_attribute_group` = ' . (int) $id;
$this->_orderBy = 'position';
self::$currentIndex = self::$currentIndex . '&id_attribute_group=' . (int) $id . '&viewattribute_group';
$this->processFilter();
return parent::renderList();
}
}
/**
* AdminController::renderForm() override.
*
* @see AdminController::renderForm()
*/
public function renderForm()
{
$this->table = 'attribute_group';
$this->identifier = 'id_attribute_group';
$group_type = array(
array(
'id' => 'select',
'name' => $this->trans('Drop-down list', array(), 'Admin.Global'),
),
array(
'id' => 'radio',
'name' => $this->trans('Radio buttons', array(), 'Admin.Global'),
),
array(
'id' => 'color',
'name' => $this->trans('Color or texture', array(), 'Admin.Catalog.Feature'),
),
);
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Attributes', array(), 'Admin.Catalog.Feature'),
'icon' => 'icon-info-sign',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'required' => true,
'col' => '4',
'hint' => $this->trans('Your internal name for this attribute.', array(), 'Admin.Catalog.Help') . '&nbsp;' . $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' <>;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Public name', array(), 'Admin.Catalog.Feature'),
'name' => 'public_name',
'lang' => true,
'required' => true,
'col' => '4',
'hint' => $this->trans('The public name for this attribute, displayed to the customers.', array(), 'Admin.Catalog.Help') . '&nbsp;' . $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' <>;=#{}',
),
array(
'type' => 'select',
'label' => $this->trans('Attribute type', array(), 'Admin.Catalog.Feature'),
'name' => 'group_type',
'required' => true,
'options' => array(
'query' => $group_type,
'id' => 'id',
'name' => 'name',
),
'col' => '2',
'hint' => $this->trans('The way the attribute\'s values will be presented to the customers in the product\'s page.', array(), 'Admin.Catalog.Help'),
),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$this->fields_form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
if (!($obj = $this->loadObject(true))) {
return;
}
return parent::renderForm();
}
public function renderFormAttributes()
{
$attributes_groups = AttributeGroup::getAttributesGroups($this->context->language->id);
$this->table = 'attribute';
$this->identifier = 'id_attribute';
$this->show_form_cancel_button = true;
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Values', array(), 'Admin.Global'),
'icon' => 'icon-info-sign',
),
'input' => array(
array(
'type' => 'select',
'label' => $this->trans('Attribute group', array(), 'Admin.Catalog.Feature'),
'name' => 'id_attribute_group',
'required' => true,
'options' => array(
'query' => $attributes_groups,
'id' => 'id_attribute_group',
'name' => 'name',
),
'hint' => $this->trans('Choose the attribute group for this value.', array(), 'Admin.Catalog.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Value', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'required' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' <>;=#{}',
),
),
);
if (Shop::isFeatureActive()) {
// We get all associated shops for all attribute groups, because we will disable group shops
// for attributes that the selected attribute group don't support
$sql = 'SELECT id_attribute_group, id_shop FROM ' . _DB_PREFIX_ . 'attribute_group_shop';
$associations = array();
foreach (Db::getInstance()->executeS($sql) as $row) {
$associations[$row['id_attribute_group']][] = $row['id_shop'];
}
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
'values' => Shop::getTree(),
);
} else {
$associations = array();
}
$this->fields_form['shop_associations'] = json_encode($associations);
$this->fields_form['input'][] = array(
'type' => 'color',
'label' => $this->trans('Color', array(), 'Admin.Catalog.Feature'),
'name' => 'color',
'hint' => $this->trans('Choose a color with the color picker, or enter an HTML color (e.g. "lightblue", "#CC6600").', array(), 'Admin.Catalog.Help'),
);
$this->fields_form['input'][] = array(
'type' => 'file',
'label' => $this->trans('Texture', array(), 'Admin.Catalog.Feature'),
'name' => 'texture',
'hint' => array(
$this->trans('Upload an image file containing the color texture from your computer.', array(), 'Admin.Catalog.Help'),
$this->trans('This will override the HTML color!', array(), 'Admin.Catalog.Help'),
),
);
$this->fields_form['input'][] = array(
'type' => 'current_texture',
'label' => $this->trans('Current texture', array(), 'Admin.Catalog.Feature'),
'name' => 'current_texture',
);
$this->fields_form['input'][] = array(
'type' => 'closediv',
'name' => '',
);
$this->fields_form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
$this->fields_form['buttons'] = array(
'save-and-stay' => array(
'title' => $this->trans('Save then add another value', array(), 'Admin.Catalog.Feature'),
'name' => 'submitAdd' . $this->table . 'AndStay',
'type' => 'submit',
'class' => 'btn btn-default pull-right',
'icon' => 'process-icon-save',
),
);
$this->fields_value['id_attribute_group'] = (int) Tools::getValue('id_attribute_group');
// Override var of Controller
$this->table = 'attribute';
$this->className = 'Attribute';
$this->identifier = 'id_attribute';
$this->lang = true;
$this->tpl_folder = 'attributes/';
// Create object Attribute
if (!$obj = new Attribute((int) Tools::getValue($this->identifier))) {
return;
}
$str_attributes_groups = '';
foreach ($attributes_groups as $attribute_group) {
$str_attributes_groups .= '"' . $attribute_group['id_attribute_group'] . '" : ' . ($attribute_group['group_type'] == 'color' ? '1' : '0') . ', ';
}
$image = '../img/' . $this->fieldImageSettings['dir'] . '/' . (int) $obj->id . '.jpg';
$this->tpl_form_vars = array(
'strAttributesGroups' => $str_attributes_groups,
'colorAttributeProperties' => Validate::isLoadedObject($obj) && $obj->isColorAttribute(),
'imageTextureExists' => file_exists(_PS_IMG_DIR_ . $this->fieldImageSettings['dir'] . '/' . (int) $obj->id . '.jpg'),
'imageTexture' => $image,
'imageTextureUrl' => Tools::safeOutput($_SERVER['REQUEST_URI']) . '&deleteImage=1',
);
return parent::renderForm();
}
/**
* AdminController::init() override.
*
* @see AdminController::init()
*/
public function init()
{
if (Tools::isSubmit('updateattribute')) {
$this->display = 'editAttributes';
} elseif (Tools::isSubmit('submitAddattribute')) {
$this->display = 'editAttributes';
} elseif (Tools::isSubmit('submitAddattribute_group')) {
$this->display = 'add';
}
parent::init();
}
/**
* Override processAdd to change SaveAndStay button action.
*
* @see classes/AdminControllerCore::processUpdate()
*/
public function processAdd()
{
if ($this->table == 'attribute') {
/** @var AttributeGroup $object */
$object = new $this->className();
foreach (Language::getLanguages(false) as $language) {
if ($object->isAttribute(
(int) Tools::getValue('id_attribute_group'),
Tools::getValue('name_' . $language['id_lang']),
$language['id_lang']
)) {
$this->errors['name_' . $language['id_lang']] = $this->trans(
'The attribute value "%1$s" already exist for %2$s language',
array(
Tools::getValue('name_' . $language['id_lang']),
$language['name'],
),
'Admin.Catalog.Notification'
);
}
}
if (!empty($this->errors)) {
return $object;
}
}
$object = parent::processAdd();
if (Tools::isSubmit('submitAdd' . $this->table . 'AndStay') && !count($this->errors)) {
if ($this->display == 'add') {
$this->redirect_after = self::$currentIndex . '&' . $this->identifier . '=&conf=3&update' . $this->table . '&token=' . $this->token;
} else {
$this->redirect_after = self::$currentIndex . '&id_attribute_group=' . (int) Tools::getValue('id_attribute_group') . '&conf=3&update' . $this->table . '&token=' . $this->token;
}
}
if (count($this->errors)) {
$this->setTypeAttribute();
}
return $object;
}
/**
* Override processUpdate to change SaveAndStay button action.
*
* @see classes/AdminControllerCore::processUpdate()
*/
public function processUpdate()
{
$object = parent::processUpdate();
if (Tools::isSubmit('submitAdd' . $this->table . 'AndStay') && !count($this->errors)) {
if ($this->display == 'add') {
$this->redirect_after = self::$currentIndex . '&' . $this->identifier . '=&conf=3&update' . $this->table . '&token=' . $this->token;
} else {
$this->redirect_after = self::$currentIndex . '&' . $this->identifier . '=&id_attribute_group=' . (int) Tools::getValue('id_attribute_group') . '&conf=3&update' . $this->table . '&token=' . $this->token;
}
}
if (count($this->errors)) {
$this->setTypeAttribute();
}
if (Tools::isSubmit('updateattribute') || Tools::isSubmit('deleteattribute') || Tools::isSubmit('submitAddattribute') || Tools::isSubmit('submitBulkdeleteattribute')) {
Tools::clearColorListCache();
}
return $object;
}
/**
* AdminController::initContent() override.
*
* @see AdminController::initContent()
*/
public function initContent()
{
if (Combination::isFeatureActive()) {
if ($this->display == 'edit' || $this->display == 'add') {
if (!($this->object = $this->loadObject(true))) {
return;
}
$this->content .= $this->renderForm();
} elseif ($this->display == 'editAttributes') {
if (!$this->object = new Attribute((int) Tools::getValue('id_attribute'))) {
return;
}
$this->content .= $this->renderFormAttributes();
} elseif ($this->display != 'view' && !$this->ajax) {
$this->content .= $this->renderList();
$this->content .= $this->renderOptions();
/* reset all attributes filter */
if (!Tools::getValue('submitFilterattribute_group', 0) && !Tools::getIsset('id_attribute_group')) {
$this->processResetFilters('attribute_values');
}
} elseif ($this->display == 'view' && !$this->ajax) {
$this->content = $this->renderView();
}
} else {
$adminPerformanceUrl = $this->context->link->getAdminLink('AdminPerformance');
$url = '<a href="' . $adminPerformanceUrl . '#featuresDetachables">' . $this->trans('Performance', array(), 'Admin.Global') . '</a>';
$this->displayWarning($this->trans('This feature has been disabled. You can activate it here: %link%.', array('%link%' => $url), 'Admin.Catalog.Notification'));
}
$this->context->smarty->assign(array(
'table' => $this->table,
'current' => self::$currentIndex,
'token' => $this->token,
'content' => $this->content,
));
}
public function initPageHeaderToolbar()
{
if (Combination::isFeatureActive()) {
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_attribute_group'] = array(
'href' => self::$currentIndex . '&addattribute_group&token=' . $this->token,
'desc' => $this->trans('Add new attribute', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
$this->page_header_toolbar_btn['new_value'] = array(
'href' => self::$currentIndex . '&updateattribute&id_attribute_group=' . (int) Tools::getValue('id_attribute_group') . '&token=' . $this->token,
'desc' => $this->trans('Add new value', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
}
}
if ($this->display == 'view') {
$this->page_header_toolbar_btn['new_value'] = array(
'href' => self::$currentIndex . '&updateattribute&id_attribute_group=' . (int) Tools::getValue('id_attribute_group') . '&token=' . $this->token,
'desc' => $this->trans('Add new value', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function initToolbar()
{
switch ($this->display) {
// @todo defining default buttons
case 'add':
case 'edit':
case 'editAttributes':
// Default save button - action dynamically handled in javascript
$this->toolbar_btn['save'] = array(
'href' => '#',
'desc' => $this->trans('Save', array(), 'Admin.Actions'),
);
if ($this->display == 'editAttributes' && !$this->id_attribute) {
$this->toolbar_btn['save-and-stay'] = array(
'short' => 'SaveAndStay',
'href' => '#',
'desc' => $this->trans('Save then add another value', array(), 'Admin.Catalog.Help'),
'force_desc' => true,
);
}
$this->toolbar_btn['back'] = array(
'href' => $this->context->link->getAdminLink('AdminAttributesGroups'),
'desc' => $this->trans('Back to list', array(), 'Admin.Actions'),
);
break;
case 'view':
$this->toolbar_btn['newAttributes'] = array(
'href' => $this->context->link->getAdminLink('AdminAttributesGroups', true, array(), array('updateattribute' => 1, 'id_attribute_group' => (int) Tools::getValue('id_attribute_group'))),
'desc' => $this->trans('Add New Values', array(), 'Admin.Catalog.Feature'),
'class' => 'toolbar-new',
);
$this->toolbar_btn['back'] = array(
'href' => $this->context->link->getAdminLink('AdminAttributesGroups'),
'desc' => $this->trans('Back to list', array(), 'Admin.Actions'),
);
break;
default: // list
$this->toolbar_btn['new'] = array(
'href' => $this->context->link->getAdminLink('AdminAttributesGroups', true, array(), array('add' . $this->table => 1)),
'desc' => $this->trans('Add New Attributes', array(), 'Admin.Catalog.Feature'),
);
if ($this->can_import) {
$this->toolbar_btn['import'] = array(
'href' => $this->context->link->getAdminLink('AdminImport', true, array(), array('import_type' => 'combinations')),
'desc' => $this->trans('Import', array(), 'Admin.Actions'),
);
}
}
}
public function initToolbarTitle()
{
$bread_extended = $this->breadcrumbs;
switch ($this->display) {
case 'edit':
$bread_extended[] = $this->trans('Edit New Attribute', array(), 'Admin.Catalog.Feature');
break;
case 'add':
$bread_extended[] = $this->trans('Add New Attribute', array(), 'Admin.Catalog.Feature');
break;
case 'view':
if (Tools::getIsset('viewattribute_group')) {
if (($id = (int) Tools::getValue('id_attribute_group'))) {
if (Validate::isLoadedObject($obj = new AttributeGroup((int) $id))) {
$bread_extended[] = $obj->name[$this->context->employee->id_lang];
}
}
} else {
$bread_extended[] = $this->attribute_name[$this->context->employee->id_lang];
}
break;
case 'editAttributes':
if ($this->id_attribute) {
if (($id = (int) Tools::getValue('id_attribute_group'))) {
if (Validate::isLoadedObject($obj = new AttributeGroup((int) $id))) {
$bread_extended[] = '<a href="' . Context::getContext()->link->getAdminLink('AdminAttributesGroups') . '&id_attribute_group=' . $id . '&viewattribute_group">' . $obj->name[$this->context->employee->id_lang] . '</a>';
}
if (Validate::isLoadedObject($obj = new Attribute((int) $this->id_attribute))) {
$bread_extended[] = $this->trans(
'Edit: %value%',
array(
'%value%' => $obj->name[$this->context->employee->id_lang],
),
'Admin.Catalog.Feature'
);
}
} else {
$bread_extended[] = $this->trans('Edit Value', array(), 'Admin.Catalog.Feature');
}
} else {
$bread_extended[] = $this->trans('Add New Value', array(), 'Admin.Catalog.Feature');
}
break;
}
if (count($bread_extended) > 0) {
$this->addMetaTitle($bread_extended[count($bread_extended) - 1]);
}
$this->toolbar_title = $bread_extended;
}
public function initProcess()
{
$this->setTypeAttribute();
if (Tools::getIsset('viewattribute_group')) {
$this->list_id = 'attribute_values';
if (isset($_POST['submitReset' . $this->list_id])) {
$this->processResetFilters();
}
} else {
$this->list_id = 'attribute_group';
}
parent::initProcess();
if ($this->table == 'attribute') {
$this->display = 'editAttributes';
$this->id_attribute = (int) Tools::getValue('id_attribute');
}
}
protected function setTypeAttribute()
{
if (Tools::isSubmit('updateattribute') || Tools::isSubmit('deleteattribute') || Tools::isSubmit('submitAddattribute') || Tools::isSubmit('submitBulkdeleteattribute')) {
$this->table = 'attribute';
$this->className = 'Attribute';
$this->identifier = 'id_attribute';
if ($this->display == 'edit') {
$this->display = 'editAttributes';
}
}
}
public function processPosition()
{
if (Tools::getIsset('viewattribute_group')) {
$object = new Attribute((int) Tools::getValue('id_attribute'));
self::$currentIndex = self::$currentIndex . '&viewattribute_group';
} else {
$object = new AttributeGroup((int) Tools::getValue('id_attribute_group'));
}
if (!Validate::isLoadedObject($object)) {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error') .
' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
} elseif (!$object->updatePosition((int) Tools::getValue('way'), (int) Tools::getValue('position'))) {
$this->errors[] = $this->trans('Failed to update the position.', array(), 'Admin.Notifications.Error');
} else {
$id_identifier_str = ($id_identifier = (int) Tools::getValue($this->identifier)) ? '&' . $this->identifier . '=' . $id_identifier : '';
$redirect = self::$currentIndex . '&' . $this->table . 'Orderby=position&' . $this->table . 'Orderway=asc&conf=5' . $id_identifier_str . '&token=' . $this->token;
$this->redirect_after = $redirect;
}
return $object;
}
/**
* Call the right method for creating or updating object.
*
* @return mixed
*/
public function processSave()
{
if ($this->display == 'add' || $this->display == 'edit') {
$this->identifier = 'id_attribute_group';
}
if (!$this->id_object) {
return $this->processAdd();
} else {
return $this->processUpdate();
}
}
public function postProcess()
{
if (!Combination::isFeatureActive()) {
return;
}
if (!Tools::getValue($this->identifier) && (int) Tools::getValue('id_attribute') && !Tools::getValue('attributeOrderby')) {
// Override var of Controller
$this->table = 'attribute';
$this->className = 'Attribute';
$this->identifier = 'id_attribute';
}
/* set location with current index */
if (Tools::getIsset('id_attribute_group') && Tools::getIsset('viewattribute_group')) {
self::$currentIndex = self::$currentIndex . '&id_attribute_group=' . (int) Tools::getValue('id_attribute_group', 0) . '&viewattribute_group';
}
// If it's an attribute, load object Attribute()
if (Tools::getValue('updateattribute') || Tools::isSubmit('deleteattribute') || Tools::isSubmit('submitAddattribute')) {
if (true !== $this->access('edit')) {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
return;
} elseif (!$object = new Attribute((int) Tools::getValue($this->identifier))) {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error') .
' <b>' . $this->table . '</b> ' .
$this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
return;
}
if (Tools::getValue('position') !== false && Tools::getValue('id_attribute')) {
$_POST['id_attribute_group'] = $object->id_attribute_group;
if (!$object->updatePosition((int) Tools::getValue('way'), (int) Tools::getValue('position'))) {
$this->errors[] = $this->trans('Failed to update the position.', array(), 'Admin.Notifications.Error');
} else {
Tools::redirectAdmin(self::$currentIndex . '&conf=5&token=' . Tools::getAdminTokenLite('AdminAttributesGroups') . '#details_details_' . $object->id_attribute_group);
}
} elseif (Tools::isSubmit('deleteattribute') && Tools::getValue('id_attribute')) {
if (!$object->delete()) {
$this->errors[] = $this->trans('Failed to delete the attribute.', array(), 'Admin.Catalog.Notification');
} else {
Tools::redirectAdmin(self::$currentIndex . '&conf=1&token=' . Tools::getAdminTokenLite('AdminAttributesGroups'));
}
} elseif (Tools::isSubmit('submitAddattribute')) {
Hook::exec('actionObjectAttributeAddBefore');
$this->action = 'save';
$id_attribute = (int) Tools::getValue('id_attribute');
// Adding last position to the attribute if not exist
if ($id_attribute <= 0) {
$sql = 'SELECT `position`+1
FROM `' . _DB_PREFIX_ . 'attribute`
WHERE `id_attribute_group` = ' . (int) Tools::getValue('id_attribute_group') . '
ORDER BY position DESC';
// set the position of the new group attribute in $_POST for postProcess() method
$_POST['position'] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
}
$_POST['id_parent'] = 0;
$this->processSave($this->token);
}
} else {
if (Tools::isSubmit('submitBulkdelete' . $this->table)) {
if ($this->access('delete')) {
if (isset($_POST[$this->list_id . 'Box'])) {
/** @var AttributeGroup $object */
$object = new $this->className();
if ($object->deleteSelection($_POST[$this->list_id . 'Box'])) {
AttributeGroup::cleanPositions();
Tools::redirectAdmin(self::$currentIndex . '&conf=2' . '&token=' . $this->token);
}
$this->errors[] = $this->trans('An error occurred while deleting this selection.', array(), 'Admin.Notifications.Error');
} else {
$this->errors[] = $this->trans('You must select at least one element to delete.', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
// clean position after delete
AttributeGroup::cleanPositions();
} elseif (Tools::isSubmit('submitAdd' . $this->table)) {
Hook::exec('actionObjectAttributeGroupAddBefore');
$id_attribute_group = (int) Tools::getValue('id_attribute_group');
// Adding last position to the attribute if not exist
if ($id_attribute_group <= 0) {
$sql = 'SELECT `position`+1
FROM `' . _DB_PREFIX_ . 'attribute_group`
ORDER BY position DESC';
// set the position of the new group attribute in $_POST for postProcess() method
$_POST['position'] = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
}
// clean \n\r characters
foreach ($_POST as $key => $value) {
if (preg_match('/^name_/Ui', $key)) {
$_POST[$key] = str_replace('\n', '', str_replace('\r', '', $value));
}
}
parent::postProcess();
} else {
parent::postProcess();
if (Tools::isSubmit('delete' . $this->table)) {
AttributeGroup::cleanPositions();
}
}
}
}
/**
* AdminController::getList() override.
*
* @see AdminController::getList()
*
* @param int $id_lang
* @param string|null $order_by
* @param string|null $order_way
* @param int $start
* @param int|null $limit
* @param int|bool $id_lang_shop
*
* @throws PrestaShopException
*/
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
if ($this->display == 'view') {
foreach ($this->_list as &$list) {
if (file_exists(_PS_IMG_DIR_ . $this->fieldImageSettings['dir'] . '/' . (int) $list['id_attribute'] . '.jpg')) {
if (!isset($list['color']) || !is_array($list['color'])) {
$list['color'] = array();
}
$list['color']['texture'] = '../img/' . $this->fieldImageSettings['dir'] . '/' . (int) $list['id_attribute'] . '.jpg';
}
}
} else {
$nb_items = count($this->_list);
for ($i = 0; $i < $nb_items; ++$i) {
$item = &$this->_list[$i];
$query = new DbQuery();
$query->select('COUNT(a.id_attribute) as count_values');
$query->from('attribute', 'a');
$query->join(Shop::addSqlAssociation('attribute', 'a'));
$query->where('a.id_attribute_group =' . (int) $item['id_attribute_group']);
$query->groupBy('attribute_shop.id_shop');
$query->orderBy('count_values DESC');
$item['count_values'] = (int) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
unset($query);
}
}
}
/**
* Overrides parent to delete items from sublist.
*
* @return mixed
*/
public function processBulkDelete()
{
// If we are deleting attributes instead of attribute_groups
if (Tools::getIsset('attributeBox')) {
$this->className = 'Attribute';
$this->table = 'attribute';
$this->boxes = Tools::getValue($this->table . 'Box');
}
$result = parent::processBulkDelete();
// Restore vars
$this->className = 'AttributeGroup';
$this->table = 'attribute_group';
return $result;
}
/* Modify group attribute position */
public function ajaxProcessUpdateGroupsPositions()
{
$way = (int) Tools::getValue('way');
$id_attribute_group = (int) Tools::getValue('id_attribute_group');
$positions = Tools::getValue('attribute_group');
$new_positions = array();
foreach ($positions as $v) {
if (count(explode('_', $v)) == 4) {
$new_positions[] = $v;
}
}
foreach ($new_positions as $position => $value) {
$pos = explode('_', $value);
if (isset($pos[2]) && (int) $pos[2] === $id_attribute_group) {
if ($group_attribute = new AttributeGroup((int) $pos[2])) {
if (isset($position) && $group_attribute->updatePosition($way, $position)) {
echo 'ok position ' . (int) $position . ' for attribute group ' . (int) $pos[2] . '\r\n';
} else {
echo '{"hasError" : true, "errors" : "Can not update the ' . (int) $id_attribute_group . ' attribute group to position ' . (int) $position . ' "}';
}
} else {
echo '{"hasError" : true, "errors" : "The (' . (int) $id_attribute_group . ') attribute group cannot be loaded."}';
}
break;
}
}
}
/* Modify attribute position */
public function ajaxProcessUpdateAttributesPositions()
{
$way = (int) Tools::getValue('way');
$id_attribute = (int) Tools::getValue('id_attribute');
$id_attribute_group = (int) Tools::getValue('id_attribute_group');
$positions = Tools::getValue('attribute');
if (is_array($positions)) {
foreach ($positions as $position => $value) {
$pos = explode('_', $value);
if ((isset($pos[1], $pos[2])) && (int) $pos[2] === $id_attribute) {
if ($attribute = new Attribute((int) $pos[2])) {
if (isset($position) && $attribute->updatePosition($way, $position)) {
echo 'ok position ' . (int) $position . ' for attribute ' . (int) $pos[2] . '\r\n';
} else {
echo '{"hasError" : true, "errors" : "Can not update the ' . (int) $id_attribute . ' attribute to position ' . (int) $position . ' "}';
}
} else {
echo '{"hasError" : true, "errors" : "The (' . (int) $id_attribute . ') attribute cannot be loaded"}';
}
break;
}
}
}
}
}

View File

@@ -0,0 +1,960 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Carrier $object
*/
class AdminCarrierWizardControllerCore extends AdminController
{
protected $wizard_access;
public function __construct()
{
$this->bootstrap = true;
$this->display = 'view';
$this->table = 'carrier';
$this->identifier = 'id_carrier';
$this->className = 'Carrier';
$this->lang = false;
$this->deleted = true;
$this->step_number = 0;
$this->type_context = Shop::getContext();
$this->old_context = Context::getContext();
$this->multishop_context = Shop::CONTEXT_ALL;
$this->context = Context::getContext();
$this->fieldImageSettings = array(
'name' => 'logo',
'dir' => 's',
);
parent::__construct();
$this->tabAccess = Profile::getProfileAccess($this->context->employee->id_profile, Tab::getIdFromClassName('AdminCarriers'));
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryPlugin('smartWizard');
$this->addJqueryPlugin('typewatch');
$this->addJs(_PS_JS_DIR_ . 'admin/carrier_wizard.js');
}
public function initWizard()
{
$this->wizard_steps = array(
'name' => 'carrier_wizard',
'steps' => array(
array(
'title' => $this->trans('General settings', array(), 'Admin.Shipping.Feature'),
),
array(
'title' => $this->trans('Shipping locations and costs', array(), 'Admin.Shipping.Feature'),
),
array(
'title' => $this->trans('Size, weight, and group access', array(), 'Admin.Shipping.Feature'),
),
array(
'title' => $this->trans('Summary', array(), 'Admin.Global'),
), ),
);
if (Shop::isFeatureActive()) {
$multistore_step = array(
array(
'title' => $this->trans('MultiStore', array(), 'Admin.Global'),
),
);
array_splice($this->wizard_steps['steps'], 1, 0, $multistore_step);
}
}
public function renderView()
{
$this->initWizard();
if (Tools::getValue('id_carrier') && $this->access('edit')) {
$carrier = $this->loadObject();
} elseif ($this->access('add')) {
$carrier = new Carrier();
}
if ((!$this->access('edit') && Tools::getValue('id_carrier')) || (!$this->access('add') && !Tools::getValue('id_carrier'))) {
$this->errors[] = $this->trans('You do not have permission to use this wizard.', array(), 'Admin.Shipping.Notification');
return;
}
$currency = $this->getActualCurrency();
$this->tpl_view_vars = array(
'currency_sign' => $currency->sign,
'PS_WEIGHT_UNIT' => Configuration::get('PS_WEIGHT_UNIT'),
'enableAllSteps' => Validate::isLoadedObject($carrier),
'wizard_steps' => $this->wizard_steps,
'validate_url' => $this->context->link->getAdminLink('AdminCarrierWizard'),
'carrierlist_url' => $this->context->link->getAdminLink('AdminCarriers') . '&conf=' . ((int) Validate::isLoadedObject($carrier) ? 4 : 3),
'multistore_enable' => Shop::isFeatureActive(),
'wizard_contents' => array(
'contents' => array(
0 => $this->renderStepOne($carrier),
1 => $this->renderStepThree($carrier),
2 => $this->renderStepFour($carrier),
3 => $this->renderStepFive($carrier),
),
),
'labels' => array(
'next' => $this->trans('Next', array(), 'Admin.Global'),
'previous' => $this->trans('Previous', array(), 'Admin.Global'),
'finish' => $this->trans('Finish', array(), 'Admin.Actions'), ),
);
if (Shop::isFeatureActive()) {
array_splice($this->tpl_view_vars['wizard_contents']['contents'], 1, 0, array(0 => $this->renderStepTwo($carrier)));
}
$this->context->smarty->assign(array(
'carrier_logo' => (Validate::isLoadedObject($carrier) && file_exists(_PS_SHIP_IMG_DIR_ . $carrier->id . '.jpg') ? _THEME_SHIP_DIR_ . $carrier->id . '.jpg' : false),
));
$this->context->smarty->assign(array(
'logo_content' => $this->createTemplate('logo.tpl')->fetch(),
));
$this->addjQueryPlugin(array('ajaxfileupload'));
return parent::renderView();
}
public function initBreadcrumbs($tab_id = null, $tabs = null)
{
if (Tools::getValue('id_carrier')) {
$this->display = 'edit';
} else {
$this->display = 'add';
}
parent::initBreadcrumbs((int) Tab::getIdFromClassName('AdminCarriers'));
$this->display = 'view';
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
$this->page_header_toolbar_btn['cancel'] = array(
'href' => $this->context->link->getAdminLink('AdminCarriers'),
'desc' => $this->trans('Cancel', array(), 'Admin.Actions'),
);
}
public function renderStepOne($carrier)
{
$this->fields_form = array(
'form' => array(
'id_form' => 'step_carrier_general',
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Carrier name', array(), 'Admin.Shipping.Feature'),
'name' => 'name',
'required' => true,
'hint' => array(
$this->trans('Allowed characters: letters, spaces and "%special_chars%".', array('%special_chars%' => '().-'), 'Admin.Shipping.Help'),
$this->trans('The carrier\'s name will be displayed during checkout.', array(), 'Admin.Shipping.Help'),
$this->trans('For in-store pickup, enter 0 to replace the carrier name with your shop name.', array(), 'Admin.Shipping.Help'),
),
),
array(
'type' => 'text',
'label' => $this->trans('Transit time', array(), 'Admin.Shipping.Feature'),
'name' => 'delay',
'lang' => true,
'required' => true,
'maxlength' => 512,
'hint' => $this->trans('The delivery time will be displayed during checkout.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Speed grade', array(), 'Admin.Shipping.Feature'),
'name' => 'grade',
'required' => false,
'size' => 1,
'hint' => $this->trans('Enter "0" for a longest shipping delay, or "9" for the shortest shipping delay.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'logo',
'label' => $this->trans('Logo', array(), 'Admin.Global'),
'name' => 'logo',
),
array(
'type' => 'text',
'label' => $this->trans('Tracking URL', array(), 'Admin.Shipping.Feature'),
'name' => 'url',
'hint' => $this->trans('Delivery tracking URL: Type \'@\' where the tracking number should appear. It will be automatically replaced by the tracking number.', array(), 'Admin.Shipping.Help'),
'desc' => $this->trans('For example: \'http://example.com/track.php?num=@\' with \'@\' where the tracking number should appear.', array(), 'Admin.Shipping.Help'),
),
),
),
);
$tpl_vars = array('max_image_size' => (int) Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE') / 1024 / 1024);
$fields_value = $this->getStepOneFieldsValues($carrier);
return $this->renderGenericForm(array('form' => $this->fields_form), $fields_value, $tpl_vars);
}
public function renderStepTwo($carrier)
{
$this->fields_form = array(
'form' => array(
'id_form' => 'step_carrier_shops',
'force' => true,
'input' => array(
array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
),
),
),
);
$fields_value = $this->getStepTwoFieldsValues($carrier);
return $this->renderGenericForm(array('form' => $this->fields_form), $fields_value);
}
public function renderStepThree($carrier)
{
$this->fields_form = array(
'form' => array(
'id_form' => 'step_carrier_ranges',
'input' => array(
'shipping_handling' => array(
'type' => 'switch',
'label' => $this->trans('Add handling costs', array(), 'Admin.Shipping.Feature'),
'name' => 'shipping_handling',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'shipping_handling_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'shipping_handling_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
'hint' => $this->trans('Include the handling costs (as set in Shipping > Preferences) in the final carrier price.', array(), 'Admin.Shipping.Help'),
),
'is_free' => array(
'type' => 'switch',
'label' => $this->trans('Free shipping', array(), 'Admin.Shipping.Feature'),
'name' => 'is_free',
'required' => false,
'class' => 't',
'values' => array(
array(
'id' => 'is_free_on',
'value' => 1,
'label' => '<img src="../img/admin/disabled.gif" alt="' . $this->trans('No', array(), 'Admin.Global') . '" title="' . $this->trans('No', array(), 'Admin.Global') . '" />',
),
array(
'id' => 'is_free_off',
'value' => 0,
'label' => '<img src="../img/admin/enabled.gif" alt="' . $this->trans('Yes', array(), 'Admin.Global') . '" title="' . $this->trans('Yes', array(), 'Admin.Global') . '" />',
),
),
),
'shipping_method' => array(
'type' => 'radio',
'label' => $this->trans('Billing', array(), 'Admin.Shipping.Feature'),
'name' => 'shipping_method',
'required' => false,
'class' => 't',
'br' => true,
'values' => array(
array(
'id' => 'billing_price',
'value' => Carrier::SHIPPING_METHOD_PRICE,
'label' => $this->trans('According to total price.', array(), 'Admin.Shipping.Feature'),
),
array(
'id' => 'billing_weight',
'value' => Carrier::SHIPPING_METHOD_WEIGHT,
'label' => $this->trans('According to total weight.', array(), 'Admin.Shipping.Feature'),
),
),
),
'id_tax_rules_group' => array(
'type' => 'select',
'label' => $this->trans('Tax', array(), 'Admin.Global'),
'name' => 'id_tax_rules_group',
'options' => array(
'query' => TaxRulesGroup::getTaxRulesGroups(true),
'id' => 'id_tax_rules_group',
'name' => 'name',
'default' => array(
'label' => $this->trans('No tax', array(), 'Admin.Global'),
'value' => 0,
),
),
),
'range_behavior' => array(
'type' => 'select',
'label' => $this->trans('Out-of-range behavior', array(), 'Admin.Shipping.Feature'),
'name' => 'range_behavior',
'options' => array(
'query' => array(
array(
'id' => 0,
'name' => $this->trans('Apply the cost of the highest defined range', array(), 'Admin.Shipping.Feature'),
),
array(
'id' => 1,
'name' => $this->trans('Disable carrier', array(), 'Admin.Shipping.Feature'),
),
),
'id' => 'id',
'name' => 'name',
),
'hint' => $this->trans('Out-of-range behavior occurs when no defined range matches the customer\'s cart (e.g. when the weight of the cart is greater than the highest weight limit defined by the weight ranges).', array(), 'Admin.Shipping.Help'),
),
'zones' => array(
'type' => 'zone',
'name' => 'zones',
),
),
),
);
if (Configuration::get('PS_ATCP_SHIPWRAP')) {
unset($this->fields_form['form']['input']['id_tax_rules_group']);
}
$tpl_vars = array();
$tpl_vars['PS_WEIGHT_UNIT'] = Configuration::get('PS_WEIGHT_UNIT');
$currency = $this->getActualCurrency();
$tpl_vars['currency_sign'] = $currency->sign;
$fields_value = $this->getStepThreeFieldsValues($carrier);
$this->getTplRangesVarsAndValues($carrier, $tpl_vars, $fields_value);
return $this->renderGenericForm(array('form' => $this->fields_form), $fields_value, $tpl_vars);
}
/**
* @param Carrier $carrier
*
* @return string
*/
public function renderStepFour($carrier)
{
$this->fields_form = array(
'form' => array(
'id_form' => 'step_carrier_conf',
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Maximum package width (%s)', array('%s' => Configuration::get('PS_DIMENSION_UNIT')), 'Admin.Shipping.Feature'),
'name' => 'max_width',
'required' => false,
'hint' => $this->trans('Maximum width managed by this carrier. Set the value to "0", or leave this field blank to ignore.', array(), 'Admin.Shipping.Help') . ' ' . $this->trans('The value must be an integer.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Maximum package height (%s)', array('%s' => Configuration::get('PS_DIMENSION_UNIT')), 'Admin.Shipping.Feature'),
'name' => 'max_height',
'required' => false,
'hint' => $this->trans('Maximum height managed by this carrier. Set the value to "0", or leave this field blank to ignore.', array(), 'Admin.Shipping.Help') . ' ' . $this->trans('The value must be an integer.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Maximum package depth (%s)', array('%s' => Configuration::get('PS_DIMENSION_UNIT')), 'Admin.Shipping.Feature'),
'name' => 'max_depth',
'required' => false,
'hint' => $this->trans('Maximum depth managed by this carrier. Set the value to "0", or leave this field blank to ignore.', array(), 'Admin.Shipping.Help') . ' ' . $this->trans('The value must be an integer.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Maximum package weight (%s)', array('%s' => Configuration::get('PS_WEIGHT_UNIT')), 'Admin.Shipping.Feature'),
'name' => 'max_weight',
'required' => false,
'hint' => $this->trans('Maximum weight managed by this carrier. Set the value to "0", or leave this field blank to ignore.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'group',
'label' => $this->trans('Group access', array(), 'Admin.Shipping.Feature'),
'name' => 'groupBox',
'values' => Group::getGroups(Context::getContext()->language->id),
'hint' => $this->trans('Mark the groups that are allowed access to this carrier.', array(), 'Admin.Shipping.Help'),
),
),
),
);
$fields_value = $this->getStepFourFieldsValues($carrier);
// Added values of object Group
$carrier_groups = $carrier->getGroups();
$carrier_groups_ids = array();
if (is_array($carrier_groups)) {
foreach ($carrier_groups as $carrier_group) {
$carrier_groups_ids[] = $carrier_group['id_group'];
}
}
$groups = Group::getGroups($this->context->language->id);
foreach ($groups as $group) {
$fields_value['groupBox_' . $group['id_group']] = Tools::getValue('groupBox_' . $group['id_group'], (in_array($group['id_group'], $carrier_groups_ids) || empty($carrier_groups_ids) && !$carrier->id));
}
return $this->renderGenericForm(array('form' => $this->fields_form), $fields_value);
}
public function renderStepFive($carrier)
{
$this->fields_form = array(
'form' => array(
'id_form' => 'step_carrier_summary',
'input' => array(
array(
'type' => 'switch',
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
),
array(
'id' => 'active_off',
'value' => 0,
),
),
'hint' => $this->trans('Enable the carrier in the front office.', array(), 'Admin.Shipping.Help'),
),
),
),
);
$template = $this->createTemplate('controllers/carrier_wizard/summary.tpl');
$fields_value = $this->getStepFiveFieldsValues($carrier);
$active_form = $this->renderGenericForm(array('form' => $this->fields_form), $fields_value);
$active_form = str_replace(array('<fieldset id="fieldset_form">', '</fieldset>'), '', $active_form);
$template->assign('active_form', $active_form);
return $template->fetch();
}
/**
* @param Carrier $carrier
* @param array $tpl_vars
* @param array $fields_value
*/
protected function getTplRangesVarsAndValues($carrier, &$tpl_vars, &$fields_value)
{
$tpl_vars['zones'] = Zone::getZones(false, true);
$carrier_zones = $carrier->getZones();
$carrier_zones_ids = array();
if (is_array($carrier_zones)) {
foreach ($carrier_zones as $carrier_zone) {
$carrier_zones_ids[] = $carrier_zone['id_zone'];
}
}
$range_table = $carrier->getRangeTable();
$shipping_method = $carrier->getShippingMethod();
$zones = Zone::getZones(false);
foreach ($zones as $zone) {
$fields_value['zones'][$zone['id_zone']] = Tools::getValue('zone_' . $zone['id_zone'], (in_array($zone['id_zone'], $carrier_zones_ids)));
}
if ($shipping_method == Carrier::SHIPPING_METHOD_FREE) {
$range_obj = $carrier->getRangeObject($carrier->shipping_method);
$price_by_range = array();
} else {
$range_obj = $carrier->getRangeObject();
$price_by_range = Carrier::getDeliveryPriceByRanges($range_table, (int) $carrier->id);
}
foreach ($price_by_range as $price) {
$tpl_vars['price_by_range'][$price['id_' . $range_table]][$price['id_zone']] = $price['price'];
}
$tmp_range = $range_obj->getRanges((int) $carrier->id);
$tpl_vars['ranges'] = array();
if ($shipping_method != Carrier::SHIPPING_METHOD_FREE) {
foreach ($tmp_range as $id => $range) {
$tpl_vars['ranges'][$range['id_' . $range_table]] = $range;
$tpl_vars['ranges'][$range['id_' . $range_table]]['id_range'] = $range['id_' . $range_table];
}
}
// init blank range
if (!count($tpl_vars['ranges'])) {
$tpl_vars['ranges'][] = array('id_range' => 0, 'delimiter1' => 0, 'delimiter2' => 0);
}
}
public function renderGenericForm($fields_form, $fields_value, $tpl_vars = array())
{
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$lang = new Language((int) Configuration::get('PS_LANG_DEFAULT'));
$helper->default_form_language = $lang->id;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$this->fields_form = array();
$helper->id = (int) Tools::getValue('id_carrier');
$helper->identifier = $this->identifier;
$helper->tpl_vars = array_merge(array(
'fields_value' => $fields_value,
'languages' => $this->getLanguages(),
'id_language' => $this->context->language->id,
), $tpl_vars);
$helper->override_folder = 'carrier_wizard/';
return $helper->generateForm($fields_form);
}
public function getStepOneFieldsValues($carrier)
{
return array(
'id_carrier' => $this->getFieldValue($carrier, 'id_carrier'),
'name' => $this->getFieldValue($carrier, 'name'),
'delay' => $this->getFieldValue($carrier, 'delay'),
'grade' => $this->getFieldValue($carrier, 'grade'),
'url' => $this->getFieldValue($carrier, 'url'),
);
}
public function getStepTwoFieldsValues($carrier)
{
return array('shop' => $this->getFieldValue($carrier, 'shop'));
}
public function getStepThreeFieldsValues($carrier)
{
$id_tax_rules_group = (is_object($this->object) && !$this->object->id) ? Carrier::getIdTaxRulesGroupMostUsed() : Carrier::getIdTaxRulesGroupByIdCarrier($this->object->id);
$shipping_handling = (is_object($this->object) && !$this->object->id) ? 0 : $this->getFieldValue($carrier, 'shipping_handling');
return array(
'is_free' => $this->getFieldValue($carrier, 'is_free'),
'id_tax_rules_group' => (int) $id_tax_rules_group,
'shipping_handling' => $shipping_handling,
'shipping_method' => $this->getFieldValue($carrier, 'shipping_method'),
'range_behavior' => $this->getFieldValue($carrier, 'range_behavior'),
'zones' => $this->getFieldValue($carrier, 'zones'),
);
}
public function getStepFourFieldsValues($carrier)
{
return array(
'range_behavior' => $this->getFieldValue($carrier, 'range_behavior'),
'max_height' => $this->getFieldValue($carrier, 'max_height'),
'max_width' => $this->getFieldValue($carrier, 'max_width'),
'max_depth' => $this->getFieldValue($carrier, 'max_depth'),
'max_weight' => $this->getFieldValue($carrier, 'max_weight'),
'group' => $this->getFieldValue($carrier, 'group'),
);
}
public function getStepFiveFieldsValues($carrier)
{
return array('active' => $this->getFieldValue($carrier, 'active'));
}
public function ajaxProcessChangeRanges()
{
if ((Validate::isLoadedObject($this->object) && !$this->access('edit')) || !$this->access('add')) {
$this->errors[] = $this->trans('You do not have permission to use this wizard.', array(), 'Admin.Shipping.Notification');
return;
}
if ((!(int) $shipping_method = Tools::getValue('shipping_method')) || !in_array($shipping_method, array(Carrier::SHIPPING_METHOD_PRICE, Carrier::SHIPPING_METHOD_WEIGHT))) {
return;
}
$carrier = $this->loadObject(true);
$carrier->shipping_method = $shipping_method;
$tpl_vars = array();
$fields_value = $this->getStepThreeFieldsValues($carrier);
$this->getTplRangesVarsAndValues($carrier, $tpl_vars, $fields_value);
$template = $this->createTemplate('controllers/carrier_wizard/helpers/form/form_ranges.tpl');
$template->assign($tpl_vars);
$template->assign('change_ranges', 1);
$template->assign('fields_value', $fields_value);
$template->assign('input', array('type' => 'zone', 'name' => 'zones'));
$currency = $this->getActualCurrency();
$template->assign('currency_sign', $currency->sign);
$template->assign('PS_WEIGHT_UNIT', Configuration::get('PS_WEIGHT_UNIT'));
die($template->fetch());
}
protected function validateForm($die = true)
{
$step_number = (int) Tools::getValue('step_number');
$return = array('has_error' => false);
if (!$this->access('edit')) {
$this->errors[] = $this->trans('You do not have permission to use this wizard.', array(), 'Admin.Shipping.Notification');
} else {
if (Shop::isFeatureActive() && $step_number == 2) {
if (!Tools::getValue('checkBoxShopAsso_carrier')) {
$return['has_error'] = true;
$return['errors'][] = $this->trans('You must choose at least one shop or group shop.', array(), 'Admin.Shipping.Notification');
}
} else {
$this->validateRules();
}
}
if (count($this->errors)) {
$return['has_error'] = true;
$return['errors'] = $this->errors;
}
if (count($this->errors) || $die) {
die(json_encode($return));
}
}
public function ajaxProcessValidateStep()
{
$this->validateForm(true);
}
public function processRanges($id_carrier)
{
if (!$this->access('edit') || !$this->access('add')) {
$this->errors[] = $this->trans('You do not have permission to use this wizard.', array(), 'Admin.Shipping.Notification');
return;
}
$carrier = new Carrier((int) $id_carrier);
if (!Validate::isLoadedObject($carrier)) {
return false;
}
$range_inf = Tools::getValue('range_inf');
$range_sup = Tools::getValue('range_sup');
$range_type = Tools::getValue('shipping_method');
$fees = Tools::getValue('fees');
$carrier->deleteDeliveryPrice($carrier->getRangeTable());
if ($range_type != Carrier::SHIPPING_METHOD_FREE) {
foreach ($range_inf as $key => $delimiter1) {
if (!isset($range_sup[$key])) {
continue;
}
$range = $carrier->getRangeObject((int) $range_type);
$range->id_carrier = (int) $carrier->id;
$range->delimiter1 = (float) $delimiter1;
$range->delimiter2 = (float) $range_sup[$key];
$range->save();
if (!Validate::isLoadedObject($range)) {
return false;
}
$price_list = array();
if (is_array($fees) && count($fees)) {
foreach ($fees as $id_zone => $fee) {
$price_list[] = array(
'id_range_price' => ($range_type == Carrier::SHIPPING_METHOD_PRICE ? (int) $range->id : null),
'id_range_weight' => ($range_type == Carrier::SHIPPING_METHOD_WEIGHT ? (int) $range->id : null),
'id_carrier' => (int) $carrier->id,
'id_zone' => (int) $id_zone,
'price' => isset($fee[$key]) ? (float) str_replace(',', '.', $fee[$key]) : 0,
);
}
}
if (count($price_list) && !$carrier->addDeliveryPrice($price_list, true)) {
return false;
}
}
}
return true;
}
public function ajaxProcessUploadLogo()
{
if (!$this->access('edit')) {
die('<return result="error" message="' . $this->trans('You do not have permission to use this wizard.', array(), 'Admin.Shipping.Notification') . '" />');
}
$allowedExtensions = array('jpeg', 'gif', 'png', 'jpg');
$logo = (isset($_FILES['carrier_logo_input']) ? $_FILES['carrier_logo_input'] : false);
if ($logo && !empty($logo['tmp_name']) && $logo['tmp_name'] != 'none'
&& (!isset($logo['error']) || !$logo['error'])
&& preg_match('/\.(jpe?g|gif|png)$/', $logo['name'])
&& is_uploaded_file($logo['tmp_name'])
&& ImageManager::isRealImage($logo['tmp_name'], $logo['type'])) {
$file = $logo['tmp_name'];
do {
$tmp_name = uniqid() . '.jpg';
} while (file_exists(_PS_TMP_IMG_DIR_ . $tmp_name));
if (!ImageManager::resize($file, _PS_TMP_IMG_DIR_ . $tmp_name)) {
die('<return result="error" message="Impossible to resize the image into ' . Tools::safeOutput(_PS_TMP_IMG_DIR_) . '" />');
}
@unlink($file);
die('<return result="success" message="' . Tools::safeOutput(_PS_TMP_IMG_ . $tmp_name) . '" />');
} else {
die('<return result="error" message="Cannot upload file" />');
}
}
public function ajaxProcessFinishStep()
{
$return = array('has_error' => false);
if (!$this->access('edit')) {
$return = array(
'has_error' => true,
$return['errors'][] = $this->trans('You do not have permission to use this wizard.', array(), 'Admin.Shipping.Notification'),
);
} else {
$this->validateForm(false);
if ($id_carrier = Tools::getValue('id_carrier')) {
$current_carrier = new Carrier((int) $id_carrier);
// if update we duplicate current Carrier
/** @var Carrier $new_carrier */
$new_carrier = $current_carrier->duplicateObject();
if (Validate::isLoadedObject($new_carrier)) {
// Set flag deteled to true for historization
$current_carrier->deleted = true;
$current_carrier->update();
// Fill the new carrier object
$this->copyFromPost($new_carrier, $this->table);
$new_carrier->position = $current_carrier->position;
$new_carrier->update();
$this->updateAssoShop((int) $new_carrier->id);
$this->duplicateLogo((int) $new_carrier->id, (int) $current_carrier->id);
$this->changeGroups((int) $new_carrier->id);
//Copy default carrier
if (Configuration::get('PS_CARRIER_DEFAULT') == $current_carrier->id) {
Configuration::updateValue('PS_CARRIER_DEFAULT', (int) $new_carrier->id);
}
// Call of hooks
Hook::exec('actionCarrierUpdate', array(
'id_carrier' => (int) $current_carrier->id,
'carrier' => $new_carrier,
));
$this->postImage($new_carrier->id);
$this->changeZones($new_carrier->id);
$new_carrier->setTaxRulesGroup((int) Tools::getValue('id_tax_rules_group'));
$carrier = $new_carrier;
}
} else {
$carrier = new Carrier();
$this->copyFromPost($carrier, $this->table);
if (!$carrier->add()) {
$return['has_error'] = true;
$return['errors'][] = $this->trans('An error occurred while saving this carrier.', array(), 'Admin.Shipping.Notification');
}
}
if ($carrier->is_free) {
//if carrier is free delete shipping cost
$carrier->deleteDeliveryPrice('range_weight');
$carrier->deleteDeliveryPrice('range_price');
}
if (Validate::isLoadedObject($carrier)) {
if (!$this->changeGroups((int) $carrier->id)) {
$return['has_error'] = true;
$return['errors'][] = $this->trans('An error occurred while saving carrier groups.', array(), 'Admin.Shipping.Notification');
}
if (!$this->changeZones((int) $carrier->id)) {
$return['has_error'] = true;
$return['errors'][] = $this->trans('An error occurred while saving carrier zones.', array(), 'Admin.Shipping.Notification');
}
if (!$carrier->is_free) {
if (!$this->processRanges((int) $carrier->id)) {
$return['has_error'] = true;
$return['errors'][] = $this->trans('An error occurred while saving carrier ranges.', array(), 'Admin.Shipping.Notification');
}
}
if (Shop::isFeatureActive() && !$this->updateAssoShop((int) $carrier->id)) {
$return['has_error'] = true;
$return['errors'][] = $this->trans('An error occurred while saving associations of shops.', array(), 'Admin.Shipping.Notification');
}
if (!$carrier->setTaxRulesGroup((int) Tools::getValue('id_tax_rules_group'))) {
$return['has_error'] = true;
$return['errors'][] = $this->trans('An error occurred while saving the tax rules group.', array(), 'Admin.Shipping.Notification');
}
if (Tools::getValue('logo')) {
if (Tools::getValue('logo') == 'null' && file_exists(_PS_SHIP_IMG_DIR_ . $carrier->id . '.jpg')) {
unlink(_PS_SHIP_IMG_DIR_ . $carrier->id . '.jpg');
} else {
$logo = basename(Tools::getValue('logo'));
if (!file_exists(_PS_TMP_IMG_DIR_ . $logo) || !copy(_PS_TMP_IMG_DIR_ . $logo, _PS_SHIP_IMG_DIR_ . $carrier->id . '.jpg')) {
$return['has_error'] = true;
$return['errors'][] = $this->trans('An error occurred while saving carrier logo.', array(), 'Admin.Shipping.Notification');
}
}
}
$return['id_carrier'] = $carrier->id;
}
}
die(json_encode($return));
}
protected function changeGroups($id_carrier, $delete = true)
{
$carrier = new Carrier((int) $id_carrier);
if (!Validate::isLoadedObject($carrier)) {
return false;
}
return $carrier->setGroups(Tools::getValue('groupBox'));
}
public function changeZones($id)
{
$return = true;
$carrier = new Carrier($id);
if (!Validate::isLoadedObject($carrier)) {
die($this->trans('The object cannot be loaded.', array(), 'Admin.Notifications.Error'));
}
$zones = Zone::getZones(false);
foreach ($zones as $zone) {
if (count($carrier->getZone($zone['id_zone']))) {
if (!isset($_POST['zone_' . $zone['id_zone']]) || !$_POST['zone_' . $zone['id_zone']]) {
$return &= $carrier->deleteZone((int) $zone['id_zone']);
}
} elseif (isset($_POST['zone_' . $zone['id_zone']]) && $_POST['zone_' . $zone['id_zone']]) {
$return &= $carrier->addZone((int) $zone['id_zone']);
}
}
return $return;
}
public function getValidationRules()
{
$step_number = (int) Tools::getValue('step_number');
if (!$step_number) {
return;
}
if ($step_number == 4 && !Shop::isFeatureActive() || $step_number == 5 && Shop::isFeatureActive()) {
return array('fields' => array());
}
$step_fields = array(
1 => array('name', 'delay', 'grade', 'url'),
2 => array('is_free', 'id_tax_rules_group', 'shipping_handling', 'shipping_method', 'range_behavior'),
3 => array('range_behavior', 'max_height', 'max_width', 'max_depth', 'max_weight'),
4 => array(),
);
if (Shop::isFeatureActive()) {
$tmp = $step_fields;
$step_fields = array_slice($tmp, 0, 1, true) + array(2 => array('shop'));
$step_fields[3] = $tmp[2];
$step_fields[4] = $tmp[3];
}
$definition = ObjectModel::getDefinition('Carrier');
foreach ($definition['fields'] as $field => $def) {
if (is_array($step_fields[$step_number]) && !in_array($field, $step_fields[$step_number])) {
unset($definition['fields'][$field]);
}
}
return $definition;
}
public static function displayFieldName($field)
{
return $field;
}
public function duplicateLogo($new_id, $old_id)
{
$old_logo = _PS_SHIP_IMG_DIR_ . '/' . (int) $old_id . '.jpg';
if (file_exists($old_logo)) {
copy($old_logo, _PS_SHIP_IMG_DIR_ . '/' . (int) $new_id . '.jpg');
}
$old_tmp_logo = _PS_TMP_IMG_DIR_ . '/carrier_mini_' . (int) $old_id . '.jpg';
if (file_exists($old_tmp_logo)) {
if (!isset($_FILES['logo'])) {
copy($old_tmp_logo, _PS_TMP_IMG_DIR_ . '/carrier_mini_' . $new_id . '.jpg');
}
unlink($old_tmp_logo);
}
}
public function getActualCurrency()
{
if ($this->type_context == Shop::CONTEXT_SHOP) {
Shop::setContext($this->type_context, $this->old_context->shop->id);
} elseif ($this->type_context == Shop::CONTEXT_GROUP) {
Shop::setContext($this->type_context, $this->old_context->shop->id_shop_group);
}
$currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
Shop::setContext(Shop::CONTEXT_ALL);
return $currency;
}
}

View File

@@ -0,0 +1,742 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Carrier $object
*/
class AdminCarriersControllerCore extends AdminController
{
protected $position_identifier = 'id_carrier';
public function __construct()
{
if ($id_carrier = Tools::getValue('id_carrier') && !Tools::isSubmit('deletecarrier') && !Tools::isSubmit('statuscarrier') && !Tools::isSubmit('isFreecarrier')) {
Tools::redirectAdmin(Context::getContext()->link->getAdminLink('AdminCarrierWizard', true, array(), array('id_carrier' => (int) $id_carrier)));
}
$this->bootstrap = true;
$this->table = 'carrier';
$this->className = 'Carrier';
$this->lang = false;
$this->deleted = true;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_defaultOrderBy = 'position';
parent::__construct();
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Notifications.Info'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Info'),
'icon' => 'icon-trash',
),
);
$this->fieldImageSettings = array(
'name' => 'logo',
'dir' => 's',
);
$this->fields_list = array(
'id_carrier' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
),
'image' => array(
'title' => $this->trans('Logo', array(), 'Admin.Global'),
'align' => 'center',
'image' => 's',
'class' => 'fixed-width-xs',
'orderby' => false,
'search' => false,
),
'delay' => array(
'title' => $this->trans('Delay', array(), 'Admin.Shipping.Feature'),
'orderby' => false,
),
'active' => array(
'title' => $this->trans('Status', array(), 'Admin.Global'),
'align' => 'center',
'active' => 'status',
'type' => 'bool',
'class' => 'fixed-width-sm',
'orderby' => false,
),
'is_free' => array(
'title' => $this->trans('Free Shipping', array(), 'Admin.Shipping.Feature'),
'align' => 'center',
'active' => 'isFree',
'type' => 'bool',
'class' => 'fixed-width-sm',
'orderby' => false,
),
'position' => array(
'title' => $this->trans('Position', array(), 'Admin.Global'),
'filter_key' => 'a!position',
'align' => 'center',
'class' => 'fixed-width-sm',
'position' => 'position',
),
);
}
public function initToolbar()
{
parent::initToolbar();
if (isset($this->toolbar_btn['new']) && $this->display != 'view') {
$this->toolbar_btn['new']['href'] = $this->context->link->getAdminLink('AdminCarrierWizard');
}
}
public function initPageHeaderToolbar()
{
$this->page_header_toolbar_title = $this->trans('Carriers', array(), 'Admin.Shipping.Feature');
if ($this->display != 'view') {
$this->page_header_toolbar_btn['new_carrier'] = array(
'href' => $this->context->link->getAdminLink('AdminCarrierWizard'),
'desc' => $this->trans('Add new carrier', array(), 'Admin.Shipping.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderList()
{
$this->_select = 'b.*';
$this->_join = 'INNER JOIN `' . _DB_PREFIX_ . 'carrier_lang` b ON a.id_carrier = b.id_carrier' . Shop::addSqlRestrictionOnLang('b') . ' AND b.id_lang = ' . (int) $this->context->language->id . ' LEFT JOIN `' . _DB_PREFIX_ . 'carrier_tax_rules_group_shop` ctrgs ON (a.`id_carrier` = ctrgs.`id_carrier` AND ctrgs.id_shop=' . (int) $this->context->shop->id . ')';
$this->_use_found_rows = false;
// Removes the Recommended modules button
unset($this->page_header_toolbar_btn['modules-list']);
// test if need to show header alert.
$sql = 'SELECT COUNT(1) FROM `' . _DB_PREFIX_ . 'carrier` WHERE deleted = 0 AND id_reference > 2';
$showHeaderAlert = (Db::getInstance()->executeS($sql, false)->fetchColumn(0) == 0);
// Assign them in two steps! Because renderModulesList needs it before to be called.
$this->context->smarty->assign('panel_title', $this->trans('Use one of our recommended carrier modules', array(), 'Admin.Shipping.Feature'));
$this->context->smarty->assign('panel_id', 'recommended-carriers-panel');
$this->context->smarty->assign(array(
'showHeaderAlert' => $showHeaderAlert,
'modules_list' => $this->renderModulesList('back-office,AdminCarriers,new'),
));
return parent::renderList();
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Carriers', array(), 'Admin.Shipping.Feature'),
'icon' => 'icon-truck',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Company', array(), 'Admin.Global'),
'name' => 'name',
'required' => true,
'hint' => array(
$this->trans('Allowed characters: letters, spaces and "%special_chars%".', array('%special_chars%' => '().-'), 'Admin.Shipping.Help'),
$this->trans('Carrier name displayed during checkout', array(), 'Admin.Shipping.Help'),
$this->trans('For in-store pickup, enter 0 to replace the carrier name with your shop name.', array(), 'Admin.Shipping.Help'),
),
),
array(
'type' => 'file',
'label' => $this->trans('Logo', array(), 'Admin.Global'),
'name' => 'logo',
'hint' => $this->trans('Upload a logo from your computer.', array(), 'Admin.Shipping.Help') . ' (.gif, .jpg, .jpeg ' . $this->trans('or', array(), 'Admin.Shipping.Help') . ' .png)',
),
array(
'type' => 'text',
'label' => $this->trans('Transit time', array(), 'Admin.Shipping.Feature'),
'name' => 'delay',
'lang' => true,
'required' => true,
'maxlength' => 512,
'hint' => $this->trans('Estimated delivery time will be displayed during checkout.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Speed grade', array(), 'Admin.Shipping.Feature'),
'name' => 'grade',
'required' => false,
'hint' => $this->trans('Enter "0" for a longest shipping delay, or "9" for the shortest shipping delay.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('URL', array(), 'Admin.Global'),
'name' => 'url',
'hint' => $this->trans('Delivery tracking URL: Type \'@\' where the tracking number should appear. It will then be automatically replaced by the tracking number.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'checkbox',
'label' => $this->trans('Zone', array(), 'Admin.Global'),
'name' => 'zone',
'values' => array(
'query' => Zone::getZones(false),
'id' => 'id_zone',
'name' => 'name',
),
'hint' => $this->trans('The zones in which this carrier will be used.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'group',
'label' => $this->trans('Group access', array(), 'Admin.Shipping.Help'),
'name' => 'groupBox',
'values' => Group::getGroups(Context::getContext()->language->id),
'hint' => $this->trans('Mark the groups that are allowed access to this carrier.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'switch',
'label' => $this->trans('Status', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
'hint' => $this->trans('Enable the carrier in the front office.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'switch',
'label' => $this->trans('Apply shipping cost', array(), 'Admin.Shipping.Feature'),
'name' => 'is_free',
'required' => false,
'class' => 't',
'values' => array(
array(
'id' => 'is_free_on',
'value' => 0,
'label' => '<img src="../img/admin/enabled.gif" alt="' . $this->trans('Yes', array(), 'Admin.Global') . '" title="' . $this->trans('Yes', array(), 'Admin.Global') . '" />',
),
array(
'id' => 'is_free_off',
'value' => 1,
'label' => '<img src="../img/admin/disabled.gif" alt="' . $this->trans('No', array(), 'Admin.Global') . '" title="' . $this->trans('No', array(), 'Admin.Global') . '" />',
),
),
'hint' => $this->trans('Apply both regular shipping cost and product-specific shipping costs.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'select',
'label' => $this->trans('Tax', array(), 'Admin.Global'),
'name' => 'id_tax_rules_group',
'options' => array(
'query' => TaxRulesGroup::getTaxRulesGroups(true),
'id' => 'id_tax_rules_group',
'name' => 'name',
'default' => array(
'label' => $this->trans('No Tax', array(), 'Admin.Global'),
'value' => 0,
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Shipping and handling', array(), 'Admin.Shipping.Feature'),
'name' => 'shipping_handling',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'shipping_handling_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'shipping_handling_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
'hint' => $this->trans('Include the shipping and handling costs in the carrier price.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'radio',
'label' => $this->trans('Billing', array(), 'Admin.Shipping.Feature'),
'name' => 'shipping_method',
'required' => false,
'class' => 't',
'br' => true,
'values' => array(
array(
'id' => 'billing_default',
'value' => Carrier::SHIPPING_METHOD_DEFAULT,
'label' => $this->trans('Default behavior', array(), 'Admin.Shipping.Feature'),
),
array(
'id' => 'billing_price',
'value' => Carrier::SHIPPING_METHOD_PRICE,
'label' => $this->trans('According to total price', array(), 'Admin.Shipping.Feature'),
),
array(
'id' => 'billing_weight',
'value' => Carrier::SHIPPING_METHOD_WEIGHT,
'label' => $this->trans('According to total weight', array(), 'Admin.Shipping.Feature'),
),
),
),
array(
'type' => 'select',
'label' => $this->trans('Out-of-range behavior', array(), 'Admin.Shipping.Feature'),
'name' => 'range_behavior',
'options' => array(
'query' => array(
array(
'id' => 0,
'name' => $this->trans('Apply the cost of the highest defined range', array(), 'Admin.Shipping.Help'),
),
array(
'id' => 1,
'name' => $this->trans('Disable carrier', array(), 'Admin.Shipping.Feature'),
),
),
'id' => 'id',
'name' => 'name',
),
'hint' => $this->trans('Out-of-range behavior occurs when none is defined (e.g. when a customer\'s cart weight is greater than the highest range limit).', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Maximum package height', array(), 'Admin.Shipping.Feature'),
'name' => 'max_height',
'required' => false,
'hint' => $this->trans('Maximum height managed by this carrier. Set the value to "0," or leave this field blank to ignore.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Maximum package width', array(), 'Admin.Shipping.Feature'),
'name' => 'max_width',
'required' => false,
'hint' => $this->trans('Maximum width managed by this carrier. Set the value to "0," or leave this field blank to ignore.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Maximum package depth', array(), 'Admin.Shipping.Feature'),
'name' => 'max_depth',
'required' => false,
'hint' => $this->trans('Maximum depth managed by this carrier. Set the value to "0," or leave this field blank to ignore.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Maximum package weight', array(), 'Admin.Shipping.Feature'),
'name' => 'max_weight',
'required' => false,
'hint' => $this->trans('Maximum weight managed by this carrier. Set the value to "0," or leave this field blank to ignore.', array(), 'Admin.Shipping.Help'),
),
array(
'type' => 'hidden',
'name' => 'is_module',
),
array(
'type' => 'hidden',
'name' => 'external_module_name',
),
array(
'type' => 'hidden',
'name' => 'shipping_external',
),
array(
'type' => 'hidden',
'name' => 'need_range',
),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$this->fields_form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
if (!($obj = $this->loadObject(true))) {
return;
}
$this->getFieldsValues($obj);
return parent::renderForm();
}
public function postProcess()
{
if (Tools::getValue('action') == 'GetModuleQuickView' && Tools::getValue('ajax') == '1') {
$this->ajaxProcessGetModuleQuickView();
}
if (Tools::getValue('submitAdd' . $this->table)) {
/* Checking fields validity */
$this->validateRules();
if (!count($this->errors)) {
$id = (int) Tools::getValue('id_' . $this->table);
/* Object update */
if (isset($id) && !empty($id)) {
try {
if ($this->access('edit')) {
$current_carrier = new Carrier($id);
if (!Validate::isLoadedObject($current_carrier)) {
throw new PrestaShopException('Cannot load Carrier object');
}
/** @var Carrier $new_carrier */
// Duplicate current Carrier
$new_carrier = $current_carrier->duplicateObject();
if (Validate::isLoadedObject($new_carrier)) {
// Set flag deteled to true for historization
$current_carrier->deleted = true;
$current_carrier->update();
// Fill the new carrier object
$this->copyFromPost($new_carrier, $this->table);
$new_carrier->position = $current_carrier->position;
$new_carrier->update();
$this->updateAssoShop($new_carrier->id);
$new_carrier->copyCarrierData((int) $current_carrier->id);
$this->changeGroups($new_carrier->id);
// Call of hooks
Hook::exec('actionCarrierUpdate', array(
'id_carrier' => (int) $current_carrier->id,
'carrier' => $new_carrier,
));
$this->postImage($new_carrier->id);
$this->changeZones($new_carrier->id);
$new_carrier->setTaxRulesGroup((int) Tools::getValue('id_tax_rules_group'));
Tools::redirectAdmin(self::$currentIndex . '&id_' . $this->table . '=' . $current_carrier->id . '&conf=4&token=' . $this->token);
} else {
$this->errors[] = $this->trans('An error occurred while updating an object.', array(), 'Admin.Notifications.Error') . ' <b>' . $this->table . '</b>';
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} catch (PrestaShopException $e) {
$this->errors[] = $e->getMessage();
}
} else {
// Object creation
if ($this->access('add')) {
// Create new Carrier
$carrier = new Carrier();
$this->copyFromPost($carrier, $this->table);
$carrier->position = Carrier::getHigherPosition() + 1;
if ($carrier->add()) {
if (($_POST['id_' . $this->table] = $carrier->id /* voluntary */) && $this->postImage($carrier->id) && $this->_redirect) {
$carrier->setTaxRulesGroup((int) Tools::getValue('id_tax_rules_group'), true);
$this->changeZones($carrier->id);
$this->changeGroups($carrier->id);
$this->updateAssoShop($carrier->id);
Tools::redirectAdmin(self::$currentIndex . '&id_' . $this->table . '=' . $carrier->id . '&conf=3&token=' . $this->token);
}
} else {
$this->errors[] = $this->trans('An error occurred while creating an object.', array(), 'Admin.Notifications.Error') . ' <b>' . $this->table . '</b>';
}
} else {
$this->errors[] = $this->trans('You do not have permission to add this.', array(), 'Admin.Notifications.Error');
}
}
}
parent::postProcess();
} elseif (isset($_GET['isFree' . $this->table])) {
if (!$this->access('edit')) {
$this->errors[] = $this->trans('You do not have permission to edit this.', [], 'Admin.Notifications.Error');
return;
}
$this->processIsFree();
} else {
// if deletion : removes the carrier from the warehouse/carrier association
if (Tools::isSubmit('delete' . $this->table)) {
$id = (int) Tools::getValue('id_' . $this->table);
// Delete from the reference_id and not from the carrier id
$carrier = new Carrier((int) $id);
Warehouse::removeCarrier($carrier->id_reference);
} elseif (Tools::isSubmit($this->table . 'Box') && count(Tools::isSubmit($this->table . 'Box')) > 0) {
$ids = Tools::getValue($this->table . 'Box');
array_walk($ids, 'intval');
foreach ($ids as $id) {
// Delete from the reference_id and not from the carrier id
$carrier = new Carrier((int) $id);
Warehouse::removeCarrier($carrier->id_reference);
}
}
parent::postProcess();
Carrier::cleanPositions();
}
}
public function processIsFree()
{
$carrier = new Carrier($this->id_object);
if (!Validate::isLoadedObject($carrier)) {
$this->errors[] = $this->trans('An error occurred while updating carrier information.', array(), 'Admin.Shipping.Notification');
}
$carrier->is_free = $carrier->is_free ? 0 : 1;
if (!$carrier->update()) {
$this->errors[] = $this->trans('An error occurred while updating carrier information.', array(), 'Admin.Shipping.Notification');
}
Tools::redirectAdmin(self::$currentIndex . '&token=' . $this->token);
}
/**
* Overload the property $fields_value.
*
* @param object $obj
*/
public function getFieldsValues($obj)
{
if ($this->getFieldValue($obj, 'is_module')) {
$this->fields_value['is_module'] = 1;
}
if ($this->getFieldValue($obj, 'shipping_external')) {
$this->fields_value['shipping_external'] = 1;
}
if ($this->getFieldValue($obj, 'need_range')) {
$this->fields_value['need_range'] = 1;
}
// Added values of object Zone
$carrier_zones = $obj->getZones();
$carrier_zones_ids = array();
if (is_array($carrier_zones)) {
foreach ($carrier_zones as $carrier_zone) {
$carrier_zones_ids[] = $carrier_zone['id_zone'];
}
}
$zones = Zone::getZones(false);
foreach ($zones as $zone) {
$this->fields_value['zone_' . $zone['id_zone']] = Tools::getValue('zone_' . $zone['id_zone'], (in_array($zone['id_zone'], $carrier_zones_ids)));
}
// Added values of object Group
$carrier_groups = $obj->getGroups();
$carrier_groups_ids = array();
if (is_array($carrier_groups)) {
foreach ($carrier_groups as $carrier_group) {
$carrier_groups_ids[] = $carrier_group['id_group'];
}
}
$groups = Group::getGroups($this->context->language->id);
foreach ($groups as $group) {
$this->fields_value['groupBox_' . $group['id_group']] = Tools::getValue('groupBox_' . $group['id_group'], (in_array($group['id_group'], $carrier_groups_ids) || empty($carrier_groups_ids) && !$obj->id));
}
$this->fields_value['id_tax_rules_group'] = $this->object->getIdTaxRulesGroup($this->context);
}
/**
* @param Carrier $object
*
* @return int
*/
protected function beforeDelete($object)
{
return $object->isUsed();
}
protected function changeGroups($id_carrier, $delete = true)
{
if ($delete) {
Db::getInstance()->execute('DELETE FROM ' . _DB_PREFIX_ . 'carrier_group WHERE id_carrier = ' . (int) $id_carrier);
}
$groups = Db::getInstance()->executeS('SELECT id_group FROM `' . _DB_PREFIX_ . 'group`');
foreach ($groups as $group) {
if (Tools::getIsset('groupBox') && in_array($group['id_group'], Tools::getValue('groupBox'))) {
Db::getInstance()->execute('
INSERT INTO ' . _DB_PREFIX_ . 'carrier_group (id_group, id_carrier)
VALUES(' . (int) $group['id_group'] . ',' . (int) $id_carrier . ')
');
}
}
}
public function changeZones($id)
{
/** @var Carrier $carrier */
$carrier = new $this->className($id);
if (!Validate::isLoadedObject($carrier)) {
die($this->trans('The object cannot be loaded.', array(), 'Admin.Notifications.Error'));
}
$zones = Zone::getZones(false);
foreach ($zones as $zone) {
if (count($carrier->getZone($zone['id_zone']))) {
if (!isset($_POST['zone_' . $zone['id_zone']]) || !$_POST['zone_' . $zone['id_zone']]) {
$carrier->deleteZone($zone['id_zone']);
}
} elseif (isset($_POST['zone_' . $zone['id_zone']]) && $_POST['zone_' . $zone['id_zone']]) {
$carrier->addZone($zone['id_zone']);
}
}
}
/**
* Modifying initial getList method to display position feature (drag and drop).
*
* @param int $id_lang
* @param string|null $order_by
* @param string|null $order_way
* @param int $start
* @param int|null $limit
* @param int|bool $id_lang_shop
*
* @throws PrestaShopException
*/
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
foreach ($this->_list as $key => $list) {
if ($list['name'] == '0') {
$this->_list[$key]['name'] = Carrier::getCarrierNameFromShopName();
}
}
}
public function ajaxProcessUpdatePositions()
{
$way = (int) (Tools::getValue('way'));
$id_carrier = (int) (Tools::getValue('id'));
$positions = Tools::getValue($this->table);
foreach ($positions as $position => $value) {
$pos = explode('_', $value);
if (isset($pos[2]) && (int) $pos[2] === $id_carrier) {
if ($carrier = new Carrier((int) $pos[2])) {
if (isset($position) && $carrier->updatePosition($way, $position)) {
echo 'ok position ' . (int) $position . ' for carrier ' . (int) $pos[1] . '\r\n';
} else {
echo '{"hasError" : true, "errors" : "Can not update carrier ' . (int) $id_carrier . ' to position ' . (int) $position . ' "}';
}
} else {
echo '{"hasError" : true, "errors" : "This carrier (' . (int) $id_carrier . ') can t be loaded"}';
}
break;
}
}
}
public function displayEditLink($token, $id, $name = null)
{
if ($this->access('edit')) {
$tpl = $this->createTemplate('helpers/list/list_action_edit.tpl');
if (!array_key_exists('Edit', self::$cache_lang)) {
self::$cache_lang['Edit'] = $this->trans('Edit', array(), 'Admin.Actions');
}
$tpl->assign(array(
'href' => $this->context->link->getAdminLink('AdminCarrierWizard', true, array(), array('id_carrier' => (int) $id)),
'action' => self::$cache_lang['Edit'],
'id' => $id,
));
return $tpl->fetch();
} else {
return;
}
}
public function displayDeleteLink($token, $id, $name = null)
{
if ($this->access('delete')) {
$tpl = $this->createTemplate('helpers/list/list_action_delete.tpl');
if (!array_key_exists('Delete', self::$cache_lang)) {
self::$cache_lang['Delete'] = $this->trans('Delete', array(), 'Admin.Actions');
}
if (!array_key_exists('DeleteItem', self::$cache_lang)) {
self::$cache_lang['DeleteItem'] = $this->trans('Delete selected item?', array(), 'Admin.Notifications.Info');
}
if (!array_key_exists('Name', self::$cache_lang)) {
self::$cache_lang['Name'] = $this->trans('Name:', array(), 'Admin.Shipping.Feature');
}
if (null !== $name) {
$name = '\n\n' . self::$cache_lang['Name'] . ' ' . $name;
}
$data = array(
$this->identifier => $id,
'href' => $this->context->link->getAdminLink('AdminCarriers', true, array(), array('id_carrier' => (int) $id, 'deletecarrier' => 1)),
'action' => self::$cache_lang['Delete'],
);
if ($this->specificConfirmDelete !== false) {
$data['confirm'] = null !== $this->specificConfirmDelete ? '\r' . $this->specificConfirmDelete : addcslashes(Tools::htmlentitiesDecodeUTF8(self::$cache_lang['DeleteItem'] . $name), '\'');
}
$tpl->assign(array_merge($this->tpl_delete_link_vars, $data));
return $tpl->fetch();
} else {
return;
}
}
protected function initTabModuleList()
{
parent::initTabModuleList();
$this->filter_modules_list = $this->tab_modules_list['default_list'] = $this->tab_modules_list['slider_list'];
}
}

View File

@@ -0,0 +1,734 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property CartRule $object
*/
class AdminCartRulesControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'cart_rule';
$this->className = 'CartRule';
$this->lang = true;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_orderWay = 'DESC';
parent::__construct();
$this->bulk_actions = array('delete' => array('text' => $this->trans('Delete selected', array(), 'Admin.Actions'), 'icon' => 'icon-trash', 'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning')));
$this->fields_list = array(
'id_cart_rule' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'align' => 'center', 'class' => 'fixed-width-xs'),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global')),
'priority' => array('title' => $this->trans('Priority', array(), 'Admin.Global'), 'align' => 'center', 'class' => 'fixed-width-xs'),
'code' => array('title' => $this->trans('Code', array(), 'Admin.Global'), 'class' => 'fixed-width-sm'),
'quantity' => array('title' => $this->trans('Quantity', array(), 'Admin.Catalog.Feature'), 'align' => 'center', 'class' => 'fixed-width-xs'),
'date_to' => array('title' => $this->trans('Expiration date', array(), 'Admin.Catalog.Feature'), 'type' => 'datetime', 'class' => 'fixed-width-lg'),
'active' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'active' => 'status', 'type' => 'bool', 'align' => 'center', 'class' => 'fixed-width-xs', 'orderby' => false),
);
}
public function ajaxProcessLoadCartRules()
{
if (!$this->access('view')) {
return die(json_encode(array('error' => 'You do not have the right permission')));
}
$type = $token = $search = '';
$limit = $count = $id_cart_rule = 0;
if (Tools::getIsset('limit')) {
$limit = Tools::getValue('limit');
}
if (Tools::getIsset('type')) {
$type = Tools::getValue('type');
}
if (Tools::getIsset('count')) {
$count = Tools::getValue('count');
}
if (Tools::getIsset('id_cart_rule')) {
$id_cart_rule = Tools::getValue('id_cart_rule');
}
if (Tools::getIsset('search')) {
$search = Tools::getValue('search');
}
$page = floor($count / $limit);
$html = '';
$next_link = '';
if (($page * $limit) + 1 == $count || $count == 0) {
if ($count == 0) {
$count = 1;
}
/** @var CartRule $current_object */
$current_object = $this->loadObject(true);
$cart_rules = $current_object->getAssociatedRestrictions('cart_rule', false, true, ($page) * $limit, $limit, $search);
if ($type == 'selected') {
$i = 1;
foreach ($cart_rules['selected'] as $cart_rule) {
$html .= '<option value="' . (int) $cart_rule['id_cart_rule'] . '">&nbsp;' . Tools::safeOutput($cart_rule['name']) . '</option>';
if ($i == $limit) {
break;
}
++$i;
}
if ($i == $limit) {
$next_link = Context::getContext()->link->getAdminLink('AdminCartRules') . '&ajaxMode=1&ajax=1&id_cart_rule=' . (int) $id_cart_rule . '&action=loadCartRules&limit=' . (int) $limit . '&type=selected&count=' . ($count - 1 + count($cart_rules['selected']) . '&search=' . urlencode($search));
}
} else {
$i = 1;
foreach ($cart_rules['unselected'] as $cart_rule) {
$html .= '<option value="' . (int) $cart_rule['id_cart_rule'] . '">&nbsp;' . Tools::safeOutput($cart_rule['name']) . '</option>';
if ($i == $limit) {
break;
}
++$i;
}
if ($i == $limit) {
$next_link = Context::getContext()->link->getAdminLink('AdminCartRules') . '&ajaxMode=1&ajax=1&id_cart_rule=' . (int) $id_cart_rule . '&action=loadCartRules&limit=' . (int) $limit . '&type=unselected&count=' . ($count - 1 + count($cart_rules['unselected']) . '&search=' . urlencode($search));
}
}
}
echo json_encode(array('html' => $html, 'next_link' => $next_link));
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryPlugin(array('typewatch', 'fancybox', 'autocomplete'));
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_cart_rule'] = array(
'href' => self::$currentIndex . '&addcart_rule&token=' . $this->token,
'desc' => $this->trans('Add new cart rule', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function postProcess()
{
if (Tools::isSubmit('submitAddcart_rule') || Tools::isSubmit('submitAddcart_ruleAndStay')) {
// If the reduction is associated to a specific product, then it must be part of the product restrictions
if ((int) Tools::getValue('reduction_product') && Tools::getValue('apply_discount_to') == 'specific' && Tools::getValue('apply_discount') != 'off') {
$reduction_product = (int) Tools::getValue('reduction_product');
// First, check if it is not already part of the restrictions
$already_restricted = false;
if (is_array($rule_group_array = Tools::getValue('product_rule_group')) && count($rule_group_array) && Tools::getValue('product_restriction')) {
foreach ($rule_group_array as $rule_group_id) {
if (is_array($rule_array = Tools::getValue('product_rule_' . $rule_group_id)) && count($rule_array)) {
foreach ($rule_array as $rule_id) {
if (Tools::getValue('product_rule_' . $rule_group_id . '_' . $rule_id . '_type') == 'products'
&& in_array($reduction_product, Tools::getValue('product_rule_select_' . $rule_group_id . '_' . $rule_id))) {
$already_restricted = true;
break 2;
}
}
}
}
}
if ($already_restricted == false) {
// Check the product restriction
$_POST['product_restriction'] = 1;
// Add a new rule group
$rule_group_id = 1;
if (is_array($rule_group_array)) {
// Empty for (with a ; at the end), that just find the first rule_group_id available in rule_group_array
for ($rule_group_id = 1; in_array($rule_group_id, $rule_group_array); ++$rule_group_id) {
42;
}
$_POST['product_rule_group'][] = $rule_group_id;
} else {
$_POST['product_rule_group'] = array($rule_group_id);
}
// Set a quantity of 1 for this new rule group
$_POST['product_rule_group_' . $rule_group_id . '_quantity'] = 1;
// Add one rule to the new rule group
$_POST['product_rule_' . $rule_group_id] = array(1);
// Set a type 'product' for this 1 rule
$_POST['product_rule_' . $rule_group_id . '_1_type'] = 'products';
// Add the product in the selected products
$_POST['product_rule_select_' . $rule_group_id . '_1'] = array($reduction_product);
}
}
// These are checkboxes (which aren't sent through POST when they are not check), so they are forced to 0
foreach (array('country', 'carrier', 'group', 'cart_rule', 'product', 'shop') as $type) {
if (!Tools::getValue($type . '_restriction')) {
$_POST[$type . '_restriction'] = 0;
}
}
// Remove the gift if the radio button is set to "no"
if (!(int) Tools::getValue('free_gift')) {
$_POST['gift_product'] = 0;
}
// Retrieve the product attribute id of the gift (if available)
if ($id_product = (int) Tools::getValue('gift_product')) {
$_POST['gift_product_attribute'] = (int) Tools::getValue('ipa_' . $id_product);
}
// Idiot-proof control
if (strtotime(Tools::getValue('date_from')) > strtotime(Tools::getValue('date_to'))) {
$this->errors[] = $this->trans('The voucher cannot end before it begins.', array(), 'Admin.Catalog.Notification');
}
if ((int) Tools::getValue('minimum_amount') < 0) {
$this->errors[] = $this->trans('The minimum amount cannot be lower than zero.', array(), 'Admin.Catalog.Notification');
}
if ((float) Tools::getValue('reduction_percent') < 0 || (float) Tools::getValue('reduction_percent') > 100) {
$this->errors[] = $this->trans('Reduction percentage must be between 0% and 100%', array(), 'Admin.Catalog.Notification');
}
if ((int) Tools::getValue('reduction_amount') < 0) {
$this->errors[] = $this->trans('Reduction amount cannot be lower than zero.', array(), 'Admin.Catalog.Notification');
}
if (Tools::getValue('code') && ($same_code = (int) CartRule::getIdByCode(Tools::getValue('code'))) && $same_code != Tools::getValue('id_cart_rule')) {
$this->errors[] = $this->trans('This cart rule code is already used (conflict with cart rule %rulename%)', array('%rulename%' => $same_code), 'Admin.Catalog.Notification');
}
if (Tools::getValue('apply_discount') == 'off' && !Tools::getValue('free_shipping') && !Tools::getValue('free_gift')) {
$this->errors[] = $this->trans('An action is required for this cart rule.', array(), 'Admin.Catalog.Notification');
}
}
return parent::postProcess();
}
public function processDelete()
{
$res = parent::processDelete();
if (Tools::isSubmit('delete' . $this->table)) {
$back = urldecode(Tools::getValue('back', ''));
if (!empty($back)) {
$this->redirect_after = $back;
}
}
return $res;
}
protected function afterUpdate($current_object)
{
// All the associations are deleted for an update, then recreated when we call the "afterAdd" method
$id_cart_rule = Tools::getValue('id_cart_rule');
foreach (array('country', 'carrier', 'group', 'product_rule_group', 'shop') as $type) {
Db::getInstance()->delete('cart_rule_' . $type, '`id_cart_rule` = ' . (int) $id_cart_rule);
}
Db::getInstance()->delete('cart_rule_product_rule', 'NOT EXISTS (SELECT 1 FROM `' . _DB_PREFIX_ . 'cart_rule_product_rule_group`
WHERE `' . _DB_PREFIX_ . 'cart_rule_product_rule`.`id_product_rule_group` = `' . _DB_PREFIX_ . 'cart_rule_product_rule_group`.`id_product_rule_group`)');
Db::getInstance()->delete('cart_rule_product_rule_value', 'NOT EXISTS (SELECT 1 FROM `' . _DB_PREFIX_ . 'cart_rule_product_rule`
WHERE `' . _DB_PREFIX_ . 'cart_rule_product_rule_value`.`id_product_rule` = `' . _DB_PREFIX_ . 'cart_rule_product_rule`.`id_product_rule`)');
Db::getInstance()->delete('cart_rule_combination', '`id_cart_rule_1` = ' . (int) $id_cart_rule . ' OR `id_cart_rule_2` = ' . (int) $id_cart_rule);
$this->afterAdd($current_object);
}
public function processAdd()
{
if ($cart_rule = parent::processAdd()) {
$this->context->smarty->assign('new_cart_rule', $cart_rule);
}
if (Tools::getValue('submitFormAjax')) {
$this->redirect_after = false;
}
return $cart_rule;
}
/**
* @TODO Move this function into CartRule
*
* @param ObjectModel $currentObject
*
* @throws PrestaShopDatabaseException
*/
protected function afterAdd($currentObject)
{
// Add restrictions for generic entities like country, carrier and group
foreach (array('country', 'carrier', 'group', 'shop') as $type) {
if (Tools::getValue($type . '_restriction') && is_array($array = Tools::getValue($type . '_select')) && count($array)) {
$values = array();
foreach ($array as $id) {
$values[] = '(' . (int) $currentObject->id . ',' . (int) $id . ')';
}
Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'cart_rule_' . $type . '` (`id_cart_rule`, `id_' . $type . '`) VALUES ' . implode(',', $values));
}
}
// Add cart rule restrictions
if (Tools::getValue('cart_rule_restriction') && is_array($array = Tools::getValue('cart_rule_select')) && count($array)) {
$values = array();
foreach ($array as $id) {
$values[] = '(' . (int) $currentObject->id . ',' . (int) $id . ')';
}
Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'cart_rule_combination` (`id_cart_rule_1`, `id_cart_rule_2`) VALUES ' . implode(',', $values));
}
// Add product rule restrictions
if (Tools::getValue('product_restriction') && is_array($ruleGroupArray = Tools::getValue('product_rule_group')) && count($ruleGroupArray)) {
foreach ($ruleGroupArray as $ruleGroupId) {
Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'cart_rule_product_rule_group` (`id_cart_rule`, `quantity`)
VALUES (' . (int) $currentObject->id . ', ' . (int) Tools::getValue('product_rule_group_' . $ruleGroupId . '_quantity') . ')');
$id_product_rule_group = Db::getInstance()->Insert_ID();
if (is_array($ruleArray = Tools::getValue('product_rule_' . $ruleGroupId)) && count($ruleArray)) {
foreach ($ruleArray as $ruleId) {
Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'cart_rule_product_rule` (`id_product_rule_group`, `type`)
VALUES (' . (int) $id_product_rule_group . ', "' . pSQL(Tools::getValue('product_rule_' . $ruleGroupId . '_' . $ruleId . '_type')) . '")');
$id_product_rule = Db::getInstance()->Insert_ID();
$values = array();
foreach (Tools::getValue('product_rule_select_' . $ruleGroupId . '_' . $ruleId) as $id) {
$values[] = '(' . (int) $id_product_rule . ',' . (int) $id . ')';
}
$values = array_unique($values);
if (count($values)) {
Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'cart_rule_product_rule_value` (`id_product_rule`, `id_item`) VALUES ' . implode(',', $values));
}
}
}
}
}
// If the new rule has no cart rule restriction, then it must be added to the white list of the other cart rules that have restrictions
if (!Tools::getValue('cart_rule_restriction')) {
Db::getInstance()->execute('
INSERT INTO `' . _DB_PREFIX_ . 'cart_rule_combination` (`id_cart_rule_1`, `id_cart_rule_2`) (
SELECT id_cart_rule, ' . (int) $currentObject->id . ' FROM `' . _DB_PREFIX_ . 'cart_rule` WHERE cart_rule_restriction = 1
)');
} else {
// And if the new cart rule has restrictions, previously unrestricted cart rules may now be restricted (a mug of coffee is strongly advised to understand this sentence)
$ruleCombinations = Db::getInstance()->executeS('
SELECT cr.id_cart_rule
FROM ' . _DB_PREFIX_ . 'cart_rule cr
WHERE cr.id_cart_rule != ' . (int) $currentObject->id . '
AND cr.cart_rule_restriction = 0
AND NOT EXISTS (
SELECT 1
FROM ' . _DB_PREFIX_ . 'cart_rule_combination
WHERE cr.id_cart_rule = ' . _DB_PREFIX_ . 'cart_rule_combination.id_cart_rule_2 AND ' . (int) $currentObject->id . ' = id_cart_rule_1
)
AND NOT EXISTS (
SELECT 1
FROM ' . _DB_PREFIX_ . 'cart_rule_combination
WHERE cr.id_cart_rule = ' . _DB_PREFIX_ . 'cart_rule_combination.id_cart_rule_1 AND ' . (int) $currentObject->id . ' = id_cart_rule_2
)
');
foreach ($ruleCombinations as $incompatibleRule) {
Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'cart_rule` SET cart_rule_restriction = 1 WHERE id_cart_rule = ' . (int) $incompatibleRule['id_cart_rule'] . ' LIMIT 1');
Db::getInstance()->execute('
INSERT IGNORE INTO `' . _DB_PREFIX_ . 'cart_rule_combination` (`id_cart_rule_1`, `id_cart_rule_2`) (
SELECT id_cart_rule, ' . (int) $incompatibleRule['id_cart_rule'] . ' FROM `' . _DB_PREFIX_ . 'cart_rule`
WHERE active = 1
AND id_cart_rule != ' . (int) $currentObject->id . '
AND id_cart_rule != ' . (int) $incompatibleRule['id_cart_rule'] . '
)');
}
}
}
/**
* Retrieve the cart rule product rule groups in the POST data
* if available, and in the database if there is none.
*
* @param CartRule $cart_rule
*
* @return array
*/
public function getProductRuleGroupsDisplay($cart_rule)
{
$productRuleGroupsArray = array();
if (Tools::getValue('product_restriction') && is_array($array = Tools::getValue('product_rule_group')) && count($array)) {
$i = 1;
foreach ($array as $ruleGroupId) {
$productRulesArray = array();
if (is_array($array = Tools::getValue('product_rule_' . $ruleGroupId)) && count($array)) {
foreach ($array as $ruleId) {
$productRulesArray[] = $this->getProductRuleDisplay(
$ruleGroupId,
$ruleId,
Tools::getValue('product_rule_' . $ruleGroupId . '_' . $ruleId . '_type'),
Tools::getValue('product_rule_select_' . $ruleGroupId . '_' . $ruleId)
);
}
}
$productRuleGroupsArray[] = $this->getProductRuleGroupDisplay(
$i++,
(int) Tools::getValue('product_rule_group_' . $ruleGroupId . '_quantity'),
$productRulesArray
);
}
} else {
$i = 1;
foreach ($cart_rule->getProductRuleGroups() as $productRuleGroup) {
$j = 1;
$productRulesDisplay = array();
foreach ($productRuleGroup['product_rules'] as $productRule) {
$productRulesDisplay[] = $this->getProductRuleDisplay($i, $j++, $productRule['type'], $productRule['values']);
}
$productRuleGroupsArray[] = $this->getProductRuleGroupDisplay($i++, $productRuleGroup['quantity'], $productRulesDisplay);
}
}
return $productRuleGroupsArray;
}
/* Return the form for a single cart rule group either with or without product_rules set up */
public function getProductRuleGroupDisplay($product_rule_group_id, $product_rule_group_quantity = 1, $product_rules = null)
{
Context::getContext()->smarty->assign('product_rule_group_id', $product_rule_group_id);
Context::getContext()->smarty->assign('product_rule_group_quantity', $product_rule_group_quantity);
Context::getContext()->smarty->assign('product_rules', $product_rules);
return $this->createTemplate('product_rule_group.tpl')->fetch();
}
public function getProductRuleDisplay($product_rule_group_id, $product_rule_id, $product_rule_type, $selected = array())
{
Context::getContext()->smarty->assign(
array(
'product_rule_group_id' => (int) $product_rule_group_id,
'product_rule_id' => (int) $product_rule_id,
'product_rule_type' => $product_rule_type,
)
);
switch ($product_rule_type) {
case 'attributes':
$attributes = array('selected' => array(), 'unselected' => array());
$results = Db::getInstance()->executeS('
SELECT CONCAT(agl.name, " - ", al.name) as name, a.id_attribute as id
FROM ' . _DB_PREFIX_ . 'attribute_group_lang agl
LEFT JOIN ' . _DB_PREFIX_ . 'attribute a ON a.id_attribute_group = agl.id_attribute_group
LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang al ON (a.id_attribute = al.id_attribute AND al.id_lang = ' . (int) Context::getContext()->language->id . ')
WHERE agl.id_lang = ' . (int) Context::getContext()->language->id . '
ORDER BY agl.name, al.name');
foreach ($results as $row) {
$attributes[in_array($row['id'], $selected) ? 'selected' : 'unselected'][] = $row;
}
Context::getContext()->smarty->assign('product_rule_itemlist', $attributes);
$choose_content = $this->createTemplate('controllers/cart_rules/product_rule_itemlist.tpl')->fetch();
Context::getContext()->smarty->assign('product_rule_choose_content', $choose_content);
break;
case 'products':
$products = array('selected' => array(), 'unselected' => array());
$results = Db::getInstance()->executeS('
SELECT DISTINCT name, p.id_product as id
FROM ' . _DB_PREFIX_ . 'product p
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl
ON (p.`id_product` = pl.`id_product`
AND pl.`id_lang` = ' . (int) Context::getContext()->language->id . Shop::addSqlRestrictionOnLang('pl') . ')
' . Shop::addSqlAssociation('product', 'p') . '
WHERE id_lang = ' . (int) Context::getContext()->language->id . '
ORDER BY name');
foreach ($results as $row) {
$products[in_array($row['id'], $selected) ? 'selected' : 'unselected'][] = $row;
}
Context::getContext()->smarty->assign('product_rule_itemlist', $products);
$choose_content = $this->createTemplate('product_rule_itemlist.tpl')->fetch();
Context::getContext()->smarty->assign('product_rule_choose_content', $choose_content);
break;
case 'manufacturers':
$products = array('selected' => array(), 'unselected' => array());
$results = Db::getInstance()->executeS('
SELECT name, id_manufacturer as id
FROM ' . _DB_PREFIX_ . 'manufacturer
ORDER BY name');
foreach ($results as $row) {
$products[in_array($row['id'], $selected) ? 'selected' : 'unselected'][] = $row;
}
Context::getContext()->smarty->assign('product_rule_itemlist', $products);
$choose_content = $this->createTemplate('product_rule_itemlist.tpl')->fetch();
Context::getContext()->smarty->assign('product_rule_choose_content', $choose_content);
break;
case 'suppliers':
$products = array('selected' => array(), 'unselected' => array());
$results = Db::getInstance()->executeS('
SELECT name, id_supplier as id
FROM ' . _DB_PREFIX_ . 'supplier
ORDER BY name');
foreach ($results as $row) {
$products[in_array($row['id'], $selected) ? 'selected' : 'unselected'][] = $row;
}
Context::getContext()->smarty->assign('product_rule_itemlist', $products);
$choose_content = $this->createTemplate('product_rule_itemlist.tpl')->fetch();
Context::getContext()->smarty->assign('product_rule_choose_content', $choose_content);
break;
case 'categories':
$categories = array('selected' => array(), 'unselected' => array());
$results = Db::getInstance()->executeS('
SELECT DISTINCT name, c.id_category as id
FROM ' . _DB_PREFIX_ . 'category c
LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl
ON (c.`id_category` = cl.`id_category`
AND cl.`id_lang` = ' . (int) Context::getContext()->language->id . Shop::addSqlRestrictionOnLang('cl') . ')
' . Shop::addSqlAssociation('category', 'c') . '
WHERE id_lang = ' . (int) Context::getContext()->language->id . '
ORDER BY name');
foreach ($results as $row) {
$categories[in_array($row['id'], $selected) ? 'selected' : 'unselected'][] = $row;
}
Context::getContext()->smarty->assign('product_rule_itemlist', $categories);
$choose_content = $this->createTemplate('product_rule_itemlist.tpl')->fetch();
Context::getContext()->smarty->assign('product_rule_choose_content', $choose_content);
break;
default:
Context::getContext()->smarty->assign('product_rule_itemlist', array('selected' => array(), 'unselected' => array()));
Context::getContext()->smarty->assign('product_rule_choose_content', '');
}
return $this->createTemplate('product_rule.tpl')->fetch();
}
public function ajaxProcess()
{
if (Tools::isSubmit('newProductRule')) {
die($this->getProductRuleDisplay(Tools::getValue('product_rule_group_id'), Tools::getValue('product_rule_id'), Tools::getValue('product_rule_type')));
}
if (Tools::isSubmit('newProductRuleGroup') && $product_rule_group_id = Tools::getValue('product_rule_group_id')) {
die($this->getProductRuleGroupDisplay($product_rule_group_id, Tools::getValue('product_rule_group_' . $product_rule_group_id . '_quantity', 1)));
}
if (Tools::isSubmit('customerFilter')) {
$search_query = trim(Tools::getValue('q'));
$customers = Db::getInstance()->executeS('
SELECT `id_customer`, `email`, CONCAT(`firstname`, \' \', `lastname`) as cname
FROM `' . _DB_PREFIX_ . 'customer`
WHERE `deleted` = 0 AND is_guest = 0 AND active = 1
AND (
`id_customer` = ' . (int) $search_query . '
OR `email` LIKE "%' . pSQL($search_query) . '%"
OR `firstname` LIKE "%' . pSQL($search_query) . '%"
OR `lastname` LIKE "%' . pSQL($search_query) . '%"
)
' . Shop::addSqlRestriction(Shop::SHARE_CUSTOMER) . '
ORDER BY `firstname`, `lastname` ASC
LIMIT 50');
die(json_encode($customers));
}
// Both product filter (free product and product discount) search for products
if (Tools::isSubmit('giftProductFilter') || Tools::isSubmit('reductionProductFilter')) {
$products = Product::searchByName(Context::getContext()->language->id, trim(Tools::getValue('q')));
die(json_encode($products));
}
}
protected function searchProducts($search)
{
if ($products = Product::searchByName((int) $this->context->language->id, $search)) {
foreach ($products as &$product) {
$combinations = array();
$productObj = new Product((int) $product['id_product'], false, (int) $this->context->language->id);
$attributes = $productObj->getAttributesGroups((int) $this->context->language->id);
$product['formatted_price'] = Tools::displayPrice(Tools::convertPrice($product['price_tax_incl'], $this->context->currency), $this->context->currency);
foreach ($attributes as $attribute) {
if (!isset($combinations[$attribute['id_product_attribute']]['attributes'])) {
$combinations[$attribute['id_product_attribute']]['attributes'] = '';
}
$combinations[$attribute['id_product_attribute']]['attributes'] .= $attribute['attribute_name'] . ' - ';
$combinations[$attribute['id_product_attribute']]['id_product_attribute'] = $attribute['id_product_attribute'];
$combinations[$attribute['id_product_attribute']]['default_on'] = $attribute['default_on'];
if (!isset($combinations[$attribute['id_product_attribute']]['price'])) {
$price_tax_incl = Product::getPriceStatic((int) $product['id_product'], true, $attribute['id_product_attribute']);
$combinations[$attribute['id_product_attribute']]['formatted_price'] = Tools::displayPrice(Tools::convertPrice($price_tax_incl, $this->context->currency), $this->context->currency);
}
}
foreach ($combinations as &$combination) {
$combination['attributes'] = rtrim($combination['attributes'], ' - ');
}
$product['combinations'] = $combinations;
}
return array(
'products' => $products,
'found' => true,
);
} else {
return array('found' => false, 'notfound' => $this->trans('No product has been found.', array(), 'Admin.Catalog.Notification'));
}
}
public function ajaxProcessSearchProducts()
{
$array = $this->searchProducts(Tools::getValue('product_search'));
$this->content = trim(json_encode($array));
}
public function renderForm()
{
$limit = 40;
$this->toolbar_btn['save-and-stay'] = array(
'href' => '#',
'desc' => $this->trans('Save and stay', array(), 'Admin.Actions'),
);
/** @var CartRule $current_object */
$current_object = $this->loadObject(true);
// All the filter are prefilled with the correct information
$customer_filter = '';
if (Validate::isUnsignedId($current_object->id_customer) &&
($customer = new Customer($current_object->id_customer)) &&
Validate::isLoadedObject($customer)) {
$customer_filter = $customer->firstname . ' ' . $customer->lastname . ' (' . $customer->email . ')';
}
$gift_product_filter = '';
if (Validate::isUnsignedId($current_object->gift_product) &&
($product = new Product($current_object->gift_product, false, $this->context->language->id)) &&
Validate::isLoadedObject($product)) {
$gift_product_filter = (!empty($product->reference) ? $product->reference : $product->name);
}
$reduction_product_filter = '';
if (Validate::isUnsignedId($current_object->reduction_product) &&
($product = new Product($current_object->reduction_product, false, $this->context->language->id)) &&
Validate::isLoadedObject($product)) {
$reduction_product_filter = (!empty($product->reference) ? $product->reference : $product->name);
}
$product_rule_groups = $this->getProductRuleGroupsDisplay($current_object);
$attribute_groups = AttributeGroup::getAttributesGroups($this->context->language->id);
$currencies = Currency::getCurrencies(false, true, true);
$languages = Language::getLanguages();
$countries = $current_object->getAssociatedRestrictions('country', true, true);
$groups = $current_object->getAssociatedRestrictions('group', false, true);
$shops = $current_object->getAssociatedRestrictions('shop', false, false);
$cart_rules = $current_object->getAssociatedRestrictions('cart_rule', false, true, 0, $limit);
$carriers = $current_object->getAssociatedRestrictions('carrier', true, false);
foreach ($carriers as &$carriers2) {
foreach ($carriers2 as &$carrier) {
foreach ($carrier as $field => &$value) {
if ($field == 'name' && $value == '0') {
$value = Configuration::get('PS_SHOP_NAME');
}
}
}
}
$gift_product_select = '';
$gift_product_attribute_select = '';
if ((int) $current_object->gift_product) {
$search_products = $this->searchProducts($gift_product_filter);
if (isset($search_products['products']) && is_array($search_products['products'])) {
foreach ($search_products['products'] as $product) {
$gift_product_select .= '
<option value="' . $product['id_product'] . '" ' . ($product['id_product'] == $current_object->gift_product ? 'selected="selected"' : '') . '>
' . $product['name'] . (count($product['combinations']) == 0 ? ' - ' . $product['formatted_price'] : '') . '
</option>';
if (count($product['combinations'])) {
$gift_product_attribute_select .= '<select class="control-form id_product_attribute" id="ipa_' . $product['id_product'] . '" name="ipa_' . $product['id_product'] . '">';
foreach ($product['combinations'] as $combination) {
$gift_product_attribute_select .= '
<option ' . ($combination['id_product_attribute'] == $current_object->gift_product_attribute ? 'selected="selected"' : '') . ' value="' . $combination['id_product_attribute'] . '">
' . $combination['attributes'] . ' - ' . $combination['formatted_price'] . '
</option>';
}
$gift_product_attribute_select .= '</select>';
}
}
}
}
$product = new Product($current_object->gift_product);
$this->context->smarty->assign(
array(
'show_toolbar' => true,
'toolbar_btn' => $this->toolbar_btn,
'toolbar_scroll' => $this->toolbar_scroll,
'title' => array($this->trans('Payment: ', array(), 'Admin.Catalog.Feature'), $this->trans('Cart Rules', array(), 'Admin.Catalog.Feature')),
'defaultDateFrom' => date('Y-m-d H:00:00'),
'defaultDateTo' => date('Y-m-d H:00:00', strtotime('+1 month')),
'customerFilter' => $customer_filter,
'giftProductFilter' => $gift_product_filter,
'gift_product_select' => $gift_product_select,
'gift_product_attribute_select' => $gift_product_attribute_select,
'reductionProductFilter' => $reduction_product_filter,
'defaultCurrency' => Configuration::get('PS_CURRENCY_DEFAULT'),
'id_lang_default' => Configuration::get('PS_LANG_DEFAULT'),
'languages' => $languages,
'currencies' => $currencies,
'countries' => $countries,
'carriers' => $carriers,
'groups' => $groups,
'shops' => $shops,
'cart_rules' => $cart_rules,
'product_rule_groups' => $product_rule_groups,
'product_rule_groups_counter' => count($product_rule_groups),
'attribute_groups' => $attribute_groups,
'currentIndex' => self::$currentIndex,
'currentToken' => $this->token,
'currentObject' => $current_object,
'currentTab' => $this,
'hasAttribute' => $product->hasAttributes(),
)
);
Media::addJsDef(array('baseHref' => $this->context->link->getAdminLink('AdminCartRules') . '&ajaxMode=1&ajax=1&id_cart_rule=' .
(int) Tools::getValue('id_cart_rule') . '&action=loadCartRules&limit=' . (int) $limit . '&count=0', ));
$this->content .= $this->createTemplate('form.tpl')->fetch();
$this->addJqueryUI('ui.datepicker');
$this->addJqueryPlugin(array('jscroll', 'typewatch'));
return parent::renderForm();
}
public function displayAjaxSearchCartRuleVouchers()
{
$found = false;
if ($vouchers = CartRule::getCartsRuleByCode(Tools::getValue('q'), (int) $this->context->language->id, true)) {
$found = true;
}
echo json_encode(array('found' => $found, 'vouchers' => $vouchers));
}
}

View File

@@ -0,0 +1,961 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Cart $object
*/
class AdminCartsControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'cart';
$this->className = 'Cart';
$this->lang = false;
$this->explicitSelect = true;
parent::__construct();
$this->addRowAction('view');
$this->addRowAction('delete');
$this->allow_export = true;
$this->_orderWay = 'DESC';
$this->_select = 'CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) `customer`, a.id_cart total, ca.name carrier, o.id_order,
IF (IFNULL(o.id_order, \'' . $this->trans('Non ordered', array(), 'Admin.Orderscustomers.Feature') . '\') = \'' . $this->trans('Non ordered', array(), 'Admin.Orderscustomers.Feature') . '\', IF(TIME_TO_SEC(TIMEDIFF(\'' . pSQL(date('Y-m-d H:i:00', time())) . '\', a.`date_add`)) > 86400, \'' . $this->trans('Abandoned cart', array(), 'Admin.Orderscustomers.Feature') . '\', \'' . $this->trans('Non ordered', array(), 'Admin.Orderscustomers.Feature') . '\'), o.id_order) AS status, IF(o.id_order, 1, 0) badge_success, IF(o.id_order, 0, 1) badge_danger, IF(co.id_guest, 1, 0) id_guest';
$this->_join = 'LEFT JOIN ' . _DB_PREFIX_ . 'customer c ON (c.id_customer = a.id_customer)
LEFT JOIN ' . _DB_PREFIX_ . 'currency cu ON (cu.id_currency = a.id_currency)
LEFT JOIN ' . _DB_PREFIX_ . 'carrier ca ON (ca.id_carrier = a.id_carrier)
LEFT JOIN ' . _DB_PREFIX_ . 'orders o ON (o.id_cart = a.id_cart)
LEFT JOIN (
SELECT `id_guest`
FROM `' . _DB_PREFIX_ . 'connections`
WHERE
TIME_TO_SEC(TIMEDIFF(\'' . pSQL(date('Y-m-d H:i:00', time())) . '\', `date_add`)) < 1800
LIMIT 1
) AS co ON co.`id_guest` = a.`id_guest`';
if (Tools::getValue('action') && Tools::getValue('action') == 'filterOnlyAbandonedCarts') {
$this->_having = 'status = \'' . $this->trans('Abandoned cart', array(), 'Admin.Orderscustomers.Feature') . '\'';
} else {
$this->_use_found_rows = false;
}
$this->fields_list = array(
'id_cart' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'text-center',
'class' => 'fixed-width-xs',
),
'status' => array(
'title' => $this->trans('Order ID', array(), 'Admin.Orderscustomers.Feature'),
'align' => 'text-center',
'badge_danger' => true,
'havingFilter' => true,
),
'customer' => array(
'title' => $this->trans('Customer', array(), 'Admin.Global'),
'filter_key' => 'c!lastname',
),
'total' => array(
'title' => $this->trans('Total', array(), 'Admin.Global'),
'callback' => 'getOrderTotalUsingTaxCalculationMethod',
'orderby' => false,
'search' => false,
'align' => 'text-right',
'badge_success' => true,
),
'carrier' => array(
'title' => $this->trans('Carrier', array(), 'Admin.Shipping.Feature'),
'align' => 'text-left',
'callback' => 'replaceZeroByShopName',
'filter_key' => 'ca!name',
),
'date_add' => array(
'title' => $this->trans('Date', array(), 'Admin.Global'),
'align' => 'text-left',
'type' => 'datetime',
'class' => 'fixed-width-lg',
'filter_key' => 'a!date_add',
),
);
if (Configuration::get('PS_GUEST_CHECKOUT_ENABLED')) {
$this->fields_list['id_guest'] = array(
'title' => $this->trans('Online', array(), 'Admin.Global'),
'align' => 'text-center',
'type' => 'bool',
'havingFilter' => true,
'class' => 'fixed-width-xs',
);
}
$this->shopLinkType = 'shop';
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['export_cart'] = array(
'href' => self::$currentIndex . '&exportcart&token=' . $this->token,
'desc' => $this->trans('Export carts', array(), 'Admin.Orderscustomers.Feature'),
'icon' => 'process-icon-export',
);
}
parent::initPageHeaderToolbar();
}
public function renderKpis()
{
$time = time();
$kpis = array();
/* The data generation is located in AdminStatsControllerCore */
$helper = new HelperKpi();
$helper->id = 'box-conversion-rate';
$helper->icon = 'icon-sort-by-attributes-alt';
//$helper->chart = true;
$helper->color = 'color1';
$helper->title = $this->trans('Conversion Rate', array(), 'Admin.Global');
$helper->subtitle = $this->trans('30 days', array(), 'Admin.Global');
if (ConfigurationKPI::get('CONVERSION_RATE') !== false) {
$helper->value = ConfigurationKPI::get('CONVERSION_RATE');
}
if (ConfigurationKPI::get('CONVERSION_RATE_CHART') !== false) {
$helper->data = ConfigurationKPI::get('CONVERSION_RATE_CHART');
}
$helper->source = $this->context->link->getAdminLink('AdminStats') . '&ajax=1&action=getKpi&kpi=conversion_rate';
$helper->refresh = (bool) (ConfigurationKPI::get('CONVERSION_RATE_EXPIRE') < $time);
$kpis[] = $helper->generate();
$helper = new HelperKpi();
$helper->id = 'box-carts';
$helper->icon = 'icon-shopping-cart';
$helper->color = 'color2';
$helper->title = $this->trans('Abandoned Carts', array(), 'Admin.Orderscustomers.Feature');
$date_from = date(Context::getContext()->language->date_format_lite, strtotime('-2 day'));
$date_to = date(Context::getContext()->language->date_format_lite, strtotime('-1 day'));
$helper->subtitle = $this->trans('From %date1% to %date2%', array('%date1%' => $date_from, '%date2%' => $date_to), 'Admin.Orderscustomers.Feature');
$helper->href = $this->context->link->getAdminLink('AdminCarts') . '&action=filterOnlyAbandonedCarts';
if (ConfigurationKPI::get('ABANDONED_CARTS') !== false) {
$helper->value = ConfigurationKPI::get('ABANDONED_CARTS');
}
$helper->source = $this->context->link->getAdminLink('AdminStats') . '&ajax=1&action=getKpi&kpi=abandoned_cart';
$helper->refresh = (bool) (ConfigurationKPI::get('ABANDONED_CARTS_EXPIRE') < $time);
$kpis[] = $helper->generate();
$helper = new HelperKpi();
$helper->id = 'box-average-order';
$helper->icon = 'icon-money';
$helper->color = 'color3';
$helper->title = $this->trans('Average Order Value', array(), 'Admin.Orderscustomers.Feature');
$helper->subtitle = $this->trans('30 days', array(), 'Admin.Global');
if (ConfigurationKPI::get('AVG_ORDER_VALUE') !== false) {
$helper->value = $this->trans('%amount% tax excl.', array('%amount%' => ConfigurationKPI::get('AVG_ORDER_VALUE')), 'Admin.Orderscustomers.Feature');
}
if (ConfigurationKPI::get('AVG_ORDER_VALUE_EXPIRE') < $time) {
$helper->source = $this->context->link->getAdminLink('AdminStats') . '&ajax=1&action=getKpi&kpi=average_order_value';
}
$kpis[] = $helper->generate();
$helper = new HelperKpi();
$helper->id = 'box-net-profit-visitor';
$helper->icon = 'icon-user';
$helper->color = 'color4';
$helper->title = $this->trans('Net Profit per Visitor', array(), 'Admin.Orderscustomers.Feature');
$helper->subtitle = $this->trans('30 days', array(), 'Admin.Global');
if (ConfigurationKPI::get('NETPROFIT_VISITOR') !== false) {
$helper->value = ConfigurationKPI::get('NETPROFIT_VISITOR');
}
$helper->source = $this->context->link->getAdminLink('AdminStats') . '&ajax=1&action=getKpi&kpi=netprofit_visitor';
$helper->refresh = (bool) (ConfigurationKPI::get('NETPROFIT_VISITOR_EXPIRE') < $time);
$kpis[] = $helper->generate();
$helper = new HelperKpiRow();
$helper->kpis = $kpis;
return $helper->generate();
}
public function renderView()
{
/** @var Cart $cart */
if (!($cart = $this->loadObject(true))) {
return;
}
$customer = new Customer($cart->id_customer);
$currency = new Currency($cart->id_currency);
$this->context->cart = $cart;
$this->context->currency = $currency;
$this->context->customer = $customer;
$this->toolbar_title = $this->trans('Cart #%ID%', array('%ID%' => $this->context->cart->id), 'Admin.Orderscustomers.Feature');
$products = $cart->getProducts();
$summary = $cart->getSummaryDetails();
/* Display order information */
$id_order = (int) Order::getIdByCartId($cart->id);
$order = new Order($id_order);
if (Validate::isLoadedObject($order)) {
$tax_calculation_method = $order->getTaxCalculationMethod();
$id_shop = (int) $order->id_shop;
} else {
$id_shop = (int) $cart->id_shop;
$tax_calculation_method = Group::getPriceDisplayMethod(Group::getCurrent()->id);
}
if ($tax_calculation_method == PS_TAX_EXC) {
$total_products = $summary['total_products'];
$total_discounts = $summary['total_discounts_tax_exc'];
$total_wrapping = $summary['total_wrapping_tax_exc'];
$total_price = $summary['total_price_without_tax'];
$total_shipping = $summary['total_shipping_tax_exc'];
} else {
$total_products = $summary['total_products_wt'];
$total_discounts = $summary['total_discounts'];
$total_wrapping = $summary['total_wrapping'];
$total_price = $summary['total_price'];
$total_shipping = $summary['total_shipping'];
}
foreach ($products as &$product) {
if ($tax_calculation_method == PS_TAX_EXC) {
$product['product_price'] = $product['price'];
$product['product_total'] = $product['total'];
} else {
$product['product_price'] = $product['price_wt'];
$product['product_total'] = $product['total_wt'];
}
$image = array();
if (isset($product['id_product_attribute']) && (int) $product['id_product_attribute']) {
$image = Db::getInstance()->getRow('SELECT id_image FROM ' . _DB_PREFIX_ . 'product_attribute_image WHERE id_product_attribute = ' . (int) $product['id_product_attribute']);
}
if (!isset($image['id_image'])) {
$image = Db::getInstance()->getRow('SELECT id_image FROM ' . _DB_PREFIX_ . 'image WHERE id_product = ' . (int) $product['id_product'] . ' AND cover = 1');
}
$product['qty_in_stock'] = StockAvailable::getQuantityAvailableByProduct($product['id_product'], isset($product['id_product_attribute']) ? $product['id_product_attribute'] : null, (int) $id_shop);
$image_product = new Image($image['id_image']);
$product['image'] = (isset($image['id_image']) ? ImageManager::thumbnail(_PS_IMG_DIR_ . 'p/' . $image_product->getExistingImgPath() . '.jpg', 'product_mini_' . (int) $product['id_product'] . (isset($product['id_product_attribute']) ? '_' . (int) $product['id_product_attribute'] : '') . '.jpg', 45, 'jpg') : '--');
$customized_datas = Product::getAllCustomizedDatas($this->context->cart->id, null, true, null, (int) $product['id_customization']);
$this->context->cart->setProductCustomizedDatas($product, $customized_datas);
if ($customized_datas) {
Product::addProductCustomizationPrice($product, $customized_datas);
}
}
$helper = new HelperKpi();
$helper->id = 'box-kpi-cart';
$helper->icon = 'icon-shopping-cart';
$helper->color = 'color1';
$helper->title = $this->trans('Total Cart', array(), 'Admin.Orderscustomers.Feature');
$helper->subtitle = $this->trans('Cart #%ID%', array('%ID%' => $cart->id), 'Admin.Orderscustomers.Feature');
$helper->value = Tools::displayPrice($total_price, $currency);
$kpi = $helper->generate();
$this->tpl_view_vars = array(
'kpi' => $kpi,
'products' => $products,
'discounts' => $cart->getCartRules(),
'order' => $order,
'cart' => $cart,
'currency' => $currency,
'customer' => $customer,
'customer_stats' => $customer->getStats(),
'total_products' => $total_products,
'total_discounts' => $total_discounts,
'total_wrapping' => $total_wrapping,
'total_price' => $total_price,
'total_shipping' => $total_shipping,
'tax_calculation_method' => $tax_calculation_method,
);
return parent::renderView();
}
public function ajaxPreProcess()
{
if ($this->access('edit')) {
$id_customer = (int) Tools::getValue('id_customer');
$customer = new Customer((int) $id_customer);
$this->context->customer = $customer;
$id_cart = (int) Tools::getValue('id_cart');
if (!$id_cart) {
$id_cart = $customer->getLastEmptyCart(false);
}
$this->context->cart = new Cart((int) $id_cart);
if (!$this->context->cart->id) {
$this->context->cart->recyclable = 0;
$this->context->cart->gift = 0;
}
if (!$this->context->cart->id_customer) {
$this->context->cart->id_customer = $id_customer;
}
if (Validate::isLoadedObject($this->context->cart) && $this->context->cart->OrderExists()) {
return;
}
if (!$this->context->cart->secure_key) {
$this->context->cart->secure_key = $this->context->customer->secure_key;
}
if (!$this->context->cart->id_shop) {
$this->context->cart->id_shop = (int) $this->context->shop->id;
}
if (!$this->context->cart->id_lang) {
$this->context->cart->id_lang = (($id_lang = (int) Tools::getValue('id_lang')) ? $id_lang : Configuration::get('PS_LANG_DEFAULT'));
}
if (!$this->context->cart->id_currency) {
$this->context->cart->id_currency = (($id_currency = (int) Tools::getValue('id_currency')) ? $id_currency : Configuration::get('PS_CURRENCY_DEFAULT'));
}
$addresses = $customer->getAddresses((int) $this->context->cart->id_lang);
$id_address_delivery = (int) Tools::getValue('id_address_delivery');
$id_address_invoice = (int) Tools::getValue('id_address_delivery');
if (!$this->context->cart->id_address_invoice && isset($addresses[0])) {
$this->context->cart->id_address_invoice = (int) $addresses[0]['id_address'];
} elseif ($id_address_invoice) {
$this->context->cart->id_address_invoice = (int) $id_address_invoice;
}
if (!$this->context->cart->id_address_delivery && isset($addresses[0])) {
$this->context->cart->id_address_delivery = $addresses[0]['id_address'];
} elseif ($id_address_delivery) {
$this->context->cart->id_address_delivery = (int) $id_address_delivery;
}
$this->context->cart->setNoMultishipping();
$this->context->cart->save();
$currency = new Currency((int) $this->context->cart->id_currency);
$this->context->currency = $currency;
}
}
public function ajaxProcessDeleteProduct()
{
if ($this->access('edit')) {
$errors = array();
if ((!$id_product = (int) Tools::getValue('id_product')) || !Validate::isInt($id_product)) {
$errors[] = $this->trans('Invalid product', array(), 'Admin.Catalog.Notification');
}
if (($id_product_attribute = (int) Tools::getValue('id_product_attribute')) && !Validate::isInt($id_product_attribute)) {
$errors[] = $this->trans('Invalid combination', array(), 'Admin.Catalog.Notification');
}
if (count($errors)) {
die(json_encode($errors));
}
if ($this->context->cart->deleteProduct($id_product, $id_product_attribute, (int) Tools::getValue('id_customization'))) {
echo json_encode($this->ajaxReturnVars());
}
}
}
public function ajaxProcessUpdateCustomizationFields()
{
$errors = array();
if ($this->access('edit')) {
$errors = array();
if (Tools::getValue('only_display') != 1) {
if (!$this->context->cart->id || (!$id_product = (int) Tools::getValue('id_product'))) {
return;
}
$product = new Product((int) $id_product);
if (!$customization_fields = $product->getCustomizationFieldIds()) {
return;
}
foreach ($customization_fields as $customization_field) {
$field_id = 'customization_' . $id_product . '_' . $customization_field['id_customization_field'];
if ($customization_field['type'] == Product::CUSTOMIZE_TEXTFIELD) {
if (!Tools::getValue($field_id)) {
if ($customization_field['required']) {
$errors[] = $this->trans('Please fill in all the required fields.', array(), 'Admin.Notifications.Error');
}
continue;
}
if (!Validate::isMessage(Tools::getValue($field_id))) {
$errors[] = $this->trans('Invalid message', array(), 'Admin.Notifications.Error');
}
$this->context->cart->addTextFieldToProduct((int) $product->id, (int) $customization_field['id_customization_field'], Product::CUSTOMIZE_TEXTFIELD, Tools::getValue($field_id));
} elseif ($customization_field['type'] == Product::CUSTOMIZE_FILE) {
if (!isset($_FILES[$field_id]) || !isset($_FILES[$field_id]['tmp_name']) || empty($_FILES[$field_id]['tmp_name'])) {
if ($customization_field['required']) {
$errors[] = $this->trans('Please fill in all the required fields.', array(), 'Admin.Notifications.Error');
}
continue;
}
if ($error = ImageManager::validateUpload($_FILES[$field_id], (int) Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'))) {
$errors[] = $error;
}
if (!($tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS')) || !move_uploaded_file($_FILES[$field_id]['tmp_name'], $tmp_name)) {
$errors[] = $this->trans('An error occurred during the image upload process.', array(), 'Admin.Catalog.Notification');
}
$file_name = md5(uniqid(mt_rand(0, mt_getrandmax()), true));
if (!ImageManager::resize($tmp_name, _PS_UPLOAD_DIR_ . $file_name)) {
continue;
} elseif (!ImageManager::resize($tmp_name, _PS_UPLOAD_DIR_ . $file_name . '_small', (int) Configuration::get('PS_PRODUCT_PICTURE_WIDTH'), (int) Configuration::get('PS_PRODUCT_PICTURE_HEIGHT'))) {
$errors[] = $this->trans('An error occurred during the image upload process.', array(), 'Admin.Catalog.Notification');
} else {
$this->context->cart->addPictureToProduct((int) $product->id, (int) $customization_field['id_customization_field'], Product::CUSTOMIZE_FILE, $file_name);
}
unlink($tmp_name);
}
}
}
$this->setMedia(false);
$this->initFooter();
$this->context->smarty->assign(array('customization_errors' => implode('<br />', $errors),
'css_files' => $this->css_files, ));
return $this->smartyOutputContent('controllers/orders/form_customization_feedback.tpl');
}
}
public function ajaxProcessUpdateQty()
{
if ($this->access('edit')) {
$errors = array();
if (!$this->context->cart->id) {
return;
}
if ($this->context->cart->OrderExists()) {
$errors[] = $this->trans('An order has already been placed with this cart.', array(), 'Admin.Catalog.Notification');
} elseif (!($id_product = (int) Tools::getValue('id_product')) || !($product = new Product((int) $id_product, true, $this->context->language->id))) {
$errors[] = $this->trans('Invalid product', array(), 'Admin.Catalog.Notification');
} elseif (!($qty = Tools::getValue('qty')) || $qty == 0) {
$errors[] = $this->trans('Invalid quantity', array(), 'Admin.Catalog.Notification');
}
// Don't try to use a product if not instanciated before due to errors
if (isset($product) && $product->id) {
if (($id_product_attribute = Tools::getValue('id_product_attribute')) != 0) {
if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty((int) $id_product_attribute, (int) $qty)) {
$errors[] = $this->trans('There are not enough products in stock.', array(), 'Admin.Catalog.Notification');
}
} elseif (!$product->checkQty((int) $qty)) {
$errors[] = $this->trans('There are not enough products in stock.', array(), 'Admin.Catalog.Notification');
}
if (!($id_customization = (int) Tools::getValue('id_customization', 0)) && !$product->hasAllRequiredCustomizableFields()) {
$errors[] = $this->trans('Please fill in all the required fields.', array(), 'Admin.Notifications.Error');
}
$this->context->cart->save();
} else {
$errors[] = $this->trans('This product cannot be added to the cart.', array(), 'Admin.Catalog.Notification');
}
if (!count($errors)) {
if ((int) $qty < 0) {
$qty = str_replace('-', '', $qty);
$operator = 'down';
} else {
$operator = 'up';
}
if (!($qty_upd = $this->context->cart->updateQty($qty, $id_product, (int) $id_product_attribute, (int) $id_customization, $operator))) {
$errors[] = $this->trans('You already have the maximum quantity available for this product.', array(), 'Admin.Catalog.Notification');
} elseif ($qty_upd < 0) {
$minimal_qty = $id_product_attribute ? Attribute::getAttributeMinimalQty((int) $id_product_attribute) : $product->minimal_quantity;
$errors[] = $this->trans('You must add a minimum quantity of %d', array($minimal_qty), 'Admin.Orderscustomers.Notification');
}
}
echo json_encode(array_merge($this->ajaxReturnVars(), array('errors' => $errors)));
}
}
public function ajaxProcessUpdateDeliveryOption()
{
if ($this->access('edit')) {
$delivery_option = Tools::getValue('delivery_option');
if ($delivery_option !== false) {
$this->context->cart->setDeliveryOption(array($this->context->cart->id_address_delivery => $delivery_option));
}
if (Validate::isBool(($recyclable = (int) Tools::getValue('recyclable')))) {
$this->context->cart->recyclable = $recyclable;
}
if (Validate::isBool(($gift = (int) Tools::getValue('gift')))) {
$this->context->cart->gift = $gift;
}
if (Validate::isMessage(($gift_message = pSQL(Tools::getValue('gift_message'))))) {
$this->context->cart->gift_message = $gift_message;
}
$this->context->cart->save();
echo json_encode($this->ajaxReturnVars());
}
}
public function ajaxProcessUpdateOrderMessage()
{
if ($this->access('edit')) {
$id_message = false;
if ($old_message = Message::getMessageByCartId((int) $this->context->cart->id)) {
$id_message = $old_message['id_message'];
}
$message = new Message((int) $id_message);
if ($message_content = Tools::getValue('message')) {
if (Validate::isMessage($message_content)) {
$message->message = $message_content;
$message->id_cart = (int) $this->context->cart->id;
$message->id_customer = (int) $this->context->cart->id_customer;
$message->save();
}
} elseif (Validate::isLoadedObject($message)) {
$message->delete();
}
echo json_encode($this->ajaxReturnVars());
}
}
public function ajaxProcessUpdateCurrency()
{
if ($this->access('edit')) {
$currency = new Currency((int) Tools::getValue('id_currency'));
if (Validate::isLoadedObject($currency) && !$currency->deleted && $currency->active) {
$this->context->cart->id_currency = (int) $currency->id;
$this->context->currency = $currency;
$this->context->cart->save();
}
echo json_encode($this->ajaxReturnVars());
}
}
public function ajaxProcessUpdateLang()
{
if ($this->access('edit')) {
$lang = new Language((int) Tools::getValue('id_lang'));
if (Validate::isLoadedObject($lang) && $lang->active) {
$this->context->cart->id_lang = (int) $lang->id;
$this->context->cart->save();
}
echo json_encode($this->ajaxReturnVars());
}
}
public function ajaxProcessDuplicateOrder()
{
if ($this->access('edit')) {
$errors = array();
if (!$id_order = Tools::getValue('id_order')) {
$errors[] = $this->trans('Invalid order', array(), 'Admin.Orderscustomers.Notification');
}
$cart = Cart::getCartByOrderId($id_order);
$new_cart = $cart->duplicate();
if (!$new_cart || !Validate::isLoadedObject($new_cart['cart'])) {
$errors[] = $this->trans('The order cannot be renewed.', array(), 'Admin.Orderscustomers.Notification');
} elseif (!$new_cart['success']) {
$errors[] = $this->trans('The order cannot be renewed.', array(), 'Admin.Orderscustomers.Notification');
} else {
$this->context->cart = $new_cart['cart'];
echo json_encode($this->ajaxReturnVars());
}
}
}
public function ajaxProcessDeleteVoucher()
{
if ($this->access('edit')) {
if ($this->context->cart->removeCartRule((int) Tools::getValue('id_cart_rule'))) {
echo json_encode($this->ajaxReturnVars());
}
}
}
public function ajaxProcessupdateFreeShipping()
{
if ($this->access('edit')) {
if (!$id_cart_rule = CartRule::getIdByCode(CartRule::BO_ORDER_CODE_PREFIX . (int) $this->context->cart->id)) {
$cart_rule = new CartRule();
$cart_rule->code = CartRule::BO_ORDER_CODE_PREFIX . (int) $this->context->cart->id;
$cart_rule->name = array(Configuration::get('PS_LANG_DEFAULT') => $this->trans('Free Shipping', array(), 'Admin.Orderscustomers.Feature'));
$cart_rule->id_customer = (int) $this->context->cart->id_customer;
$cart_rule->free_shipping = true;
$cart_rule->quantity = 1;
$cart_rule->quantity_per_user = 1;
$cart_rule->minimum_amount_currency = (int) $this->context->cart->id_currency;
$cart_rule->reduction_currency = (int) $this->context->cart->id_currency;
$cart_rule->date_from = date('Y-m-d H:i:s', time());
$cart_rule->date_to = date('Y-m-d H:i:s', time() + 24 * 36000);
$cart_rule->active = 1;
$cart_rule->add();
} else {
$cart_rule = new CartRule((int) $id_cart_rule);
}
$this->context->cart->removeCartRule((int) $cart_rule->id);
if (Tools::getValue('free_shipping')) {
$this->context->cart->addCartRule((int) $cart_rule->id);
}
echo json_encode($this->ajaxReturnVars());
}
}
public function ajaxProcessAddVoucher()
{
if ($this->access('edit')) {
$errors = array();
if (!($id_cart_rule = Tools::getValue('id_cart_rule')) || !$cart_rule = new CartRule((int) $id_cart_rule)) {
$errors[] = $this->trans('Invalid voucher.', array(), 'Admin.Catalog.Notification');
} elseif ($err = $cart_rule->checkValidity($this->context)) {
$errors[] = $err;
}
if (!count($errors)) {
if (!$this->context->cart->addCartRule((int) $cart_rule->id)) {
$errors[] = $this->trans('Can\'t add the voucher.', array(), 'Admin.Advparameters.Notification');
}
}
echo json_encode(array_merge($this->ajaxReturnVars(), array('errors' => $errors)));
}
}
public function ajaxProcessUpdateAddress()
{
if ($this->access('edit')) {
echo json_encode(array('addresses' => $this->context->customer->getAddresses((int) $this->context->cart->id_lang)));
}
}
public function ajaxProcessUpdateAddresses()
{
if ($this->access('edit')) {
if (($id_address_delivery = (int) Tools::getValue('id_address_delivery')) &&
($address_delivery = new Address((int) $id_address_delivery)) &&
$address_delivery->id_customer == $this->context->cart->id_customer) {
$this->context->cart->id_address_delivery = (int) $address_delivery->id;
}
if (($id_address_invoice = (int) Tools::getValue('id_address_invoice')) &&
($address_invoice = new Address((int) $id_address_invoice)) &&
$address_invoice->id_customer = $this->context->cart->id_customer) {
$this->context->cart->id_address_invoice = (int) $address_invoice->id;
}
$this->context->cart->save();
echo json_encode($this->ajaxReturnVars());
}
}
protected function getCartSummary()
{
$summary = $this->context->cart->getSummaryDetails(null, true);
$currency = Context::getContext()->currency;
if (count($summary['products'])) {
foreach ($summary['products'] as &$product) {
$product['numeric_price'] = $product['price'];
$product['numeric_total'] = $product['total'];
$product['price'] = str_replace($currency->sign, '', Tools::displayPrice($product['price'], $currency));
$product['total'] = str_replace($currency->sign, '', Tools::displayPrice($product['total'], $currency));
$product['image_link'] = $this->context->link->getImageLink($product['link_rewrite'], $product['id_image'], 'small_default');
if (!isset($product['attributes_small'])) {
$product['attributes_small'] = '';
}
$product['customized_datas'] = Product::getAllCustomizedDatas((int) $this->context->cart->id, null, true, null, (int) $product['id_customization']);
}
}
if (count($summary['discounts'])) {
foreach ($summary['discounts'] as &$voucher) {
$voucher['value_real'] = Tools::displayPrice($voucher['value_real'], $currency);
}
}
if (isset($summary['gift_products']) && count($summary['gift_products'])) {
foreach ($summary['gift_products'] as &$product) {
$product['image_link'] = $this->context->link->getImageLink($product['link_rewrite'], $product['id_image'], 'small_default');
if (!isset($product['attributes_small'])) {
$product['attributes_small'] = '';
}
}
}
return $summary;
}
protected function getDeliveryOptionList()
{
$delivery_option_list_formated = array();
$delivery_option_list = $this->context->cart->getDeliveryOptionList();
if (!count($delivery_option_list)) {
return array();
}
$id_default_carrier = (int) Configuration::get('PS_CARRIER_DEFAULT');
foreach (current($delivery_option_list) as $key => $delivery_option) {
$name = '';
$first = true;
$id_default_carrier_delivery = false;
foreach ($delivery_option['carrier_list'] as $carrier) {
if (!$first) {
$name .= ', ';
} else {
$first = false;
}
$name .= $carrier['instance']->name;
if ($delivery_option['unique_carrier']) {
$name .= ' - ' . $carrier['instance']->delay[$this->context->employee->id_lang];
}
if (!$id_default_carrier_delivery) {
$id_default_carrier_delivery = (int) $carrier['instance']->id;
}
if ($carrier['instance']->id == $id_default_carrier) {
$id_default_carrier_delivery = $id_default_carrier;
}
if (!$this->context->cart->id_carrier) {
$this->context->cart->setDeliveryOption(array($this->context->cart->id_address_delivery => (int) $carrier['instance']->id . ','));
$this->context->cart->save();
}
}
$delivery_option_list_formated[] = array('name' => $name, 'key' => $key);
}
return $delivery_option_list_formated;
}
public function displayAjaxSearchCarts()
{
$id_customer = (int) Tools::getValue('id_customer');
$carts = Cart::getCustomerCarts((int) $id_customer, false);
$orders = Order::getCustomerOrders((int) $id_customer);
if (count($carts)) {
foreach ($carts as $key => &$cart) {
$cart_obj = new Cart((int) $cart['id_cart']);
if ($cart['id_cart'] == $this->context->cart->id) {
unset($carts[$key]);
continue;
}
$currency = new Currency((int) $cart['id_currency']);
$cart['total_price'] = Tools::displayPrice($cart_obj->getOrderTotal(), $currency);
}
}
if (count($orders)) {
foreach ($orders as &$order) {
$order['total_paid_real'] = Tools::displayPrice($order['total_paid_real'], $currency);
}
}
if ($orders || $carts) {
$to_return = array_merge(
$this->ajaxReturnVars(),
array(
'carts' => $carts,
'orders' => $orders,
'found' => true,
)
);
} else {
$to_return = array_merge($this->ajaxReturnVars(), array('found' => false));
}
echo json_encode($to_return);
}
public function ajaxReturnVars()
{
$id_cart = (int) $this->context->cart->id;
$message_content = '';
if ($message = Message::getMessageByCartId((int) $this->context->cart->id)) {
$message_content = $message['message'];
}
$cart_rules = $this->context->cart->getCartRules(CartRule::FILTER_ACTION_SHIPPING);
$free_shipping = false;
if (count($cart_rules)) {
foreach ($cart_rules as $cart_rule) {
if ($cart_rule['id_cart_rule'] == CartRule::getIdByCode(CartRule::BO_ORDER_CODE_PREFIX . (int) $this->context->cart->id)) {
$free_shipping = true;
break;
}
}
}
$addresses = $this->context->customer->getAddresses((int) $this->context->cart->id_lang);
foreach ($addresses as &$data) {
$address = new Address((int) $data['id_address']);
$data['formated_address'] = AddressFormat::generateAddress($address, array(), '<br />');
}
return array(
'summary' => $this->getCartSummary(),
'delivery_option_list' => $this->getDeliveryOptionList(),
'cart' => $this->context->cart,
'currency' => new Currency($this->context->cart->id_currency),
'addresses' => $addresses,
'id_cart' => $id_cart,
'order_message' => $message_content,
'link_order' => $this->context->link->getPageLink(
'order',
false,
(int) $this->context->cart->id_lang,
'step=3&recover_cart=' . $id_cart . '&token_cart=' . md5(_COOKIE_KEY_ . 'recover_cart_' . $id_cart)
),
'free_shipping' => (int) $free_shipping,
);
}
public function initToolbar()
{
parent::initToolbar();
unset($this->toolbar_btn['new']);
}
/**
* Display an image as a download.
*/
public function displayAjaxCustomizationImage()
{
if (!Tools::isSubmit('img') || !Tools::isSubmit('name')) {
return;
}
$img = Tools::getValue('img');
$name = Tools::getValue('name');
$path = _PS_UPLOAD_DIR_ . $img;
if (Validate::isMd5($img) && Validate::isGenericName($path)) {
header('Content-type: image/jpeg');
header('Content-Disposition: attachment; filename="' . $name . '.jpg"');
readfile($path);
}
}
public function displayAjaxGetSummary()
{
echo json_encode($this->ajaxReturnVars());
}
public function ajaxProcessUpdateProductPrice()
{
if ($this->access('edit')) {
SpecificPrice::deleteByIdCart((int) $this->context->cart->id, (int) Tools::getValue('id_product'), (int) Tools::getValue('id_product_attribute'));
$specific_price = new SpecificPrice();
$specific_price->id_cart = (int) $this->context->cart->id;
$specific_price->id_shop = 0;
$specific_price->id_shop_group = 0;
$specific_price->id_currency = 0;
$specific_price->id_country = 0;
$specific_price->id_group = 0;
$specific_price->id_customer = (int) $this->context->customer->id;
$specific_price->id_product = (int) Tools::getValue('id_product');
$specific_price->id_product_attribute = (int) Tools::getValue('id_product_attribute');
$specific_price->price = (float) Tools::getValue('price');
$specific_price->from_quantity = 1;
$specific_price->reduction = 0;
$specific_price->reduction_type = 'amount';
$specific_price->from = '0000-00-00 00:00:00';
$specific_price->to = '0000-00-00 00:00:00';
$specific_price->add();
echo json_encode($this->ajaxReturnVars());
}
}
public static function getOrderTotalUsingTaxCalculationMethod($id_cart)
{
$context = Context::getContext();
$context->cart = new Cart($id_cart);
$context->currency = new Currency((int) $context->cart->id_currency);
$context->customer = new Customer((int) $context->cart->id_customer);
return Cart::getTotalCart($id_cart, true, Cart::BOTH_WITHOUT_SHIPPING);
}
public static function replaceZeroByShopName($echo, $tr)
{
return $echo == '0' ? Carrier::getCarrierNameFromShopName() : $echo;
}
public function displayDeleteLink($token, $id, $name = null)
{
// don't display ordered carts
foreach ($this->_list as $row) {
if ($row['id_cart'] == $id && isset($row['id_order']) && is_numeric($row['id_order'])) {
return;
}
}
return $this->helper->displayDeleteLink($token, $id, $name);
}
public function renderList()
{
if (!($this->fields_list && is_array($this->fields_list))) {
return false;
}
$this->getList($this->context->language->id);
$helper = new HelperList();
// Empty list is ok
if (!is_array($this->_list)) {
$this->displayWarning($this->trans('Bad SQL query', array(), 'Admin.Notifications.Error') . '<br />' . htmlspecialchars($this->_list_error));
return false;
}
$this->setHelperDisplay($helper);
$helper->tpl_vars = $this->tpl_list_vars;
$helper->tpl_delete_link_vars = $this->tpl_delete_link_vars;
// For compatibility reasons, we have to check standard actions in class attributes
foreach ($this->actions_available as $action) {
if (!in_array($action, $this->actions) && isset($this->$action) && $this->$action) {
$this->actions[] = $action;
}
}
$helper->is_cms = $this->is_cms;
$skip_list = array();
foreach ($this->_list as $row) {
if (isset($row['id_order']) && is_numeric($row['id_order'])) {
$skip_list[] = $row['id_cart'];
}
}
if (array_key_exists('delete', $helper->list_skip_actions)) {
$helper->list_skip_actions['delete'] = array_merge($helper->list_skip_actions['delete'], (array) $skip_list);
} else {
$helper->list_skip_actions['delete'] = (array) $skip_list;
}
$list = $helper->generateList($this->_list, $this->fields_list);
return $list;
}
}

View File

@@ -0,0 +1,320 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property CMSCategory $object
*/
class AdminCmsCategoriesControllerCore extends AdminController
{
/** @var object CMSCategory() instance for navigation */
protected $cms_category;
protected $position_identifier = 'id_cms_category_to_move';
/**
* @deprecated since 1.7.6, to be removed in the next minor
*/
public function __construct()
{
@trigger_error(
'The AdminCmsCategoriesController is deprecated and will be removed in the next minor',
E_USER_DEPRECATED
);
$this->bootstrap = true;
$this->is_cms = true;
$this->table = 'cms_category';
$this->list_id = 'cms_category';
$this->className = 'CMSCategory';
$this->lang = true;
$this->addRowAction('view');
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_orderBy = 'position';
parent::__construct();
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->tpl_list_vars['icon'] = 'icon-folder-close';
$this->tpl_list_vars['title'] = $this->trans('Categories', array(), 'Admin.Catalog.Feature');
$this->fields_list = array(
'id_cms_category' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'align' => 'center', 'class' => 'fixed-width-xs'),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'width' => 'auto', 'callback' => 'hideCMSCategoryPosition', 'callback_object' => 'CMSCategory'),
'description' => array('title' => $this->trans('Description', array(), 'Admin.Global'), 'maxlength' => 90, 'orderby' => false),
'position' => array('title' => $this->trans('Position', array(), 'Admin.Global'), 'filter_key' => 'position', 'align' => 'center', 'class' => 'fixed-width-sm', 'position' => 'position'),
'active' => array(
'title' => $this->trans('Displayed', array(), 'Admin.Global'), 'class' => 'fixed-width-sm', 'active' => 'status',
'align' => 'center', 'type' => 'bool', 'orderby' => false,
),
);
// The controller can't be call directly
// In this case, AdminCmsContentController::getCurrentCMSCategory() is null
if (!AdminCmsContentController::getCurrentCMSCategory()) {
$this->redirect_after = '?controller=AdminCmsContent&token=' . Tools::getAdminTokenLite('AdminCmsContent');
$this->redirect();
}
$this->cms_category = AdminCmsContentController::getCurrentCMSCategory();
$this->_where = ' AND `id_parent` = ' . (int) $this->cms_category->id;
$this->_select = 'position ';
}
public function getTabSlug()
{
return 'ROLE_MOD_TAB_ADMINCMSCONTENT_';
}
public function renderList()
{
$this->initToolbar();
$this->_group = 'GROUP BY a.`id_cms_category`';
if (isset($this->toolbar_btn['new'])) {
$this->toolbar_btn['new']['href'] .= '&id_parent=' . (int) Tools::getValue('id_cms_category');
}
return parent::renderList();
}
public function postProcess()
{
if (Tools::isSubmit('submitAdd' . $this->table)) {
$this->action = 'save';
if ($id_cms_category = (int) Tools::getValue('id_cms_category')) {
$this->id_object = $id_cms_category;
if (!CMSCategory::checkBeforeMove($id_cms_category, (int) Tools::getValue('id_parent'))) {
$this->errors[] = $this->trans('The page Category cannot be moved here.', array(), 'Admin.Design.Notification');
return false;
}
}
$object = parent::postProcess();
$this->updateAssoShop((int) Tools::getValue('id_cms_category'));
if ($object !== false) {
Tools::redirectAdmin(self::$currentIndex . '&conf=3&id_cms_category=' . (int) $object->id . '&token=' . Tools::getValue('token'));
}
return $object;
} elseif (Tools::isSubmit('statuscms_category') && Tools::getValue($this->identifier)) {
// Change object statuts (active, inactive)
if ($this->access('edit')) {
if (Validate::isLoadedObject($object = $this->loadObject())) {
if ($object->toggleStatus()) {
$identifier = ((int) $object->id_parent ? '&id_cms_category=' . (int) $object->id_parent : '');
Tools::redirectAdmin(self::$currentIndex . '&conf=5' . $identifier . '&token=' . Tools::getValue('token'));
} else {
$this->errors[] = $this->trans('An error occurred while updating the status.', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error')
. ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('delete' . $this->table)) {
// Delete object
if ($this->access('delete')) {
if (Validate::isLoadedObject($object = $this->loadObject()) && isset($this->fieldImageSettings)) {
// check if request at least one object with noZeroObject
if (isset($object->noZeroObject) && count($taxes = call_user_func(array($this->className, $object->noZeroObject))) <= 1) {
$this->errors[] = $this->trans('You need at least one object.', array(), 'Admin.Notifications.Error')
. ' <b>' . $this->table . '</b><br />' . $this->trans('You cannot delete all of the items.', array(), 'Admin.Notifications.Error');
} else {
$identifier = ((int) $object->id_parent ? '&' . $this->identifier . '=' . (int) $object->id_parent : '');
if ($this->deleted) {
$object->deleted = 1;
if ($object->update()) {
Tools::redirectAdmin(self::$currentIndex . '&conf=1&token=' . Tools::getValue('token') . $identifier);
}
} elseif ($object->delete()) {
Tools::redirectAdmin(self::$currentIndex . '&conf=1&token=' . Tools::getValue('token') . $identifier);
}
$this->errors[] = $this->trans('An error occurred during deletion.', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('An error occurred while deleting the object.', array(), 'Admin.Notifications.Error')
. ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('position')) {
$object = new CMSCategory((int) Tools::getValue($this->identifier, Tools::getValue('id_cms_category_to_move', 1)));
if (!$this->access('edit')) {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
} elseif (!Validate::isLoadedObject($object)) {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error')
. ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
} elseif (!$object->updatePosition((int) Tools::getValue('way'), (int) Tools::getValue('position'))) {
$this->errors[] = $this->trans('Failed to update the position.', array(), 'Admin.Notifications.Error');
} else {
$identifier = ((int) $object->id_parent ? '&' . $this->identifier . '=' . (int) $object->id_parent : '');
$token = Tools::getAdminTokenLite('AdminCmsContent');
Tools::redirectAdmin(
self::$currentIndex . '&' . $this->table . 'Orderby=position&' . $this->table . 'Orderway=asc&conf=5' . $identifier . '&token=' . $token
);
}
} elseif (Tools::getValue('submitDel' . $this->table) || Tools::getValue('submitBulkdelete' . $this->table)) {
// Delete multiple objects
if ($this->access('delete')) {
if (Tools::isSubmit($this->table . 'Box')) {
$cms_category = new CMSCategory();
$result = true;
$result = $cms_category->deleteSelection(Tools::getValue($this->table . 'Box'));
if ($result) {
$cms_category->cleanPositions((int) Tools::getValue('id_cms_category'));
$token = Tools::getAdminTokenLite('AdminCmsContent');
Tools::redirectAdmin(self::$currentIndex . '&conf=2&token=' . $token . '&id_cms_category=' . (int) Tools::getValue('id_cms_category'));
}
$this->errors[] = $this->trans('An error occurred while deleting this selection.', array(), 'Admin.Notifications.Error');
} else {
$this->errors[] = $this->trans('You must select at least one element to delete.', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
}
parent::postProcess();
}
public function renderForm()
{
$this->display = 'edit';
$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_parent'), 1);
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('CMS Category', array(), 'Admin.Design.Feature'),
'icon' => 'icon-folder-close',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'class' => 'copyMeta2friendlyURL',
'required' => true,
'lang' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'switch',
'label' => $this->trans('Displayed', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
// custom template
array(
'type' => 'select_category',
'label' => $this->trans('Parent category', array(), 'Admin.Design.Feature'),
'name' => 'id_parent',
'options' => array(
'html' => $html_categories,
),
),
array(
'type' => 'textarea',
'label' => $this->trans('Description', array(), 'Admin.Global'),
'name' => 'description',
'lang' => true,
'rows' => 5,
'cols' => 40,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Meta title', array(), 'Admin.Global'),
'name' => 'meta_title',
'lang' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Meta description', array(), 'Admin.Global'),
'name' => 'meta_description',
'lang' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Meta keywords', array(), 'Admin.Global'),
'name' => 'meta_keywords',
'lang' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Friendly URL', array(), 'Admin.Global'),
'name' => 'link_rewrite',
'required' => true,
'lang' => true,
'hint' => $this->trans('Only letters and the minus (-) character are allowed.', array(), 'Admin.Catalog.Help'),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$this->tpl_form_vars['PS_ALLOW_ACCENTED_CHARS_URL'] = (int) Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL');
return parent::renderForm();
}
}

View File

@@ -0,0 +1,314 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property CMS $object
*/
class AdminCmsContentControllerCore extends AdminController
{
/** @var object adminCMSCategories() instance */
protected $admin_cms_categories;
/** @var object adminCMS() instance */
protected $admin_cms;
/** @var object Category() instance for navigation */
protected static $category = null;
/**
* @deprecated since 1.7.6, to be removed in the next minor
*/
public function __construct()
{
@trigger_error(
'The AdminCmsContentController is deprecated and will be removed in the next minor',
E_USER_DEPRECATED
);
$this->bootstrap = true;
/* Get current category */
$id_cms_category = (int) Tools::getValue('id_cms_category', Tools::getValue('id_cms_category_parent', 1));
self::$category = new CMSCategory($id_cms_category);
if (!Validate::isLoadedObject(self::$category)) {
die('Category cannot be loaded');
}
parent::__construct();
$this->table = 'cms';
$this->className = 'CMS';
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->admin_cms_categories = new AdminCmsCategoriesController();
$this->admin_cms_categories->tabAccess = $this->tabAccess;
$this->admin_cms_categories->init();
$this->admin_cms = new AdminCmsController();
$this->admin_cms->tabAccess = $this->tabAccess;
$this->admin_cms->init();
$this->context->controller = $this;
}
/**
* Return current category.
*
* @return object
*/
public static function getCurrentCMSCategory()
{
return self::$category;
}
public function initProcess()
{
if (((Tools::isSubmit('submitAddcms_category') || Tools::isSubmit('submitAddcms_categoryAndStay')) && count($this->admin_cms_categories->errors))
|| Tools::isSubmit('updatecms_category')
|| Tools::isSubmit('addcms_category')) {
$this->display = 'edit_category';
} elseif (((Tools::isSubmit('submitAddcms') || Tools::isSubmit('submitAddcmsAndStay')) && count($this->admin_cms->errors))
|| Tools::isSubmit('updatecms')
|| Tools::isSubmit('addcms')) {
$this->display = 'edit_page';
} else {
$this->display = 'list';
}
}
public function initContent()
{
$id_cms_category = (int) Tools::getValue('id_cms_category');
if (!$id_cms_category) {
$id_cms_category = 1;
}
if ($this->display == 'list') {
$this->page_header_toolbar_btn['new_cms_category'] = array(
'href' => self::$currentIndex . '&addcms_category&token=' . $this->token,
'desc' => $this->trans('Add new page category', array(), 'Admin.Design.Help'),
'icon' => 'process-icon-new',
);
$this->page_header_toolbar_btn['new_cms_page'] = array(
'href' => self::$currentIndex . '&addcms&id_cms_category=' . (int) $id_cms_category . '&token=' . $this->token,
'desc' => $this->trans('Add new page', array(), 'Admin.Design.Help'),
'icon' => 'process-icon-new',
);
}
$this->page_header_toolbar_title = implode(' ' . Configuration::get('PS_NAVIGATION_PIPE') . ' ', $this->toolbar_title);
if (is_array($this->page_header_toolbar_btn)
&& $this->page_header_toolbar_btn instanceof Traversable
|| trim($this->page_header_toolbar_title) != '') {
$this->show_page_header_toolbar = true;
}
$this->admin_cms_categories->token = $this->token;
$this->admin_cms->token = $this->token;
if ($this->display == 'edit_category') {
$this->content .= $this->admin_cms_categories->renderForm();
} elseif ($this->display == 'edit_page') {
$this->content .= $this->admin_cms->renderForm();
} elseif ($this->display == 'list') {
$id_cms_category = (int) Tools::getValue('id_cms_category');
if (!$id_cms_category) {
$id_cms_category = 1;
}
// CMS categories breadcrumb
$cms_tabs = array('cms_category', 'cms');
// Cleaning links
$cat_bar_index = self::$currentIndex;
foreach ($cms_tabs as $tab) {
if (Tools::getValue($tab . 'Orderby') && Tools::getValue($tab . 'Orderway')) {
$cat_bar_index = preg_replace('/&' . $tab . 'Orderby=([a-z _]*)&' . $tab . 'Orderway=([a-z]*)/i', '', self::$currentIndex);
}
}
$this->context->smarty->assign(array(
'cms_breadcrumb' => Tools::getPath($cat_bar_index, $id_cms_category, '', '', 'cms'),
));
$this->content .= $this->admin_cms_categories->renderList();
$this->admin_cms->id_cms_category = $id_cms_category;
$this->content .= $this->admin_cms->renderList();
}
$this->context->smarty->assign(array(
'content' => $this->content,
'show_page_header_toolbar' => $this->show_page_header_toolbar,
'title' => $this->page_header_toolbar_title,
'toolbar_btn' => $this->page_header_toolbar_btn,
'page_header_toolbar_btn' => $this->page_header_toolbar_btn,
'page_header_toolbar_title' => $this->toolbar_title,
));
}
public function initToolbarTitle()
{
$this->toolbar_title = is_array($this->breadcrumbs) ? array_unique($this->breadcrumbs) : array($this->breadcrumbs);
$id_cms_category = (int) Tools::getValue('id_cms_category');
if ($id_cms_category && $id_cms_category !== 1) {
$cms_category = new CMSCategory($id_cms_category);
}
$id_cms_page = Tools::getValue('id_cms');
if ($this->display == 'edit_category') {
if (Tools::getValue('addcms_category') !== false) {
$this->toolbar_title[] = $this->trans('Add new category', array(), 'Admin.Design.Feature');
} else {
if (isset($cms_category)) {
$this->toolbar_title[] = $this->trans('Edit category: %name%', array('%name%' => $cms_category->name[$this->context->employee->id_lang]), 'Admin.Design.Feature');
}
}
} elseif ($this->display == 'edit_page') {
if (Tools::getValue('addcms') !== false) {
$this->toolbar_title[] = $this->trans('Add new page', array(), 'Admin.Design.Feature');
} elseif ($id_cms_page) {
$cms_page = new CMS($id_cms_page);
$this->toolbar_title[] = $this->trans('Edit page: %meta_title%', array('%meta_title%' => $cms_page->meta_title[$this->context->employee->id_lang]), 'Admin.Design.Feature');
}
} elseif ($this->display == 'list' && isset($cms_category)) {
$this->toolbar_title[] = $this->trans('Category: %category%', array('%category%' => $cms_category->name[$this->context->employee->id_lang]), 'Admin.Design.Feature');
}
}
public function postProcess()
{
$this->admin_cms->postProcess();
$this->admin_cms_categories->postProcess();
parent::postProcess();
if (isset($this->admin_cms->errors)) {
$this->errors = array_merge($this->errors, $this->admin_cms->errors);
}
if (isset($this->admin_cms_categories->errors)) {
$this->errors = array_merge($this->errors, $this->admin_cms_categories->errors);
}
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryUi('ui.widget');
$this->addJqueryPlugin('tagify');
}
public function ajaxProcessUpdateCmsPositions()
{
if ($this->access('edit')) {
$id_cms = (int) Tools::getValue('id_cms');
$id_category = (int) Tools::getValue('id_cms_category');
$way = (int) Tools::getValue('way');
$positions = Tools::getValue('cms');
if (is_array($positions)) {
foreach ($positions as $key => $value) {
$pos = explode('_', $value);
if ((isset($pos[1], $pos[2])) && ($pos[1] == $id_category && $pos[2] == $id_cms)) {
$position = $key;
break;
}
}
}
$cms = new CMS($id_cms);
if (Validate::isLoadedObject($cms)) {
if (isset($position) && $cms->updatePosition($way, $position)) {
die(true);
} else {
die('{"hasError" : true, "errors" : "Can not update cms position"}');
}
} else {
die('{"hasError" : true, "errors" : "This cms can not be loaded"}');
}
}
}
public function ajaxProcessUpdateCmsCategoriesPositions()
{
if ($this->access('edit')) {
$id_cms_category_to_move = (int) Tools::getValue('id_cms_category_to_move');
$id_cms_category_parent = (int) Tools::getValue('id_cms_category_parent');
$way = (int) Tools::getValue('way');
$positions = Tools::getValue('cms_category');
if (is_array($positions)) {
foreach ($positions as $key => $value) {
$pos = explode('_', $value);
if ((isset($pos[1], $pos[2])) && ($pos[1] == $id_cms_category_parent && $pos[2] == $id_cms_category_to_move)) {
$position = $key;
break;
}
}
}
$cms_category = new CMSCategory($id_cms_category_to_move);
if (Validate::isLoadedObject($cms_category)) {
if (isset($position) && $cms_category->updatePosition($way, $position)) {
die(true);
} else {
die('{"hasError" : true, "errors" : "Can not update cms categories position"}');
}
} else {
die('{"hasError" : true, "errors" : "This cms category can not be loaded"}');
}
}
}
public function ajaxProcessPublishCMS()
{
if ($this->access('edit')) {
if ($id_cms = (int) Tools::getValue('id_cms')) {
$bo_cms_url = _PS_BASE_URL_ . __PS_BASE_URI__ . basename(_PS_ADMIN_DIR_) . '/index.php?tab=AdminCmsContent&id_cms=' . (int) $id_cms . '&updatecms&token=' . $this->token;
if (Tools::getValue('redirect')) {
die($bo_cms_url);
}
$cms = new CMS((int) (Tools::getValue('id_cms')));
if (!Validate::isLoadedObject($cms)) {
die('error: invalid id');
}
$cms->active = 1;
if ($cms->save()) {
die($bo_cms_url);
} else {
die('error: saving');
}
} else {
die('error: parameters');
}
}
}
}

View File

@@ -0,0 +1,468 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property CMS $object
*/
class AdminCmsControllerCore extends AdminController
{
protected $category;
public $id_cms_category;
protected $position_identifier = 'id_cms';
/**
* @deprecated since 1.7.6, to be removed in the next minor
*/
public function __construct()
{
@trigger_error(
'The AdminCmsController is deprecated and will be removed in the next minor',
E_USER_DEPRECATED
);
$this->bootstrap = true;
$this->table = 'cms';
$this->list_id = 'cms';
$this->className = 'CMS';
$this->lang = true;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_orderBy = 'position';
parent::__construct();
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'id_cms' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'link_rewrite' => array(
'title' => $this->trans('URL', array(), 'Admin.Global'),
),
'meta_title' => array(
'title' => $this->trans('Title', array(), 'Admin.Global'),
'filter_key' => 'b!meta_title',
'maxlength' => 50,
),
'head_seo_title' => array(
'title' => $this->trans('Meta title', array(), 'Admin.Global'),
'filter_key' => 'b!head_seo_title',
'maxlength' => 50,
),
'position' => array(
'title' => $this->trans('Position', array(), 'Admin.Global'),
'filter_key' => 'position',
'align' => 'center',
'class' => 'fixed-width-sm',
'position' => 'position',
),
'active' => array(
'title' => $this->trans('Displayed', array(), 'Admin.Global'),
'align' => 'center',
'active' => 'status',
'class' => 'fixed-width-sm',
'type' => 'bool',
'orderby' => false,
),
);
// The controller can't be call directly
// In this case, AdminCmsContentController::getCurrentCMSCategory() is null
if (!AdminCmsContentController::getCurrentCMSCategory()) {
$this->redirect_after = '?controller=AdminCmsContent&token=' . Tools::getAdminTokenLite('AdminCmsContent');
$this->redirect();
}
$this->_category = AdminCmsContentController::getCurrentCMSCategory();
$this->tpl_list_vars['icon'] = 'icon-folder-close';
$this->tpl_list_vars['title'] = $this->trans('Pages in category "%name%"', array('%name%' => $this->_category->name[Context::getContext()->employee->id_lang]), 'Admin.Design.Feature');
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'cms_category` c ON (c.`id_cms_category` = a.`id_cms_category`)';
$this->_select = 'a.position ';
$this->_where = ' AND c.id_cms_category = ' . (int) $this->_category->id;
}
public function getTabSlug()
{
return 'ROLE_MOD_TAB_ADMINCMSCONTENT_';
}
public function initPageHeaderToolbar()
{
$this->page_header_toolbar_btn['save-and-preview'] = array(
'href' => '#',
'desc' => $this->trans('Save and preview', array(), 'Admin.Actions'),
);
$this->page_header_toolbar_btn['save-and-stay'] = array(
'short' => $this->trans('Save and stay', array(), 'Admin.Actions'),
'href' => '#',
'desc' => $this->trans('Save and stay', array(), 'Admin.Actions'),
);
return parent::initPageHeaderToolbar();
}
public function renderForm()
{
if (!$this->loadObject(true)) {
return;
}
if (Validate::isLoadedObject($this->object)) {
$this->display = 'edit';
} else {
$this->display = 'add';
}
$this->initToolbar();
$this->initPageHeaderToolbar();
$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);
$this->fields_form = array(
'tinymce' => true,
'legend' => array(
'title' => $this->l('Page'),
'icon' => 'icon-folder-close',
),
'input' => array(
// custom template
array(
'type' => 'select_category',
'label' => $this->trans('Page Category', array(), 'Admin.Design.Feature'),
'name' => 'id_cms_category',
'options' => array(
'html' => $html_categories,
),
),
array(
'type' => 'text',
'label' => $this->trans('Title', array(), 'Admin.Global'),
'name' => 'meta_title',
'id' => 'name', // for copyMeta2friendlyURL compatibility
'lang' => true,
'required' => true,
'class' => 'copyMeta2friendlyURL',
'hint' => array(
$this->trans('Used in the h1 page tag, and as the default title tag value.', array(), 'Admin.Design.Help'),
$this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
),
array(
'type' => 'text',
'label' => $this->trans('Meta title', array(), 'Admin.Global'),
'name' => 'head_seo_title',
'lang' => true,
'hint' => array(
$this->trans('Used to override the title tag value. If left blank, the default title value is used.', array(), 'Admin.Design.Help'),
$this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
),
array(
'type' => 'text',
'label' => $this->trans('Meta description', array(), 'Admin.Global'),
'name' => 'meta_description',
'lang' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'tags',
'label' => $this->trans('Meta keywords', array(), 'Admin.Global'),
'name' => 'meta_keywords',
'lang' => true,
'hint' => array(
$this->trans('To add tags, click in the field, write something, and then press the "Enter" key.', array(), 'Admin.Shopparameters.Help'),
$this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
),
array(
'type' => 'text',
'label' => $this->trans('Friendly URL', array(), 'Admin.Global'),
'name' => 'link_rewrite',
'required' => true,
'lang' => true,
'hint' => $this->trans('Only letters and the hyphen (-) character are allowed.', array(), 'Admin.Design.Feature'),
),
array(
'type' => 'textarea',
'label' => $this->trans('Page content', array(), 'Admin.Design.Feature'),
'name' => 'content',
'autoload_rte' => true,
'lang' => true,
'rows' => 5,
'cols' => 40,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' <>;=#{}',
),
array(
'type' => 'switch',
'label' => $this->trans('Indexation by search engines', array(), 'Admin.Design.Feature'),
'name' => 'indexation',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'indexation_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'indexation_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Displayed', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
'buttons' => array(
'save_and_preview' => array(
'name' => 'viewcms',
'type' => 'submit',
'title' => $this->trans('Save and preview', array(), 'Admin.Actions'),
'class' => 'btn btn-default pull-right',
'icon' => 'process-icon-preview',
),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
if (Validate::isLoadedObject($this->object)) {
$this->context->smarty->assign('url_prev', $this->getPreviewUrl($this->object));
}
$this->tpl_form_vars = array(
'active' => $this->object->active,
'PS_ALLOW_ACCENTED_CHARS_URL', (int) Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL'),
);
return parent::renderForm();
}
public function renderList()
{
$this->_group = 'GROUP BY a.`id_cms`';
//self::$currentIndex = self::$currentIndex.'&cms';
$this->position_group_identifier = (int) $this->id_cms_category;
$this->toolbar_title = $this->trans('Pages in this category', array(), 'Admin.Design.Feature');
$this->toolbar_btn['new'] = array(
'href' => self::$currentIndex . '&add' . $this->table . '&id_cms_category=' . (int) $this->id_cms_category . '&token=' . $this->token,
'desc' => $this->trans('Add new', array(), 'Admin.Actions'),
);
return parent::renderList();
}
public function displayList($token = null)
{
/* Display list header (filtering, pagination and column names) */
$this->displayListHeader($token);
if (!count($this->_list)) {
echo '<tr><td class="center" colspan="' . (count($this->fields_list) + 2) . '">' . $this->trans('No items found', array(), 'Admin.Design.Notification') . '</td></tr>';
}
/* Show the content of the table */
$this->displayListContent($token);
/* Close list table and submit button */
$this->displayListFooter($token);
}
public function postProcess()
{
if (Tools::isSubmit('viewcms') && ($id_cms = (int) Tools::getValue('id_cms'))) {
parent::postProcess();
if (($cms = new CMS($id_cms, $this->context->language->id)) && Validate::isLoadedObject($cms)) {
Tools::redirectAdmin(self::$currentIndex . '&id_cms=' . $id_cms . '&conf=4&updatecms&token=' . Tools::getAdminTokenLite('AdminCmsContent') . '&url_preview=1');
}
} elseif (Tools::isSubmit('deletecms')) {
if (Tools::getValue('id_cms') == Configuration::get('PS_CONDITIONS_CMS_ID')) {
Configuration::updateValue('PS_CONDITIONS', 0);
Configuration::updateValue('PS_CONDITIONS_CMS_ID', 0);
}
$cms = new CMS((int) Tools::getValue('id_cms'));
$cms->cleanPositions($cms->id_cms_category);
if (!$cms->delete()) {
$this->errors[] = $this->trans('An error occurred while deleting the object.', array(), 'Admin.Notifications.Error')
. ' <b>' . $this->table . ' (' . Db::getInstance()->getMsgError() . ')</b>';
} else {
Tools::redirectAdmin(self::$currentIndex . '&id_cms_category=' . $cms->id_cms_category . '&conf=1&token=' . Tools::getAdminTokenLite('AdminCmsContent'));
}
} elseif (Tools::getValue('submitDel' . $this->table)) {
// Delete multiple objects
if ($this->access('delete')) {
if (Tools::isSubmit($this->table . 'Box')) {
$cms = new CMS();
$result = true;
$result = $cms->deleteSelection(Tools::getValue($this->table . 'Box'));
if ($result) {
$cms->cleanPositions((int) Tools::getValue('id_cms_category'));
$token = Tools::getAdminTokenLite('AdminCmsContent');
Tools::redirectAdmin(self::$currentIndex . '&conf=2&token=' . $token . '&id_cms_category=' . (int) Tools::getValue('id_cms_category'));
}
$this->errors[] = $this->trans('An error occurred while deleting this selection.', array(), 'Admin.Notifications.Error');
} else {
$this->errors[] = $this->trans('You must select at least one element to delete.', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('submitAddcms') || Tools::isSubmit('submitAddcmsAndPreview')) {
parent::validateRules();
if (count($this->errors)) {
return false;
}
if (!$id_cms = (int) Tools::getValue('id_cms')) {
$cms = new CMS();
$this->copyFromPost($cms, 'cms');
if (!$cms->add()) {
$this->errors[] = $this->trans('An error occurred while creating an object.', array(), 'Admin.Notifications.Error') . ' <b>' . $this->table . ' (' . Db::getInstance()->getMsgError() . ')</b>';
} else {
$this->updateAssoShop($cms->id);
}
} else {
$cms = new CMS($id_cms);
$this->copyFromPost($cms, 'cms');
if (!$cms->update()) {
$this->errors[] = $this->trans('An error occurred while updating an object.', array(), 'Admin.Notifications.Error') . ' <b>' . $this->table . ' (' . Db::getInstance()->getMsgError() . ')</b>';
} else {
$this->updateAssoShop($cms->id);
}
}
if (Tools::isSubmit('view' . $this->table)) {
Tools::redirectAdmin(self::$currentIndex . '&id_cms=' . $cms->id . '&conf=4&updatecms&token=' . Tools::getAdminTokenLite('AdminCmsContent') . '&url_preview=1');
} elseif (Tools::isSubmit('submitAdd' . $this->table . 'AndStay')) {
Tools::redirectAdmin(self::$currentIndex . '&' . $this->identifier . '=' . $cms->id . '&conf=4&update' . $this->table . '&token=' . Tools::getAdminTokenLite('AdminCmsContent'));
} else {
Tools::redirectAdmin(self::$currentIndex . '&id_cms_category=' . $cms->id_cms_category . '&conf=4&token=' . Tools::getAdminTokenLite('AdminCmsContent'));
}
} elseif (Tools::isSubmit('way') && Tools::isSubmit('id_cms') && (Tools::isSubmit('position'))) {
/* @var CMS $object */
if (!$this->access('edit')) {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
} elseif (!Validate::isLoadedObject($object = $this->loadObject())) {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error')
. ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
} elseif (!$object->updatePosition((int) Tools::getValue('way'), (int) Tools::getValue('position'))) {
$this->errors[] = $this->trans('Failed to update the position.', array(), 'Admin.Notifications.Error');
} else {
Tools::redirectAdmin(self::$currentIndex . '&' . $this->table . 'Orderby=position&' . $this->table . 'Orderway=asc&conf=4&id_cms_category=' . (int) $object->id_cms_category . '&token=' . Tools::getAdminTokenLite('AdminCmsContent'));
}
} elseif (Tools::isSubmit('statuscms') && Tools::isSubmit($this->identifier)) {
// Change object status (active, inactive)
if ($this->access('edit')) {
if (Validate::isLoadedObject($object = $this->loadObject())) {
/** @var CMS $object */
if ($object->toggleStatus()) {
Tools::redirectAdmin(self::$currentIndex . '&conf=5&id_cms_category=' . (int) $object->id_cms_category . '&token=' . Tools::getValue('token'));
} else {
$this->errors[] = $this->trans('An error occurred while updating the status.', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error')
. ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('submitBulkdeletecms')) {
// Delete multiple CMS content
if ($this->access('delete')) {
$this->action = 'bulkdelete';
$this->boxes = Tools::getValue($this->table . 'Box');
if (is_array($this->boxes) && array_key_exists(0, $this->boxes)) {
$firstCms = new CMS((int) $this->boxes[0]);
$id_cms_category = (int) $firstCms->id_cms_category;
if (!$res = parent::postProcess(true)) {
return $res;
}
Tools::redirectAdmin(self::$currentIndex . '&conf=2&token=' . Tools::getAdminTokenLite('AdminCmsContent') . '&id_cms_category=' . $id_cms_category);
}
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
} else {
parent::postProcess(true);
}
}
public function getPreviewUrl(CMS $cms)
{
$preview_url = $this->context->link->getCMSLink($cms, null, null, $this->context->language->id);
if (!$cms->active) {
$params = http_build_query(
array(
'adtoken' => Tools::getAdminTokenLite('AdminCmsContent'),
'ad' => basename(_PS_ADMIN_DIR_),
'id_employee' => (int) $this->context->employee->id,
)
);
$preview_url .= (strpos($preview_url, '?') === false ? '?' : '&') . $params;
}
return $preview_url;
}
}

View File

@@ -0,0 +1,527 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Country $object
*/
class AdminCountriesControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'country';
$this->className = 'Country';
$this->lang = true;
$this->deleted = false;
$this->_defaultOrderBy = 'name';
$this->_defaultOrderWay = 'ASC';
$this->explicitSelect = true;
$this->addRowAction('edit');
parent::__construct();
$this->bulk_actions = array(
'delete' => array('text' => $this->trans('Delete selected', array(), 'Admin.Actions'), 'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Actions')),
'AffectZone' => array('text' => $this->trans('Assign to a new zone', array(), 'Admin.International.Feature')),
);
$this->fieldImageSettings = array(
'name' => 'logo',
'dir' => 'st',
);
$this->fields_options = array(
'general' => array(
'title' => $this->trans('Country options', array(), 'Admin.International.Feature'),
'fields' => array(
'PS_RESTRICT_DELIVERED_COUNTRIES' => array(
'title' => $this->trans('Restrict country selections in front office to those covered by active carriers', array(), 'Admin.International.Help'),
'cast' => 'intval',
'type' => 'bool',
'default' => '0',
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
$zones_array = array();
$this->zones = Zone::getZones();
foreach ($this->zones as $zone) {
$zones_array[$zone['id_zone']] = $zone['name'];
}
$this->fields_list = array(
'id_country' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Country', array(), 'Admin.Global'),
'filter_key' => 'b!name',
),
'iso_code' => array(
'title' => $this->trans('ISO code', array(), 'Admin.International.Feature'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'call_prefix' => array(
'title' => $this->trans('Call prefix', array(), 'Admin.International.Feature'),
'align' => 'center',
'callback' => 'displayCallPrefix',
'class' => 'fixed-width-sm',
),
'zone' => array(
'title' => $this->trans('Zone', array(), 'Admin.Global'),
'type' => 'select',
'list' => $zones_array,
'filter_key' => 'z!id_zone',
'filter_type' => 'int',
'order_key' => 'z!name',
),
'active' => array(
'title' => $this->trans('Enabled', array(), 'Admin.Global'),
'align' => 'center',
'active' => 'status',
'type' => 'bool',
'orderby' => false,
'filter_key' => 'a!active',
'class' => 'fixed-width-sm',
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_country'] = array(
'href' => self::$currentIndex . '&addcountry&token=' . $this->token,
'desc' => $this->trans('Add new country', array(), 'Admin.International.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
/**
* AdminController::setMedia() override.
*
* @see AdminController::setMedia()
*/
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryPlugin('fieldselection');
}
public function renderList()
{
$this->_select = 'z.`name` AS zone';
$this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'zone` z ON (z.`id_zone` = a.`id_zone`)';
$this->_use_found_rows = false;
$this->tpl_list_vars['zones'] = Zone::getZones();
$this->tpl_list_vars['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
$this->tpl_list_vars['POST'] = $_POST;
return parent::renderList();
}
public function renderForm()
{
if (!($obj = $this->loadObject(true))) {
return;
}
$address_layout = AddressFormat::getAddressCountryFormat($obj->id);
if ($value = Tools::getValue('address_layout')) {
$address_layout = $value;
}
$default_layout = '';
// TODO: Use format from XML
$default_layout_tab = [
array('firstname', 'lastname'),
array('company'),
array('vat_number'),
array('address1'),
array('address2'),
array('postcode', 'city'),
array('Country:name'),
array('phone'),
];
foreach ($default_layout_tab as $line) {
$default_layout .= implode(' ', $line) . AddressFormat::FORMAT_NEW_LINE;
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Countries', array(), 'Admin.International.Feature'),
'icon' => 'icon-globe',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Country', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'required' => true,
'hint' => $this->trans('Country name', array(), 'Admin.International.Feature') . ' - ' . $this->trans('Invalid characters:', array(), 'Admin.Global') . ' &lt;&gt;;=#{} ',
),
array(
'type' => 'text',
'label' => $this->trans('ISO code', array(), 'Admin.International.Feature'),
'name' => 'iso_code',
'maxlength' => 3,
'class' => 'uppercase',
'required' => true,
'hint' => $this->trans('Two -- or three -- letter ISO code (e.g. "us" for United States).', array(), 'Admin.International.Help'),
/* @TODO - add two lines for the hint? */
/*'desc' => $this->l('Two -- or three -- letter ISO code (e.g. U.S. for United States)').'.
<a href="http://www.iso.org/iso/country_codes/iso_3166_code_lists/country_names_and_code_elements.htm" target="_blank">'.
$this->l('Official list here').'
</a>.'*/
),
array(
'type' => 'text',
'label' => $this->trans('Call prefix', array(), 'Admin.International.Feature'),
'name' => 'call_prefix',
'maxlength' => 3,
'class' => 'uppercase',
'required' => true,
'hint' => $this->trans('International call prefix, (e.g. 1 for United States).', array(), 'Admin.International.Help'),
),
array(
'type' => 'select',
'label' => $this->trans('Default currency', array(), 'Admin.International.Feature'),
'name' => 'id_currency',
'options' => array(
'query' => Currency::getCurrencies(false, true, true),
'id' => 'id_currency',
'name' => 'name',
'default' => array(
'label' => $this->trans('Default store currency', array(), 'Admin.International.Feature'),
'value' => 0,
),
),
),
array(
'type' => 'select',
'label' => $this->trans('Zone', array(), 'Admin.Global'),
'name' => 'id_zone',
'options' => array(
'query' => Zone::getZones(),
'id' => 'id_zone',
'name' => 'name',
),
'hint' => $this->trans('Geographical region.', array(), 'Admin.International.Help'),
),
array(
'type' => 'switch',
'label' => $this->trans('Does it need Zip/postal code?', array(), 'Admin.International.Feature'),
'name' => 'need_zip_code',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'need_zip_code_on',
'value' => 1,
'label' => $this->trans('Yes', array(), 'Admin.Global'),
),
array(
'id' => 'need_zip_code_off',
'value' => 0,
'label' => $this->trans('No', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'text',
'label' => $this->trans('Zip/postal code format', array(), 'Admin.International.Feature'),
'name' => 'zip_code_format',
'required' => true,
'desc' => $this->trans('Indicate the format of the postal code: use L for a letter, N for a number, and C for the country\'s ISO 3166-1 alpha-2 code. For example, NNNNN for the United States, France, Poland and many other; LNNNNLLL for Argentina, etc. If you do not want PrestaShop to verify the postal code for this country, leave it blank.', array(), 'Admin.International.Help'),
),
array(
'type' => 'address_layout',
'label' => $this->trans('Address format', array(), 'Admin.International.Feature'),
'name' => 'address_layout',
'address_layout' => $address_layout,
'encoding_address_layout' => urlencode($address_layout),
'encoding_default_layout' => urlencode($default_layout),
'display_valid_fields' => $this->displayValidFields(),
),
array(
'type' => 'switch',
'label' => $this->trans('Active', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
'hint' => $this->trans('Display this country to your customers (the selected country will always be displayed in the Back Office).', array(), 'Admin.International.Help'),
),
array(
'type' => 'switch',
'label' => $this->trans('Contains states', array(), 'Admin.International.Feature'),
'name' => 'contains_states',
'required' => false,
'values' => array(
array(
'id' => 'contains_states_on',
'value' => 1,
'label' => '<img src="../img/admin/enabled.gif" alt="' . $this->trans('Yes', array(), 'Admin.Global') . '" title="' . $this->trans('Yes', array(), 'Admin.Global') . '" />' . $this->trans('Yes', array(), 'Admin.Global'),
),
array(
'id' => 'contains_states_off',
'value' => 0,
'label' => '<img src="../img/admin/disabled.gif" alt="' . $this->trans('No', array(), 'Admin.Global') . '" title="' . $this->trans('No', array(), 'Admin.Global') . '" />' . $this->trans('No', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Do you need a tax identification number?', array(), 'Admin.International.Feature'),
'name' => 'need_identification_number',
'required' => false,
'values' => array(
array(
'id' => 'need_identification_number_on',
'value' => 1,
'label' => '<img src="../img/admin/enabled.gif" alt="' . $this->trans('Yes', array(), 'Admin.Global') . '" title="' . $this->trans('Yes', array(), 'Admin.Global') . '" />' . $this->trans('Yes', array(), 'Admin.Global'),
),
array(
'id' => 'need_identification_number_off',
'value' => 0,
'label' => '<img src="../img/admin/disabled.gif" alt="' . $this->trans('No', array(), 'Admin.Global') . '" title="' . $this->trans('No', array(), 'Admin.Global') . '" />' . $this->trans('No', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Display tax label (e.g. "Tax incl.")', array(), 'Admin.International.Feature'),
'name' => 'display_tax_label',
'required' => false,
'values' => array(
array(
'id' => 'display_tax_label_on',
'value' => 1,
'label' => '<img src="../img/admin/enabled.gif" alt="' . $this->trans('Yes', array(), 'Admin.Global') . '" title="' . $this->trans('Yes', array(), 'Admin.Global') . '" />' . $this->trans('Yes', array(), 'Admin.Global'),
),
array(
'id' => 'display_tax_label_off',
'value' => 0,
'label' => '<img src="../img/admin/disabled.gif" alt="' . $this->trans('No', array(), 'Admin.Global') . '" title="' . $this->trans('No', array(), 'Admin.Global') . '" />' . $this->trans('No', array(), 'Admin.Global'),
),
),
),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$this->fields_form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
return parent::renderForm();
}
public function processUpdate()
{
/** @var Country $country */
$country = $this->loadObject();
if (Validate::isLoadedObject($country) && Tools::getValue('id_zone')) {
$old_id_zone = $country->id_zone;
$results = Db::getInstance()->executeS('SELECT `id_state` FROM `' . _DB_PREFIX_ . 'state` WHERE `id_country` = ' . (int) $country->id . ' AND `id_zone` = ' . (int) $old_id_zone);
if ($results && count($results)) {
$ids = array();
foreach ($results as $res) {
$ids[] = (int) $res['id_state'];
}
if (count($ids)) {
$res = Db::getInstance()->execute(
'UPDATE `' . _DB_PREFIX_ . 'state`
SET `id_zone` = ' . (int) Tools::getValue('id_zone') . '
WHERE `id_state` IN (' . implode(',', $ids) . ')'
);
}
}
}
return parent::processUpdate();
}
public function postProcess()
{
if (!Tools::getValue('id_' . $this->table)) {
if (Validate::isLanguageIsoCode(Tools::getValue('iso_code')) && (int) Country::getByIso(Tools::getValue('iso_code'))) {
$this->errors[] = $this->trans('This ISO code already exists.You cannot create two countries with the same ISO code.', array(), 'Admin.International.Notification');
}
} elseif (Validate::isLanguageIsoCode(Tools::getValue('iso_code'))) {
$id_country = (int) Country::getByIso(Tools::getValue('iso_code'));
if ($id_country != 0 && $id_country != Tools::getValue('id_' . $this->table)) {
$this->errors[] = $this->trans('This ISO code already exists.You cannot create two countries with the same ISO code.', array(), 'Admin.International.Notification');
}
}
return parent::postProcess();
}
public function processSave()
{
if (!$this->id_object) {
$tmp_addr_format = new AddressFormat();
} else {
$tmp_addr_format = new AddressFormat($this->id_object);
}
$tmp_addr_format->format = Tools::getValue('address_layout');
if (!$tmp_addr_format->checkFormatFields()) {
$error_list = $tmp_addr_format->getErrorList();
foreach ($error_list as $error) {
$this->errors[] = $error;
}
}
if (strlen($tmp_addr_format->format) <= 0) {
$this->errors[] = $this->trans('Address format invalid', array(), 'Admin.Notifications.Error');
}
$country = parent::processSave();
if (!count($this->errors)) {
if (null === $tmp_addr_format->id_country) {
$tmp_addr_format->id_country = $country->id;
}
if (!$tmp_addr_format->save()) {
$this->errors[] = $this->trans('Invalid address layout %s', array(Db::getInstance()->getMsgError()), 'Admin.International.Notification');
}
}
return $country;
}
public function processStatus()
{
parent::processStatus();
/** @var Country $object */
if (Validate::isLoadedObject($object = $this->loadObject()) && $object->active == 1) {
return Country::addModuleRestrictions(array(), array(array('id_country' => $object->id)), array());
}
return false;
}
/**
* Allow the assignation of zone only if the form is displayed.
*/
protected function processBulkAffectZone()
{
$zone_to_affect = Tools::getValue('zone_to_affect');
if ($zone_to_affect && $zone_to_affect !== 0) {
parent::processBulkAffectZone();
}
if (Tools::getIsset('submitBulkAffectZonecountry')) {
$this->tpl_list_vars['assign_zone'] = true;
}
}
protected function displayValidFields()
{
/* The following translations are needed later - don't remove the comments!
$this->trans('Customer', array(), 'Admin.Global');
$this->l('Warehouse');
$this->trans('Country', array(), 'Admin.Global');
$this->l('State');
$this->l('Address');
*/
$html_tabnav = '<ul class="nav nav-tabs" id="custom-address-fields">';
$html_tabcontent = '<div class="tab-content" >';
$object_list = AddressFormat::getLiableClass('Address');
$object_list['Address'] = null;
// Get the available properties for each class
$i = 0;
$class_tab_active = 'active';
foreach ($object_list as $class_name => &$object) {
if ($i != 0) {
$class_tab_active = '';
}
$fields = array();
$html_tabnav .= '<li' . ($class_tab_active ? ' class="' . $class_tab_active . '"' : '') . '>
<a href="#availableListFieldsFor_' . $class_name . '"><i class="icon-caret-down"></i>&nbsp;' . Translate::getAdminTranslation($class_name, 'AdminCountries') . '</a></li>';
foreach (AddressFormat::getValidateFields($class_name) as $name) {
$fields[] = '<a href="javascript:void(0);" class="addPattern btn btn-default btn-xs" id="' . ($class_name == 'Address' ? $name : $class_name . ':' . $name) . '">
<i class="icon-plus-sign"></i>&nbsp;' . ObjectModel::displayFieldName($name, $class_name) . '</a>';
}
$html_tabcontent .= '
<div class="tab-pane availableFieldsList panel ' . $class_tab_active . '" id="availableListFieldsFor_' . $class_name . '">
' . implode(' ', $fields) . '</div>';
unset($object);
++$i;
}
$html_tabnav .= '</ul>';
$html_tabcontent .= '</div>';
return $html_tabnav . $html_tabcontent;
}
public static function displayCallPrefix($prefix)
{
return (int) $prefix ? '+' . $prefix : '-';
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,559 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;
class AdminDashboardControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->display = 'view';
parent::__construct();
if (Tools::isSubmit('profitability_conf') || Tools::isSubmit('submitOptionsconfiguration')) {
$this->fields_options = $this->getOptionFields();
}
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryUI('ui.datepicker');
$this->addJS(array(
_PS_JS_DIR_ . 'vendor/d3.v3.min.js',
__PS_BASE_URI__ . $this->admin_webpath . '/themes/' . $this->bo_theme . '/js/vendor/nv.d3.min.js',
_PS_JS_DIR_ . '/admin/dashboard.js',
));
$this->addCSS(__PS_BASE_URI__ . $this->admin_webpath . '/themes/' . $this->bo_theme . '/css/vendor/nv.d3.css');
}
public function initPageHeaderToolbar()
{
$this->page_header_toolbar_title = $this->trans('Dashboard', array(), 'Admin.Dashboard.Feature');
$this->page_header_toolbar_btn['switch_demo'] = array(
'desc' => $this->trans('Demo mode', array(), 'Admin.Dashboard.Feature'),
'icon' => 'process-icon-toggle-' . (Configuration::get('PS_DASHBOARD_SIMULATION') ? 'on' : 'off'),
'help' => $this->trans('This mode displays sample data so you can try your dashboard without real numbers.', array(), 'Admin.Dashboard.Help'),
);
parent::initPageHeaderToolbar();
// Remove the last element on this controller to match the title with the rule of the others
array_pop($this->meta_title);
}
protected function getOptionFields()
{
$forms = array();
$currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
$carriers = Carrier::getCarriers((int) $this->context->language->id, true, false, false, null, Carrier::ALL_CARRIERS);
$modules = Module::getModulesOnDisk(true);
$forms = array(
'payment' => array('title' => $this->trans('Average bank fees per payment method', array(), 'Admin.Dashboard.Feature'), 'id' => 'payment'),
'carriers' => array('title' => $this->trans('Average shipping fees per shipping method', array(), 'Admin.Dashboard.Feature'), 'id' => 'carriers'),
'other' => array('title' => $this->trans('Other settings', array(), 'Admin.Dashboard.Feature'), 'id' => 'other'),
);
foreach ($forms as &$form) {
$form['icon'] = 'tab-preferences';
$form['fields'] = array();
$form['submit'] = array('title' => $this->trans('Save', array(), 'Admin.Actions'));
}
foreach ($modules as $module) {
if (isset($module->tab) && $module->tab == 'payments_gateways' && $module->id) {
$moduleClass = Module::getInstanceByName($module->name);
if (!$moduleClass->isEnabledForShopContext()) {
continue;
}
$forms['payment']['fields']['CONF_' . strtoupper($module->name) . '_FIXED'] = array(
'title' => $module->displayName,
'desc' => $this->trans(
'Choose a fixed fee for each order placed in %currency% with %module%.',
array(
'%currency' => $currency->iso_code,
'%module%' => $module->displayName,
),
'Admin.Dashboard.Help'
),
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
'defaultValue' => '0',
'suffix' => $currency->iso_code,
);
$forms['payment']['fields']['CONF_' . strtoupper($module->name) . '_VAR'] = array(
'title' => $module->displayName,
'desc' => $this->trans(
'Choose a variable fee for each order placed in %currency% with %module%. It will be applied on the total paid with taxes.',
array(
'%currency' => $currency->iso_code,
'%module%' => $module->displayName,
),
'Admin.Dashboard.Help'
),
'validation' => 'isPercentage',
'cast' => 'floatval',
'type' => 'text',
'defaultValue' => '0',
'suffix' => '%',
);
if (Currency::isMultiCurrencyActivated()) {
$forms['payment']['fields']['CONF_' . strtoupper($module->name) . '_FIXED_FOREIGN'] = array(
'title' => $module->displayName,
'desc' => $this->trans(
'Choose a fixed fee for each order placed with a foreign currency with %module%.',
array(
'%module%' => $module->displayName,
),
'Admin.Dashboard.Help'
),
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
'defaultValue' => '0',
'suffix' => $currency->iso_code,
);
$forms['payment']['fields']['CONF_' . strtoupper($module->name) . '_VAR_FOREIGN'] = array(
'title' => $module->displayName,
'desc' => $this->trans(
'Choose a variable fee for each order placed with a foreign currency with %module%. It will be applied on the total paid with taxes.',
array('%module%' => $module->displayName),
'Admin.Dashboard.Help'
),
'validation' => 'isPercentage',
'cast' => 'floatval',
'type' => 'text',
'defaultValue' => '0',
'suffix' => '%',
);
}
}
}
foreach ($carriers as $carrier) {
$forms['carriers']['fields']['CONF_' . strtoupper($carrier['id_reference']) . '_SHIP'] = array(
'title' => $carrier['name'],
'desc' => $this->trans(
'For the carrier named %s, indicate the domestic delivery costs in percentage of the price charged to customers.',
array(
'%s' => $carrier['name'],
),
'Admin.Dashboard.Help'
),
'validation' => 'isPercentage',
'cast' => 'floatval',
'type' => 'text',
'defaultValue' => '0',
'suffix' => '%',
);
$forms['carriers']['fields']['CONF_' . strtoupper($carrier['id_reference']) . '_SHIP_OVERSEAS'] = array(
'title' => $carrier['name'],
'desc' => $this->trans(
'For the carrier named %s, indicate the overseas delivery costs in percentage of the price charged to customers.',
array(
'%s' => $carrier['name'],
),
'Admin.Dashboard.Help'
),
'validation' => 'isPercentage',
'cast' => 'floatval',
'type' => 'text',
'defaultValue' => '0',
'suffix' => '%',
);
}
$forms['carriers']['description'] = $this->trans('Method: Indicate the percentage of your carrier margin. For example, if you charge $10 of shipping fees to your customer for each shipment, but you really pay $4 to this carrier, then you should indicate "40" in the percentage field.', array(), 'Admin.Dashboard.Help');
$forms['other']['fields']['CONF_AVERAGE_PRODUCT_MARGIN'] = array(
'title' => $this->trans('Average gross margin percentage', array(), 'Admin.Dashboard.Feature'),
'desc' => $this->trans('You should calculate this percentage as follows: ((total sales revenue) - (cost of goods sold)) / (total sales revenue) * 100. This value is only used to calculate the Dashboard approximate gross margin, if you do not specify the wholesale price for each product.', array(), 'Admin.Dashboard.Help'),
'validation' => 'isPercentage',
'cast' => 'intval',
'type' => 'text',
'defaultValue' => '0',
'suffix' => '%',
);
$forms['other']['fields']['CONF_ORDER_FIXED'] = array(
'title' => $this->trans('Other fees per order', array(), 'Admin.Dashboard.Feature'),
'desc' => $this->trans('You should calculate this value by making the sum of all of your additional costs per order.', array(), 'Admin.Dashboard.Help'),
'validation' => 'isPrice',
'cast' => 'floatval',
'type' => 'text',
'defaultValue' => '0',
'suffix' => $currency->iso_code,
);
Media::addJsDef(array(
'dashboard_ajax_url' => $this->context->link->getAdminLink('AdminDashboard'),
'read_more' => '',
));
return $forms;
}
public function renderView()
{
if (Tools::isSubmit('profitability_conf')) {
return parent::renderOptions();
}
// $translations = array(
// 'Calendar' => $this->trans('Calendar', array(),'Admin.Global'),
// 'Day' => $this->trans('Day', array(), 'Admin.Global'),
// 'Month' => $this->trans('Month', array(), 'Admin.Global'),
// 'Year' => $this->trans('Year', array(), 'Admin.Global'),
// 'From' => $this->trans('From:', array(), 'Admin.Global'),
// 'To' => $this->trans('To:', array(), 'Admin.Global'),
// 'Save' => $this->trans('Save', array(), 'Admin.Global')
// );
$testStatsDateUpdate = $this->context->cookie->__get('stats_date_update');
if (!empty($testStatsDateUpdate) && $this->context->cookie->__get('stats_date_update') < strtotime(date('Y-m-d'))) {
switch ($this->context->employee->preselect_date_range) {
case 'day':
$date_from = date('Y-m-d');
$date_to = date('Y-m-d');
break;
case 'prev-day':
$date_from = date('Y-m-d', strtotime('-1 day'));
$date_to = date('Y-m-d', strtotime('-1 day'));
break;
case 'month':
default:
$date_from = date('Y-m-01');
$date_to = date('Y-m-d');
break;
case 'prev-month':
$date_from = date('Y-m-01', strtotime('-1 month'));
$date_to = date('Y-m-t', strtotime('-1 month'));
break;
case 'year':
$date_from = date('Y-01-01');
$date_to = date('Y-m-d');
break;
case 'prev-year':
$date_from = date('Y-m-01', strtotime('-1 year'));
$date_to = date('Y-12-t', strtotime('-1 year'));
break;
}
$this->context->employee->stats_date_from = $date_from;
$this->context->employee->stats_date_to = $date_to;
$this->context->employee->update();
$this->context->cookie->__set('stats_date_update', strtotime(date('Y-m-d')));
$this->context->cookie->write();
}
$calendar_helper = new HelperCalendar();
$calendar_helper->setDateFrom(Tools::getValue('date_from', $this->context->employee->stats_date_from));
$calendar_helper->setDateTo(Tools::getValue('date_to', $this->context->employee->stats_date_to));
$stats_compare_from = $this->context->employee->stats_compare_from;
$stats_compare_to = $this->context->employee->stats_compare_to;
if (null === $stats_compare_from || $stats_compare_from == '0000-00-00') {
$stats_compare_from = null;
}
if (null === $stats_compare_to || $stats_compare_to == '0000-00-00') {
$stats_compare_to = null;
}
$calendar_helper->setCompareDateFrom($stats_compare_from);
$calendar_helper->setCompareDateTo($stats_compare_to);
$calendar_helper->setCompareOption(Tools::getValue('compare_date_option', $this->context->employee->stats_compare_option));
$params = array(
'date_from' => $this->context->employee->stats_date_from,
'date_to' => $this->context->employee->stats_date_to,
);
$moduleManagerBuilder = ModuleManagerBuilder::getInstance();
$moduleManager = $moduleManagerBuilder->build();
$this->tpl_view_vars = array(
'date_from' => $this->context->employee->stats_date_from,
'date_to' => $this->context->employee->stats_date_to,
'hookDashboardZoneOne' => Hook::exec('dashboardZoneOne', $params),
'hookDashboardZoneTwo' => Hook::exec('dashboardZoneTwo', $params),
//'translations' => $translations,
'action' => '#',
'warning' => $this->getWarningDomainName(),
'new_version_url' => Tools::getCurrentUrlProtocolPrefix() . _PS_API_DOMAIN_ . '/version/check_version.php?v=' . _PS_VERSION_ . '&lang=' . $this->context->language->iso_code . '&autoupgrade=' . (int) ($moduleManager->isInstalled('autoupgrade') && $moduleManager->isEnabled('autoupgrade')) . '&hosted_mode=' . (int) defined('_PS_HOST_MODE_'),
'dashboard_use_push' => Configuration::get('PS_DASHBOARD_USE_PUSH'),
'calendar' => $calendar_helper->generate(),
'PS_DASHBOARD_SIMULATION' => Configuration::get('PS_DASHBOARD_SIMULATION'),
'datepickerFrom' => Tools::getValue('datepickerFrom', $this->context->employee->stats_date_from),
'datepickerTo' => Tools::getValue('datepickerTo', $this->context->employee->stats_date_to),
'preselect_date_range' => Tools::getValue('preselectDateRange', $this->context->employee->preselect_date_range),
'help_center_link' => $this->getHelpCenterLink($this->context->language->iso_code),
);
return parent::renderView();
}
public function postProcess()
{
if (Tools::isSubmit('submitDateRealTime')) {
if ($use_realtime = (int) Tools::getValue('submitDateRealTime')) {
$this->context->employee->stats_date_from = date('Y-m-d');
$this->context->employee->stats_date_to = date('Y-m-d');
$this->context->employee->stats_compare_option = HelperCalendar::DEFAULT_COMPARE_OPTION;
$this->context->employee->stats_compare_from = null;
$this->context->employee->stats_compare_to = null;
$this->context->employee->update();
}
Configuration::updateValue('PS_DASHBOARD_USE_PUSH', $use_realtime);
}
if (Tools::isSubmit('submitDateRange')) {
if (!Validate::isDate(Tools::getValue('date_from'))
|| !Validate::isDate(Tools::getValue('date_to'))) {
$this->errors[] = $this->trans('The selected date range is not valid.', array(), 'Admin.Notifications.Error');
}
if (Tools::getValue('datepicker_compare')) {
if (!Validate::isDate(Tools::getValue('compare_date_from'))
|| !Validate::isDate(Tools::getValue('compare_date_to'))) {
$this->errors[] = $this->trans('The selected date range is not valid.', array(), 'Admin.Notifications.Error');
}
}
if (!count($this->errors)) {
$this->context->employee->stats_date_from = Tools::getValue('date_from');
$this->context->employee->stats_date_to = Tools::getValue('date_to');
$this->context->employee->preselect_date_range = Tools::getValue('preselectDateRange');
if (Tools::getValue('datepicker_compare')) {
$this->context->employee->stats_compare_from = Tools::getValue('compare_date_from');
$this->context->employee->stats_compare_to = Tools::getValue('compare_date_to');
$this->context->employee->stats_compare_option = Tools::getValue('compare_date_option');
} else {
$this->context->employee->stats_compare_from = null;
$this->context->employee->stats_compare_to = null;
$this->context->employee->stats_compare_option = HelperCalendar::DEFAULT_COMPARE_OPTION;
}
$this->context->employee->update();
}
}
parent::postProcess();
}
protected function getWarningDomainName()
{
$warning = false;
if (Shop::isFeatureActive()) {
return;
}
$shop = Context::getContext()->shop;
if ($_SERVER['HTTP_HOST'] != $shop->domain && $_SERVER['HTTP_HOST'] != $shop->domain_ssl && Tools::getValue('ajax') == false && !defined('_PS_HOST_MODE_')) {
$warning = $this->trans('You are currently connected under the following domain name:', array(), 'Admin.Dashboard.Notification') . ' <span style="color: #CC0000;">' . $_SERVER['HTTP_HOST'] . '</span><br />';
if (Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE')) {
$warning .= $this->trans(
'This is different from the shop domain name set in the Multistore settings: "%s".',
array(
'%s' => $shop->domain,
),
'Admin.Dashboard.Notification'
) . $this->trans(
'If this is your main domain, please {link}change it now{/link}.',
array(
'{link}' => '<a href="index.php?controller=AdminShopUrl&id_shop_url=' . (int) $shop->id . '&updateshop_url&token=' . Tools::getAdminTokenLite('AdminShopUrl') . '">',
'{/link}' => '</a>',
),
'Admin.Dashboard.Notification'
);
} else {
$warning .= $this->trans('This is different from the domain name set in the "SEO & URLs" tab.', array(), 'Admin.Dashboard.Notification') . '
' . $this->trans(
'If this is your main domain, please {link}change it now{/link}.',
array(
'{link}' => '<a href="index.php?controller=AdminMeta&token=' . Tools::getAdminTokenLite('AdminMeta') . '#meta_fieldset_shop_url">',
'{/link}' => '</a>',
),
'Admin.Dashboard.Notification'
);
}
}
return $warning;
}
public function ajaxProcessRefreshDashboard()
{
$id_module = null;
if ($module = Tools::getValue('module')) {
$module_obj = Module::getInstanceByName($module);
if (Validate::isLoadedObject($module_obj)) {
$id_module = $module_obj->id;
}
}
$params = array(
'date_from' => $this->context->employee->stats_date_from,
'date_to' => $this->context->employee->stats_date_to,
'compare_from' => $this->context->employee->stats_compare_from,
'compare_to' => $this->context->employee->stats_compare_to,
'dashboard_use_push' => (int) Tools::getValue('dashboard_use_push'),
'extra' => (int) Tools::getValue('extra'),
);
die(json_encode(Hook::exec('dashboardData', $params, $id_module, true, true, (int) Tools::getValue('dashboard_use_push'))));
}
public function ajaxProcessSetSimulationMode()
{
Configuration::updateValue('PS_DASHBOARD_SIMULATION', (int) Tools::getValue('PS_DASHBOARD_SIMULATION'));
die('k' . Configuration::get('PS_DASHBOARD_SIMULATION') . 'k');
}
public function ajaxProcessGetBlogRss()
{
$return = array('has_errors' => false, 'rss' => array());
if (!$this->isFresh('/config/xml/blog-' . $this->context->language->iso_code . '.xml', 86400)) {
if (!$this->refresh('/config/xml/blog-' . $this->context->language->iso_code . '.xml', _PS_API_URL_ . '/rss/blog/blog-' . $this->context->language->iso_code . '.xml')) {
$return['has_errors'] = true;
}
}
if (!$return['has_errors']) {
$rss = @simplexml_load_file(_PS_ROOT_DIR_ . '/config/xml/blog-' . $this->context->language->iso_code . '.xml');
if (!$rss) {
$return['has_errors'] = true;
}
$articles_limit = 2;
if ($rss) {
foreach ($rss->channel->item as $item) {
if ($articles_limit > 0 && Validate::isCleanHtml((string) $item->title) && Validate::isCleanHtml((string) $item->description)
&& isset($item->link, $item->title)) {
if (in_array($this->context->mode, array(Context::MODE_HOST, Context::MODE_HOST_CONTRIB))) {
$utm_content = 'cloud';
} else {
$utm_content = 'download';
}
$shop_default_country_id = (int) Configuration::get('PS_COUNTRY_DEFAULT');
$shop_default_iso_country = (string) Tools::strtoupper(Country::getIsoById($shop_default_country_id));
$analytics_params = array('utm_source' => 'back-office',
'utm_medium' => 'rss',
'utm_campaign' => 'back-office-' . $shop_default_iso_country,
'utm_content' => $utm_content,
);
$url_query = parse_url($item->link, PHP_URL_QUERY);
parse_str($url_query, $link_query_params);
if ($link_query_params) {
$full_url_params = array_merge($link_query_params, $analytics_params);
$base_url = explode('?', (string) $item->link);
$base_url = (string) $base_url[0];
$article_link = $base_url . '?' . http_build_query($full_url_params);
} else {
$article_link = (string) $item->link . '?' . http_build_query($analytics_params);
}
$return['rss'][] = array(
'date' => Tools::displayDate(date('Y-m-d', strtotime((string) $item->pubDate))),
'title' => (string) Tools::htmlentitiesUTF8($item->title),
'short_desc' => Tools::truncateString(strip_tags((string) $item->description), 150),
'link' => (string) $article_link,
);
} else {
break;
}
--$articles_limit;
}
}
}
die(json_encode($return));
}
public function ajaxProcessSaveDashConfig()
{
$return = array('has_errors' => false, 'errors' => array());
$module = Tools::getValue('module');
$hook = Tools::getValue('hook');
$configs = Tools::getValue('configs');
$params = array(
'date_from' => $this->context->employee->stats_date_from,
'date_to' => $this->context->employee->stats_date_to,
);
if (Validate::isModuleName($module) && $module_obj = Module::getInstanceByName($module)) {
$return['errors'] = $module_obj->validateDashConfig($configs);
if (count($return['errors'])) {
$return['has_errors'] = true;
} else {
$return['has_errors'] = $module_obj->saveDashConfig($configs);
}
}
if (Validate::isHookName($hook) && method_exists($module_obj, $hook)) {
$return['widget_html'] = $module_obj->$hook($params);
}
die(json_encode($return));
}
/**
* Returns the Help center link for the provided locale
*
* @param string $languageCode 2-letter locale code
*
* @return string
*/
private function getHelpCenterLink($languageCode)
{
$links = [
'fr' => 'https://www.prestashop.com/fr/contact?utm_source=back-office&utm_medium=links&utm_campaign=help-center-fr&utm_content=download17',
'en' => 'https://www.prestashop.com/en/contact?utm_source=back-office&utm_medium=links&utm_campaign=help-center-en&utm_content=download17',
'es' => 'https://www.prestashop.com/es/contacto?utm_source=back-office&utm_medium=links&utm_campaign=help-center-es&utm_content=download17',
'de' => 'https://www.prestashop.com/de/kontakt?utm_source=back-office&utm_medium=links&utm_campaign=help-center-de&utm_content=download17',
'it' => 'https://www.prestashop.com/it/contatti?utm_source=back-office&utm_medium=links&utm_campaign=help-center-it&utm_content=download17',
'nl' => 'https://www.prestashop.com/nl/contacteer-ons?utm_source=back-office&utm_medium=links&utm_campaign=help-center-nl&utm_content=download17',
'pt' => 'https://www.prestashop.com/pt/contato?utm_source=back-office&utm_medium=links&utm_campaign=help-center-pt&utm_content=download17',
'pl' => 'https://www.prestashop.com/pl/kontakt?utm_source=back-office&utm_medium=links&utm_campaign=help-center-pl&utm_content=download17',
];
return isset($links[$languageCode]) ? $links[$languageCode] : $links['en'];
}
}

View File

@@ -0,0 +1,656 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Feature $object
*/
class AdminFeaturesControllerCore extends AdminController
{
public $bootstrap = true;
protected $position_identifier = 'id_feature';
protected $feature_name;
public function __construct()
{
$this->table = 'feature';
$this->className = 'Feature';
$this->list_id = 'feature';
$this->identifier = 'id_feature';
$this->lang = true;
parent::__construct();
$this->fields_list = array(
'id_feature' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'width' => 'auto',
'filter_key' => 'b!name',
),
'value' => array(
'title' => $this->trans('Values', array(), 'Admin.Global'),
'orderby' => false,
'search' => false,
'align' => 'center',
'class' => 'fixed-width-xs',
),
'position' => array(
'title' => $this->trans('Position', array(), 'Admin.Global'),
'filter_key' => 'a!position',
'align' => 'center',
'class' => 'fixed-width-xs',
'position' => 'position',
),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'icon' => 'icon-trash',
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
),
);
}
/**
* AdminController::renderList() override.
*
* @see AdminController::renderList()
*/
public function renderList()
{
$this->addRowAction('view');
$this->addRowAction('edit');
$this->addRowAction('delete');
return parent::renderList();
}
/**
* Change object type to feature value (use when processing a feature value).
*/
protected function setTypeValue()
{
$this->table = 'feature_value';
$this->className = 'FeatureValue';
$this->identifier = 'id_feature_value';
}
/**
* Change object type to feature (use when processing a feature).
*/
protected function setTypeFeature()
{
$this->table = 'feature';
$this->className = 'Feature';
$this->identifier = 'id_feature';
}
public function renderView()
{
if (($id = (int) Tools::getValue('id_feature'))) {
$this->setTypeValue();
$this->list_id = 'feature_value';
$this->lang = true;
// Action for list
$this->addRowAction('edit');
$this->addRowAction('delete');
if (!Validate::isLoadedObject($obj = new Feature((int) $id))) {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error') . ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
return;
}
$this->feature_name = $obj->name;
$this->toolbar_title = $this->feature_name[$this->context->employee->id_lang];
$this->fields_list = array(
'id_feature_value' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'value' => array(
'title' => $this->trans('Value', array(), 'Admin.Global'),
),
);
$this->_where = sprintf('AND `id_feature` = %d', (int) $id);
self::$currentIndex = self::$currentIndex . '&id_feature=' . (int) $id . '&viewfeature';
$this->processFilter();
return parent::renderList();
}
}
/**
* AdminController::renderForm() override.
*
* @see AdminController::renderForm()
*/
public function renderForm()
{
$this->toolbar_title = $this->trans('Add a new feature', array(), 'Admin.Catalog.Feature');
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Feature', array(), 'Admin.Catalog.Feature'),
'icon' => 'icon-info-sign',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'size' => 33,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' <>;=#{}',
'required' => true,
),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$this->fields_form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
return parent::renderForm();
}
public function initPageHeaderToolbar()
{
if (Feature::isFeatureActive()) {
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_feature'] = array(
'href' => self::$currentIndex . '&addfeature&token=' . $this->token,
'desc' => $this->trans('Add new feature', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
$this->page_header_toolbar_btn['new_feature_value'] = array(
'href' => self::$currentIndex . '&addfeature_value&id_feature=' . (int) Tools::getValue('id_feature') . '&token=' . $this->token,
'desc' => $this->trans('Add new feature value', array(), 'Admin.Catalog.Help'),
'icon' => 'process-icon-new',
);
}
}
if ($this->display == 'view') {
$this->page_header_toolbar_btn['new_feature_value'] = array(
'href' => self::$currentIndex . '&addfeature_value&id_feature=' . (int) Tools::getValue('id_feature') . '&token=' . $this->token,
'desc' => $this->trans('Add new feature value', array(), 'Admin.Catalog.Help'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
/**
* AdminController::initToolbar() override.
*
* @see AdminController::initToolbar()
*/
public function initToolbar()
{
switch ($this->display) {
case 'editFeatureValue':
case 'add':
case 'edit':
$this->toolbar_btn['save'] = array(
'href' => '#',
'desc' => $this->trans('Save', array(), 'Admin.Actions'),
);
if ($this->display == 'editFeatureValue') {
$this->toolbar_btn['save-and-stay'] = array(
'short' => 'SaveAndStay',
'href' => '#',
'desc' => $this->trans('Save and add another value', array(), 'Admin.Catalog.Help'),
'force_desc' => true,
);
}
// Default cancel button - like old back link
$back = Tools::safeOutput(Tools::getValue('back', ''));
if (empty($back)) {
$back = self::$currentIndex . '&token=' . $this->token;
}
$this->toolbar_btn['back'] = array(
'href' => $back,
'desc' => $this->trans('Back to the list', array(), 'Admin.Catalog.Help'),
);
break;
case 'view':
$this->toolbar_btn['newAttributes'] = array(
'href' => self::$currentIndex . '&addfeature_value&id_feature=' . (int) Tools::getValue('id_feature') . '&token=' . $this->token,
'desc' => $this->trans('Add new feature values', array(), 'Admin.Catalog.Help'),
);
$this->toolbar_btn['back'] = array(
'href' => self::$currentIndex . '&token=' . $this->token,
'desc' => $this->trans('Back to the list', array(), 'Admin.Catalog.Help'),
);
break;
default:
parent::initToolbar();
}
}
public function initToolbarTitle()
{
$bread_extended = $this->breadcrumbs;
switch ($this->display) {
case 'edit':
$bread_extended[] = $this->trans('Edit New Feature', array(), 'Admin.Catalog.Feature');
$this->addMetaTitle($bread_extended[count($bread_extended) - 1]);
break;
case 'add':
$bread_extended[] = $this->trans('Add New Feature', array(), 'Admin.Catalog.Feature');
$this->addMetaTitle($bread_extended[count($bread_extended) - 1]);
break;
case 'view':
$bread_extended[] = $this->feature_name[$this->context->employee->id_lang];
$this->addMetaTitle($bread_extended[count($bread_extended) - 1]);
break;
case 'editFeatureValue':
if (Tools::getValue('id_feature_value')) {
if (($id = (int) Tools::getValue('id_feature'))) {
if (Validate::isLoadedObject($obj = new Feature((int) $id))) {
$bread_extended[] = '<a href="' . Context::getContext()->link->getAdminLink('AdminFeatures') . '&id_feature=' . $id . '&viewfeature">' . $obj->name[$this->context->employee->id_lang] . '</a>';
}
if (Validate::isLoadedObject($obj = new FeatureValue((int) Tools::getValue('id_feature_value')))) {
$bread_extended[] = $this->trans('Edit: %value%', array('%value%' => $obj->value[$this->context->employee->id_lang]), 'Admin.Catalog.Feature');
}
} else {
$bread_extended[] = $this->trans('Edit Value', array(), 'Admin.Catalog.Feature');
}
} else {
$bread_extended[] = $this->trans('Add New Value', array(), 'Admin.Catalog.Feature');
}
if (count($bread_extended) > 0) {
$this->addMetaTitle($bread_extended[count($bread_extended) - 1]);
}
break;
}
$this->toolbar_title = $bread_extended;
}
/**
* AdminController::renderForm() override.
*
* @see AdminController::renderForm()
*/
public function initFormFeatureValue()
{
$this->setTypeValue();
$this->fields_form[0]['form'] = array(
'legend' => array(
'title' => $this->trans('Feature value', array(), 'Admin.Catalog.Feature'),
'icon' => 'icon-info-sign',
),
'input' => array(
array(
'type' => 'select',
'label' => $this->trans('Feature', array(), 'Admin.Catalog.Feature'),
'name' => 'id_feature',
'options' => array(
'query' => Feature::getFeatures($this->context->language->id),
'id' => 'id_feature',
'name' => 'name',
),
'required' => true,
),
array(
'type' => 'text',
'label' => $this->trans('Value', array(), 'Admin.Global'),
'name' => 'value',
'lang' => true,
'size' => 33,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' <>;=#{}',
'required' => true,
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
'buttons' => array(
'save-and-stay' => array(
'title' => $this->trans('Save then add another value', array(), 'Admin.Catalog.Feature'),
'name' => 'submitAdd' . $this->table . 'AndStay',
'type' => 'submit',
'class' => 'btn btn-default pull-right',
'icon' => 'process-icon-save',
),
),
);
$this->fields_value['id_feature'] = (int) Tools::getValue('id_feature');
// Create Object FeatureValue
$feature_value = new FeatureValue(Tools::getValue('id_feature_value'));
$this->tpl_vars = array(
'feature_value' => $feature_value,
);
$this->getlanguages();
$helper = new HelperForm();
$helper->show_cancel_button = true;
$back = Tools::safeOutput(Tools::getValue('back', ''));
if (empty($back)) {
$back = self::$currentIndex . '&token=' . $this->token;
}
if (!Validate::isCleanHtml($back)) {
die(Tools::displayError());
}
$helper->back_url = $back;
$helper->currentIndex = self::$currentIndex;
$helper->token = $this->token;
$helper->table = $this->table;
$helper->identifier = $this->identifier;
$helper->override_folder = 'feature_value/';
$helper->id = $feature_value->id;
$helper->toolbar_scroll = false;
$helper->tpl_vars = $this->tpl_vars;
$helper->languages = $this->_languages;
$helper->default_form_language = $this->default_form_language;
$helper->allow_employee_form_lang = $this->allow_employee_form_lang;
$helper->fields_value = $this->getFieldsValue($feature_value);
$helper->toolbar_btn = $this->toolbar_btn;
$helper->title = $this->trans('Add a new feature value', array(), 'Admin.Catalog.Feature');
$this->content .= $helper->generateForm($this->fields_form);
}
/**
* AdminController::initContent() override.
*
* @see AdminController::initContent()
*/
public function initContent()
{
if (Feature::isFeatureActive()) {
if ($this->display == 'edit' || $this->display == 'add') {
if (!$this->loadObject(true)) {
return;
}
$this->content .= $this->renderForm();
} elseif ($this->display == 'view') {
// Some controllers use the view action without an object
if ($this->className) {
$this->loadObject(true);
}
$this->content .= $this->renderView();
} elseif ($this->display == 'editFeatureValue') {
if (!$this->object = new FeatureValue((int) Tools::getValue('id_feature_value'))) {
return;
}
$this->content .= $this->initFormFeatureValue();
} elseif ($this->display != 'view' && !$this->ajax) {
// If a feature value was saved, we need to reset the values to display the list
$this->setTypeFeature();
$this->content .= $this->renderList();
/* reset all attributes filter */
if (!Tools::getValue('submitFilterfeature_value', 0) && !Tools::getIsset('id_feature_value')) {
$this->processResetFilters('feature_value');
}
}
} else {
$adminPerformanceUrl = $this->context->link->getAdminLink('AdminPerformance');
$url = '<a href="' . $adminPerformanceUrl . '#featuresDetachables">' . $this->trans('Performance', array(), 'Admin.Global') . '</a>';
$this->displayWarning($this->trans('This feature has been disabled. You can activate it here: %url%.', array('%url%' => $url), 'Admin.Catalog.Notification'));
}
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
public function initProcess()
{
// Are we working on feature values?
if (Tools::getValue('id_feature_value')
|| Tools::isSubmit('deletefeature_value')
|| Tools::isSubmit('submitAddfeature_value')
|| Tools::isSubmit('addfeature_value')
|| Tools::isSubmit('updatefeature_value')
|| Tools::isSubmit('submitBulkdeletefeature_value')) {
$this->setTypeValue();
}
if (Tools::getIsset('viewfeature')) {
$this->list_id = 'feature_value';
if (isset($_POST['submitReset' . $this->list_id])) {
$this->processResetFilters();
}
} else {
$this->list_id = 'feature';
$this->_defaultOrderBy = 'position';
$this->_defaultOrderWay = 'ASC';
}
parent::initProcess();
}
public function postProcess()
{
if (!Feature::isFeatureActive()) {
return;
}
/* set location with current index */
if (Tools::getIsset('id_feature') && Tools::getIsset('viewfeature')) {
self::$currentIndex = self::$currentIndex . '&id_feature=' . Tools::getValue('id_feature', 0) . '&viewfeature';
}
if ($this->table == 'feature_value' && ($this->action == 'save' || $this->action == 'delete' || $this->action == 'bulkDelete')) {
Hook::exec(
'displayFeatureValuePostProcess',
array('errors' => &$this->errors)
);
} // send errors as reference to allow displayFeatureValuePostProcess to stop saving process
else {
Hook::exec(
'displayFeaturePostProcess',
array('errors' => &$this->errors)
);
} // send errors as reference to allow displayFeaturePostProcess to stop saving process
parent::postProcess();
if ($this->table == 'feature_value' && ($this->display == 'edit' || $this->display == 'add')) {
$this->display = 'editFeatureValue';
}
}
/**
* Override processAdd to change SaveAndStay button action.
*
* @see classes/AdminControllerCore::processAdd()
*/
public function processAdd()
{
$object = parent::processAdd();
if (Tools::isSubmit('submitAdd' . $this->table . 'AndStay') && !count($this->errors)) {
if ($this->table == 'feature_value' && ($this->display == 'edit' || $this->display == 'add')) {
$this->redirect_after = self::$currentIndex . '&addfeature_value&id_feature=' . (int) Tools::getValue('id_feature') . '&token=' . $this->token;
} else {
$this->redirect_after = self::$currentIndex . '&' . $this->identifier . '=&conf=3&update' . $this->table . '&token=' . $this->token;
}
} elseif (Tools::isSubmit('submitAdd' . $this->table . 'AndStay') && count($this->errors)) {
$this->display = 'editFeatureValue';
}
return $object;
}
/**
* Override processUpdate to change SaveAndStay button action.
*
* @see classes/AdminControllerCore::processUpdate()
*/
public function processUpdate()
{
$object = parent::processUpdate();
if (Tools::isSubmit('submitAdd' . $this->table . 'AndStay') && !count($this->errors)) {
$this->redirect_after = self::$currentIndex . '&' . $this->identifier . '=&conf=3&update' . $this->table . '&token=' . $this->token;
}
return $object;
}
/**
* Call the right method for creating or updating object.
*
* @return mixed
*/
public function processSave()
{
if ($this->table == 'feature') {
$id_feature = (int) Tools::getValue('id_feature');
// Adding last position to the feature if not exist
if ($id_feature <= 0) {
$sql = 'SELECT `position`+1
FROM `' . _DB_PREFIX_ . 'feature`
ORDER BY position DESC';
// set the position of the new feature in $_POST for postProcess() method
$_POST['position'] = Db::getInstance()->getValue($sql);
}
// clean \n\r characters
foreach ($_POST as $key => $value) {
if (preg_match('/^name_/Ui', $key)) {
$_POST[$key] = str_replace('\n', '', str_replace('\r', '', $value));
}
}
}
return parent::processSave();
}
/**
* AdminController::getList() override.
*
* @see AdminController::getList()
*
* @param int $id_lang
* @param string|null $order_by
* @param string|null $order_way
* @param int $start
* @param int|null $limit
* @param int|bool $id_lang_shop
*
* @throws PrestaShopException
*/
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
if ($this->table == 'feature_value') {
$this->_where .= ' AND (a.custom = 0 OR a.custom IS NULL)';
}
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
if ($this->table == 'feature') {
$nb_items = count($this->_list);
for ($i = 0; $i < $nb_items; ++$i) {
$item = &$this->_list[$i];
$query = new DbQuery();
$query->select('COUNT(fv.id_feature_value) as count_values');
$query->from('feature_value', 'fv');
$query->where('fv.id_feature =' . (int) $item['id_feature']);
$query->where('(fv.custom=0 OR fv.custom IS NULL)');
$res = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
$item['value'] = (int) $res;
unset($query);
}
}
}
public function ajaxProcessUpdatePositions()
{
if ($this->access('edit')) {
$way = (int) Tools::getValue('way');
$id_feature = (int) Tools::getValue('id');
$positions = Tools::getValue('feature');
$new_positions = array();
foreach ($positions as $v) {
if (!empty($v)) {
$new_positions[] = $v;
}
}
foreach ($new_positions as $position => $value) {
$pos = explode('_', $value);
if (isset($pos[2]) && (int) $pos[2] === $id_feature) {
if ($feature = new Feature((int) $pos[2])) {
if (isset($position) && $feature->updatePosition($way, $position, $id_feature)) {
echo 'ok position ' . (int) $position . ' for feature ' . (int) $pos[1] . '\r\n';
} else {
echo '{"hasError" : true, "errors" : "Can not update feature ' . (int) $id_feature . ' to position ' . (int) $position . ' "}';
}
} else {
echo '{"hasError" : true, "errors" : "This feature (' . (int) $id_feature . ') can t be loaded"}';
}
break;
}
}
}
}
}

View File

@@ -0,0 +1,232 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Gender $object
*/
class AdminGendersControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'gender';
$this->className = 'Gender';
$this->lang = true;
$this->addRowAction('edit');
$this->addRowAction('delete');
parent::__construct();
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->default_image_height = 16;
$this->default_image_width = 16;
$this->fieldImageSettings = array(
'name' => 'image',
'dir' => 'genders',
);
$this->fields_list = array(
'id_gender' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Social title', array(), 'Admin.Shopparameters.Feature'),
'filter_key' => 'b!name',
),
'type' => array(
'title' => $this->trans('Gender', array(), 'Admin.Global'),
'orderby' => false,
'type' => 'select',
'list' => array(
0 => $this->trans('Male', array(), 'Admin.Shopparameters.Feature'),
1 => $this->trans('Female', array(), 'Admin.Shopparameters.Feature'),
2 => $this->trans('Neutral', array(), 'Admin.Shopparameters.Feature'),
),
'filter_key' => 'a!type',
'callback' => 'displayGenderType',
'callback_object' => $this,
),
'image' => array(
'title' => $this->trans('Image', array(), 'Admin.Global'),
'align' => 'center',
'image' => 'genders',
'orderby' => false,
'search' => false,
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_gender'] = array(
'href' => self::$currentIndex . '&addgender&token=' . $this->token,
'desc' => $this->trans('Add new social title', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Social titles', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-male',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Social title', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'col' => 4,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Shopparameters.Help') . ' 0-9!&lt;&gt;,;?=+()@#"<22>{}_$%:',
'required' => true,
),
array(
'type' => 'radio',
'label' => $this->trans('Gender', array(), 'Admin.Global'),
'name' => 'type',
'required' => false,
'class' => 't',
'values' => array(
array(
'id' => 'type_male',
'value' => 0,
'label' => $this->trans('Male', array(), 'Admin.Shopparameters.Feature'),
),
array(
'id' => 'type_female',
'value' => 1,
'label' => $this->trans('Female', array(), 'Admin.Shopparameters.Feature'),
),
array(
'id' => 'type_neutral',
'value' => 2,
'label' => $this->trans('Neutral', array(), 'Admin.Shopparameters.Feature'),
),
),
),
array(
'type' => 'file',
'label' => $this->trans('Image', array(), 'Admin.Global'),
'name' => 'image',
'col' => 6,
'value' => true,
),
array(
'type' => 'text',
'label' => $this->trans('Image width', array(), 'Admin.Shopparameters.Feature'),
'name' => 'img_width',
'col' => 2,
'hint' => $this->trans('Image width in pixels. Enter "0" to use the original size.', array(), 'Admin.Shopparameters.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Image height', array(), 'Admin.Shopparameters.Feature'),
'name' => 'img_height',
'col' => 2,
'hint' => $this->trans('Image height in pixels. Enter "0" to use the original size.', array(), 'Admin.Shopparameters.Help'),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
/** @var Gender $obj */
if (!($obj = $this->loadObject(true))) {
return;
}
$this->fields_value = array(
'img_width' => $this->default_image_width,
'img_height' => $this->default_image_height,
'image' => $obj->getImage(),
);
return parent::renderForm();
}
public function displayGenderType($value, $tr)
{
return $this->fields_list['type']['list'][$value];
}
protected function postImage($id)
{
if (isset($this->fieldImageSettings['name'], $this->fieldImageSettings['dir'])) {
if (!Validate::isInt(Tools::getValue('img_width')) || !Validate::isInt(Tools::getValue('img_height'))) {
$this->errors[] = $this->trans('Width and height must be numeric values.', array(), 'Admin.Shopparameters.Notification');
} else {
if ((int) Tools::getValue('img_width') > 0 && (int) Tools::getValue('img_height') > 0) {
$width = (int) Tools::getValue('img_width');
$height = (int) Tools::getValue('img_height');
} else {
$width = null;
$height = null;
}
return $this->uploadImage($id, $this->fieldImageSettings['name'], $this->fieldImageSettings['dir'] . '/', false, $width, $height);
}
}
return !count($this->errors) ? true : false;
}
protected function afterImageUpload()
{
parent::afterImageUpload();
if (($id_gender = (int) Tools::getValue('id_gender')) &&
isset($_FILES) && count($_FILES) && file_exists(_PS_GENDERS_DIR_ . $id_gender . '.jpg')) {
$current_file = _PS_TMP_IMG_DIR_ . 'gender_mini_' . $id_gender . '_' . $this->context->shop->id . '.jpg';
if (file_exists($current_file)) {
unlink($current_file);
}
}
return true;
}
}

View File

@@ -0,0 +1,652 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Group $object
*/
class AdminGroupsControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'group';
$this->className = 'Group';
$this->list_id = 'group';
$this->lang = true;
parent::__construct();
$this->addRowAction('edit');
$this->addRowAction('view');
$this->addRowAction('delete');
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$groups_to_keep = array(
Configuration::get('PS_UNIDENTIFIED_GROUP'),
Configuration::get('PS_GUEST_GROUP'),
Configuration::get('PS_CUSTOMER_GROUP'),
);
$this->fields_list = array(
'id_group' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Group name', array(), 'Admin.Shopparameters.Feature'),
'filter_key' => 'b!name',
),
'reduction' => array(
'title' => $this->trans('Discount (%)', array(), 'Admin.Shopparameters.Feature'),
'align' => 'right',
'type' => 'percent',
),
'nb' => array(
'title' => $this->trans('Members', array(), 'Admin.Shopparameters.Feature'),
'align' => 'center',
'havingFilter' => true,
),
'show_prices' => array(
'title' => $this->trans('Show prices', array(), 'Admin.Shopparameters.Feature'),
'align' => 'center',
'type' => 'bool',
'orderby' => false,
),
'date_add' => array(
'title' => $this->trans('Creation date', array(), 'Admin.Shopparameters.Feature'),
'type' => 'date',
'align' => 'right',
),
);
$this->addRowActionSkipList('delete', $groups_to_keep);
$this->_select .= '(SELECT COUNT(jcg.`id_customer`)
FROM `' . _DB_PREFIX_ . 'customer_group` jcg
LEFT JOIN `' . _DB_PREFIX_ . 'customer` jc ON (jc.`id_customer` = jcg.`id_customer`)
WHERE jc.`deleted` != 1
' . Shop::addSqlRestriction(Shop::SHARE_CUSTOMER) . '
AND jcg.`id_group` = a.`id_group`) AS nb';
$this->_use_found_rows = false;
$groups = Group::getGroups(Context::getContext()->language->id, true);
if (Group::isFeatureActive()) {
$this->fields_options = array(
'general' => array(
'title' => $this->trans('Default groups options', array(), 'Admin.Shopparameters.Feature'),
'fields' => array(
'PS_UNIDENTIFIED_GROUP' => array(
'title' => $this->trans('Visitors group', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('The group defined for your un-identified visitors.', array(), 'Admin.Shopparameters.Help'),
'cast' => 'intval',
'type' => 'select',
'list' => $groups,
'identifier' => 'id_group',
),
'PS_GUEST_GROUP' => array(
'title' => $this->trans('Guests group', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('The group defined for your identified guest customers (used in guest checkout).', array(), 'Admin.Shopparameters.Help'),
'cast' => 'intval',
'type' => 'select',
'list' => $groups,
'identifier' => 'id_group',
),
'PS_CUSTOMER_GROUP' => array(
'title' => $this->trans('Customers group', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('The group defined for your identified registered customers.', array(), 'Admin.Shopparameters.Help'),
'cast' => 'intval',
'type' => 'select',
'list' => $groups,
'identifier' => 'id_group',
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
),
);
}
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryPlugin('fancybox');
$this->addJqueryUi('ui.sortable');
}
public function initToolbar()
{
if ($this->display == 'add' || $this->display == 'edit') {
$this->toolbar_btn['save-and-stay'] = array(
'short' => 'SaveAndStay',
'href' => '#',
'desc' => $this->trans('Save, then add a category reduction.', array(), 'Admin.Shopparameters.Feature'),
'force_desc' => true,
);
}
parent::initToolbar();
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_group'] = array(
'href' => self::$currentIndex . '&addgroup&token=' . $this->token,
'desc' => $this->trans('Add new group', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function initProcess()
{
$this->id_object = Tools::getValue('id_' . $this->table);
if (Tools::isSubmit('changeShowPricesVal') && $this->id_object) {
$this->action = 'change_show_prices_val';
}
if (Tools::getIsset('viewgroup')) {
$this->list_id = 'customer_group';
if (isset($_POST['submitReset' . $this->list_id])) {
$this->processResetFilters();
}
} else {
$this->list_id = 'group';
}
parent::initProcess();
}
public function renderView()
{
$this->context = Context::getContext();
if (!($group = $this->loadObject(true))) {
return;
}
$this->tpl_view_vars = array(
'group' => $group,
'language' => $this->context->language,
'customerList' => $this->renderCustomersList($group),
'categorieReductions' => $this->formatCategoryDiscountList($group->id),
);
return parent::renderView();
}
protected function renderCustomersList($group)
{
$genders = array(0 => '?');
$genders_icon = array('default' => 'unknown.gif');
foreach (Gender::getGenders() as $gender) {
/* @var Gender $gender */
$genders_icon[$gender->id] = '../genders/' . (int) $gender->id . '.jpg';
$genders[$gender->id] = $gender->name;
}
$this->table = 'customer_group';
$this->lang = false;
$this->list_id = 'customer_group';
$this->actions = array();
$this->addRowAction('edit');
$this->identifier = 'id_customer';
$this->bulk_actions = false;
$this->list_no_link = true;
$this->explicitSelect = true;
$this->fields_list = (array(
'id_customer' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'filter_key' => 'c!id_customer',
'class' => 'fixed-width-xs',
),
'id_gender' => array(
'title' => $this->trans('Social title', array(), 'Admin.Global'),
'icon' => $genders_icon,
'list' => $genders,
),
'firstname' => array(
'title' => $this->trans('First name', array(), 'Admin.Global'),
'maxlength' => 30,
),
'lastname' => array(
'title' => $this->trans('Last name', array(), 'Admin.Global'),
'maxlength' => 30,
),
'email' => array(
'title' => $this->trans('Email address', array(), 'Admin.Global'),
'filter_key' => 'c!email',
'orderby' => true,
'maxlength' => 50,
),
'birthday' => array(
'title' => $this->trans('Date of birth', array(), 'Admin.Global'),
'type' => 'date',
'class' => 'fixed-width-md',
'align' => 'center',
),
'date_add' => array(
'title' => $this->trans('Registration date', array(), 'Admin.Shopparameters.Feature'),
'type' => 'date',
'class' => 'fixed-width-md',
'align' => 'center',
),
'active' => array(
'title' => $this->trans('Enabled', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-sm',
'type' => 'bool',
'search' => false,
'orderby' => false,
'filter_key' => 'c!active',
'callback' => 'printOptinIcon',
),
));
$this->_select = 'c.*, a.id_group';
$this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (a.`id_customer` = c.`id_customer`)';
$this->_where = 'AND a.`id_group` = ' . (int) $group->id . ' AND c.`deleted` != 1';
$this->_where .= Shop::addSqlRestriction(Shop::SHARE_CUSTOMER, 'c');
self::$currentIndex = self::$currentIndex . '&id_group=' . (int) $group->id . '&viewgroup';
$this->processFilter();
return parent::renderList();
}
public function printOptinIcon($value, $customer)
{
return $value ? '<i class="icon-check"></i>' : '<i class="icon-remove"></i>';
}
public function renderForm()
{
if (!($group = $this->loadObject(true))) {
return;
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Customer group', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-group',
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'required' => true,
'lang' => true,
'col' => 4,
'hint' => $this->trans('Forbidden characters:', array(), 'Admin.Notifications.Info') . ' 0-9!&amp;lt;&amp;gt;,;?=+()@#"<22>{}_$%:',
),
array(
'type' => 'text',
'label' => $this->trans('Discount', array(), 'Admin.Global'),
'name' => 'reduction',
'suffix' => '%',
'col' => 1,
'hint' => $this->trans('Automatically apply this value as a discount on all products for members of this customer group.', array(), 'Admin.Shopparameters.Help'),
),
array(
'type' => 'select',
'label' => $this->trans('Price display method', array(), 'Admin.Shopparameters.Feature'),
'name' => 'price_display_method',
'col' => 2,
'hint' => $this->trans('How prices are displayed in the order summary for this customer group.', array(), 'Admin.Shopparameters.Help'),
'options' => array(
'query' => array(
array(
'id_method' => PS_TAX_EXC,
'name' => $this->trans('Tax excluded', array(), 'Admin.Global'),
),
array(
'id_method' => PS_TAX_INC,
'name' => $this->trans('Tax included', array(), 'Admin.Global'),
),
),
'id' => 'id_method',
'name' => 'name',
),
),
array(
'type' => 'switch',
'label' => $this->trans('Show prices', array(), 'Admin.Shopparameters.Feature'),
'name' => 'show_prices',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'show_prices_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'show_prices_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
'hint' => $this->trans('Customers in this group can view prices.', array(), 'Admin.Shopparameters.Help'),
'desc' => $this->trans('Need to hide prices for all groups? Save time, enable catalog mode in Product Settings instead.', array(), 'Admin.Shopparameters.Help'),
),
array(
'type' => 'group_discount_category',
'label' => $this->trans('Category discount', array(), 'Admin.Shopparameters.Feature'),
'name' => 'reduction',
'values' => ($group->id ? $this->formatCategoryDiscountList((int) $group->id) : array()),
),
array(
'type' => 'modules',
'label' => $this->trans('Modules authorization', array(), 'Admin.Shopparameters.Feature'),
'name' => 'auth_modules',
'values' => $this->formatModuleListAuth($group->id),
),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
if (Tools::getIsset('addgroup')) {
$this->fields_value['price_display_method'] = Configuration::get('PRICE_DISPLAY_METHOD');
}
$this->fields_value['reduction'] = isset($group->reduction) ? $group->reduction : 0;
$tree = new HelperTreeCategories('categories-tree');
$this->tpl_form_vars['categoryTreeView'] = $tree->setRootCategory((int) Category::getRootCategory()->id)->render();
return parent::renderForm();
}
protected function formatCategoryDiscountList($id_group)
{
$group_reductions = GroupReduction::getGroupReductions((int) $id_group, $this->context->language->id);
$category_reductions = array();
$category_reduction = Tools::getValue('category_reduction');
foreach ($group_reductions as $category) {
if (is_array($category_reduction) && array_key_exists($category['id_category'], $category_reduction)) {
$category['reduction'] = $category_reduction[$category['id_category']];
}
$category_reductions[(int) $category['id_category']] = array(
'path' => Tools::getPath(Context::getContext()->link->getAdminLink('AdminCategories'), (int) $category['id_category']),
'reduction' => (float) $category['reduction'] * 100,
'id_category' => (int) $category['id_category'],
);
}
if (is_array($category_reduction)) {
foreach ($category_reduction as $key => $val) {
if (!array_key_exists($key, $category_reductions)) {
$category_reductions[(int) $key] = array(
'path' => Tools::getPath(Context::getContext()->link->getAdminLink('AdminCategories'), $key),
'reduction' => (float) $val * 100,
'id_category' => (int) $key,
);
}
}
}
return $category_reductions;
}
public function formatModuleListAuth($id_group)
{
$modules = Module::getModulesInstalled();
$authorized_modules = '';
$auth_modules = array();
$unauth_modules = array();
$shops = Shop::getContextListShopID();
if ($id_group) {
$authorized_modules = Module::getAuthorizedModules($id_group, $shops);
}
if (is_array($authorized_modules)) {
foreach ($modules as $module) {
$authorized = false;
foreach ($authorized_modules as $auth_module) {
if ($module['id_module'] == $auth_module['id_module']) {
$authorized = true;
}
}
if ($authorized) {
$auth_modules[] = $module;
} else {
$unauth_modules[] = $module;
}
}
} else {
$auth_modules = $modules;
}
$auth_modules_tmp = array();
foreach ($auth_modules as $key => $val) {
if ($module = Module::getInstanceById($val['id_module'])) {
$auth_modules_tmp[] = $module;
}
}
$auth_modules = $auth_modules_tmp;
$unauth_modules_tmp = array();
foreach ($unauth_modules as $key => $val) {
if (($tmp_obj = Module::getInstanceById($val['id_module']))) {
$unauth_modules_tmp[] = $tmp_obj;
}
}
$unauth_modules = $unauth_modules_tmp;
return array('unauth_modules' => $unauth_modules, 'auth_modules' => $auth_modules);
}
public function processSave()
{
if (!$this->validateDiscount(Tools::getValue('reduction'))) {
$this->errors[] = $this->trans('The discount value is incorrect (must be a percentage).', array(), 'Admin.Shopparameters.Notification');
} else {
$this->updateCategoryReduction();
$object = parent::processSave();
$this->updateRestrictions();
return $object;
}
}
protected function validateDiscount($reduction)
{
if (!Validate::isPrice($reduction) || $reduction > 100 || $reduction < 0) {
return false;
} else {
return true;
}
}
public function ajaxProcessAddCategoryReduction()
{
$category_reduction = Tools::getValue('category_reduction');
$id_category = Tools::getValue('id_category'); //no cast validation is done with Validate::isUnsignedId($id_category)
$result = array();
if (!Validate::isUnsignedId($id_category)) {
$result['errors'][] = $this->trans('Wrong category ID.', array(), 'Admin.Shopparameters.Notification');
$result['hasError'] = true;
} elseif (!$this->validateDiscount($category_reduction)) {
$result['errors'][] = $this->trans('The discount value is incorrect (must be a percentage).', array(), 'Admin.Shopparameters.Notification');
$result['hasError'] = true;
} else {
$result['id_category'] = (int) $id_category;
$result['catPath'] = Tools::getPath(self::$currentIndex . '?tab=AdminCategories', (int) $id_category);
$result['discount'] = $category_reduction;
$result['hasError'] = false;
}
die(json_encode($result));
}
/**
* Update (or create) restrictions for modules by group.
*/
protected function updateRestrictions()
{
$id_group = Tools::getValue('id_group');
$auth_modules = Tools::getValue('modulesBoxAuth');
$return = true;
if ($id_group) {
$shops = Shop::getContextListShopID();
if (is_array($auth_modules)) {
$return &= Group::addModulesRestrictions($id_group, $auth_modules, $shops);
}
}
// update module list by hook cache
Cache::clean(Hook::MODULE_LIST_BY_HOOK_KEY . '*');
return $return;
}
protected function updateCategoryReduction()
{
$category_reduction = Tools::getValue('category_reduction');
Db::getInstance()->execute(
'
DELETE FROM `' . _DB_PREFIX_ . 'group_reduction`
WHERE `id_group` = ' . (int) Tools::getValue('id_group')
);
Db::getInstance()->execute(
'
DELETE FROM `' . _DB_PREFIX_ . 'product_group_reduction_cache`
WHERE `id_group` = ' . (int) Tools::getValue('id_group')
);
if (is_array($category_reduction) && count($category_reduction)) {
if (!Configuration::getGlobalValue('PS_GROUP_FEATURE_ACTIVE')) {
Configuration::updateGlobalValue('PS_GROUP_FEATURE_ACTIVE', 1);
}
foreach ($category_reduction as $cat => $reduction) {
if (!Validate::isUnsignedId($cat) || !$this->validateDiscount($reduction)) {
$this->errors[] = $this->trans('The discount value is incorrect.', array(), 'Admin.Shopparameters.Notification');
} else {
$category = new Category((int) $cat);
$category->addGroupsIfNoExist((int) Tools::getValue('id_group'));
$group_reduction = new GroupReduction();
$group_reduction->id_group = (int) Tools::getValue('id_group');
$group_reduction->reduction = (float) ($reduction / 100);
$group_reduction->id_category = (int) $cat;
if (!$group_reduction->save()) {
$this->errors[] = $this->trans('You cannot save group reductions.', array(), 'Admin.Shopparameters.Notification');
}
}
}
}
}
/**
* Toggle show prices flag.
*/
public function processChangeShowPricesVal()
{
$group = new Group($this->id_object);
if (!Validate::isLoadedObject($group)) {
$this->errors[] = $this->trans('An error occurred while updating this group.', array(), 'Admin.Shopparameters.Notification');
}
$update = Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'group` SET show_prices = ' . ($group->show_prices ? 0 : 1) . ' WHERE `id_group` = ' . (int) $group->id);
if (!$update) {
$this->errors[] = $this->trans('An error occurred while updating this group.', array(), 'Admin.Shopparameters.Notification');
}
Tools::clearSmartyCache();
Tools::redirectAdmin(self::$currentIndex . '&token=' . $this->token);
}
public function renderList()
{
$unidentified = new Group(Configuration::get('PS_UNIDENTIFIED_GROUP'));
$guest = new Group(Configuration::get('PS_GUEST_GROUP'));
$default = new Group(Configuration::get('PS_CUSTOMER_GROUP'));
$unidentified_group_information = $this->trans('%group_name% - All persons without a customer account or customers that are not logged in.', array('%group_name%' => '<b>' . $unidentified->name[$this->context->language->id] . '</b>'), 'Admin.Shopparameters.Help');
$guest_group_information = $this->trans('%group_name% - All persons who placed an order through Guest Checkout.', array('%group_name%' => '<b>' . $guest->name[$this->context->language->id] . '</b>'), 'Admin.Shopparameters.Help');
$default_group_information = $this->trans('%group_name% - All persons who created an account on this site.', array('%group_name%' => '<b>' . $default->name[$this->context->language->id] . '</b>'), 'Admin.Shopparameters.Help');
$this->displayInformation($this->trans('PrestaShop has three default customer groups:', array(), 'Admin.Shopparameters.Help'));
$this->displayInformation($unidentified_group_information);
$this->displayInformation($guest_group_information);
$this->displayInformation($default_group_information);
return parent::renderList();
}
public function displayEditLink($token, $id)
{
$tpl = $this->createTemplate('helpers/list/list_action_edit.tpl');
if (!array_key_exists('Edit', self::$cache_lang)) {
self::$cache_lang['Edit'] = $this->trans('Edit', array(), 'Admin.Actions');
}
$href = self::$currentIndex . '&' . $this->identifier . '=' . $id . '&update' . $this->table . '&token=' . ($token != null ? $token : $this->token);
if ($this->display == 'view') {
$href = Context::getContext()->link->getAdminLink('AdminCustomers', true, [], [
'id_customer' => $id,
'updatecustomer' => 1,
'back' => urlencode($href),
]);
}
$tpl->assign(array(
'href' => $href,
'action' => self::$cache_lang['Edit'],
'id' => $id,
));
return $tpl->fetch();
}
}

View File

@@ -0,0 +1,748 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property ImageType $object
*/
class AdminImagesControllerCore extends AdminController
{
protected $start_time = 0;
protected $max_execution_time = 7200;
protected $display_move;
public function __construct()
{
$this->bootstrap = true;
$this->table = 'image_type';
$this->className = 'ImageType';
$this->lang = false;
$this->addRowAction('edit');
$this->addRowAction('delete');
parent::__construct();
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'id_image_type' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'align' => 'center', 'class' => 'fixed-width-xs'),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global')),
'width' => array('title' => $this->trans('Width', array(), 'Admin.Global'), 'suffix' => ' px'),
'height' => array('title' => $this->trans('Height', array(), 'Admin.Global'), 'suffix' => ' px'),
'products' => array('title' => $this->trans('Products', array(), 'Admin.Global'), 'align' => 'center', 'type' => 'bool', 'callback' => 'printEntityActiveIcon', 'orderby' => false),
'categories' => array('title' => $this->trans('Categories', array(), 'Admin.Global'), 'align' => 'center', 'type' => 'bool', 'callback' => 'printEntityActiveIcon', 'orderby' => false),
'manufacturers' => array('title' => $this->trans('Brands', array(), 'Admin.Global'), 'align' => 'center', 'type' => 'bool', 'callback' => 'printEntityActiveIcon', 'orderby' => false),
'suppliers' => array('title' => $this->trans('Suppliers', array(), 'Admin.Global'), 'align' => 'center', 'type' => 'bool', 'callback' => 'printEntityActiveIcon', 'orderby' => false),
'stores' => array('title' => $this->trans('Stores', array(), 'Admin.Global'), 'align' => 'center', 'type' => 'bool', 'callback' => 'printEntityActiveIcon', 'orderby' => false),
);
// No need to display the old image system migration tool except if product images are in _PS_PROD_IMG_DIR_
$this->display_move = false;
$dir = _PS_PROD_IMG_DIR_;
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false && $this->display_move == false) {
if (!is_dir($dir . DIRECTORY_SEPARATOR . $file) && $file[0] != '.' && is_numeric($file[0])) {
$this->display_move = true;
}
}
closedir($dh);
}
}
$this->fields_options = array(
'images' => array(
'title' => $this->trans('Images generation options', array(), 'Admin.Design.Feature'),
'icon' => 'icon-picture',
'top' => '',
'bottom' => '',
'description' => $this->trans('JPEG images have a small file size and standard quality. PNG images have a larger file size, a higher quality and support transparency. Note that in all cases the image files will have the .jpg extension.', array(), 'Admin.Design.Help') . '
<br /><br />' . $this->trans('WARNING: This feature may not be compatible with your theme, or with some of your modules. In particular, PNG mode is not compatible with the Watermark module. If you encounter any issues, turn it off by selecting "Use JPEG".', array(), 'Admin.Design.Help'),
'fields' => array(
'PS_IMAGE_QUALITY' => array(
'title' => $this->trans('Image format', array(), 'Admin.Design.Feature'),
'show' => true,
'required' => true,
'type' => 'radio',
'choices' => array('jpg' => $this->trans('Use JPEG.', array(), 'Admin.Design.Feature'), 'png' => $this->trans('Use PNG only if the base image is in PNG format.', array(), 'Admin.Design.Feature'), 'png_all' => $this->trans('Use PNG for all images.', array(), 'Admin.Design.Feature')),
),
'PS_JPEG_QUALITY' => array(
'title' => $this->trans('JPEG compression', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('Ranges from 0 (worst quality, smallest file) to 100 (best quality, biggest file).', array(), 'Admin.Design.Help') . ' ' . $this->trans('Recommended: 90.', array(), 'Admin.Design.Help'),
'validation' => 'isUnsignedId',
'required' => true,
'cast' => 'intval',
'type' => 'text',
),
'PS_PNG_QUALITY' => array(
'title' => $this->trans('PNG compression', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('PNG compression is lossless: unlike JPG, you do not lose image quality with a high compression ratio. However, photographs will compress very badly.', array(), 'Admin.Design.Help') . ' ' . $this->trans('Ranges from 0 (biggest file) to 9 (smallest file, slowest decompression).', array(), 'Admin.Design.Help') . ' ' . $this->trans('Recommended: 7.', array(), 'Admin.Design.Help'),
'validation' => 'isUnsignedId',
'required' => true,
'cast' => 'intval',
'type' => 'text',
),
'PS_IMAGE_GENERATION_METHOD' => array(
'title' => $this->trans('Generate images based on one side of the source image', array(), 'Admin.Design.Feature'),
'validation' => 'isUnsignedId',
'required' => false,
'cast' => 'intval',
'type' => 'select',
'list' => array(
array(
'id' => '0',
'name' => $this->trans('Automatic (longest side)', array(), 'Admin.Design.Feature'),
),
array(
'id' => '1',
'name' => $this->trans('Width', array(), 'Admin.Global'),
),
array(
'id' => '2',
'name' => $this->trans('Height', array(), 'Admin.Global'),
),
),
'identifier' => 'id',
'visibility' => Shop::CONTEXT_ALL,
),
'PS_PRODUCT_PICTURE_MAX_SIZE' => array(
'title' => $this->trans('Maximum file size of product customization pictures', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('The maximum file size of pictures that customers can upload to customize a product (in bytes).', array(), 'Admin.Design.Help'),
'validation' => 'isUnsignedInt',
'required' => true,
'cast' => 'intval',
'type' => 'text',
'suffix' => $this->trans('bytes', array(), 'Admin.Design.Feature'),
'visibility' => Shop::CONTEXT_ALL,
),
'PS_PRODUCT_PICTURE_WIDTH' => array(
'title' => $this->trans('Product picture width', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('Width of product customization pictures that customers can upload (in pixels).', array(), 'Admin.Design.Help'),
'validation' => 'isUnsignedInt',
'required' => true,
'cast' => 'intval',
'type' => 'text',
'width' => 'px',
'suffix' => $this->trans('pixels', array(), 'Admin.Design.Feature'),
'visibility' => Shop::CONTEXT_ALL,
),
'PS_PRODUCT_PICTURE_HEIGHT' => array(
'title' => $this->trans('Product picture height', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('Height of product customization pictures that customers can upload (in pixels).', array(), 'Admin.Design.Help'),
'validation' => 'isUnsignedInt',
'required' => true,
'cast' => 'intval',
'type' => 'text',
'height' => 'px',
'suffix' => $this->trans('pixels', array(), 'Admin.Design.Feature'),
'visibility' => Shop::CONTEXT_ALL,
),
'PS_HIGHT_DPI' => array(
'type' => 'bool',
'title' => $this->trans('Generate high resolution images', array(), 'Admin.Design.Feature'),
'required' => false,
'is_bool' => true,
'hint' => $this->trans('This will generate an additional file for each image (thus doubling your total amount of images). Resolution of these images will be twice higher.', array(), 'Admin.Design.Help'),
'desc' => $this->trans('Enable to optimize the display of your images on high pixel density screens.', array(), 'Admin.Design.Help'),
'visibility' => Shop::CONTEXT_ALL,
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
if ($this->display_move) {
$this->fields_options['product_images']['fields']['PS_LEGACY_IMAGES'] = array(
'title' => $this->trans('Use the legacy image filesystem', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('This should be set to yes unless you successfully moved images in "Images" page under the "Preferences" menu.', array(), 'Admin.Design.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'required' => false,
'type' => 'bool',
'visibility' => Shop::CONTEXT_ALL,
);
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Image type', array(), 'Admin.Design.Feature'),
'icon' => 'icon-picture',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name for the image type', array(), 'Admin.Design.Feature'),
'name' => 'name',
'required' => true,
'hint' => $this->trans('Letters, underscores and hyphens only (e.g. "small_custom", "cart_medium", "large", "thickbox_extra-large").', array(), 'Admin.Design.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Width', array(), 'Admin.Global'),
'name' => 'width',
'required' => true,
'maxlength' => 5,
'suffix' => $this->trans('pixels', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('Maximum image width in pixels.', array(), 'Admin.Design.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Height', array(), 'Admin.Global'),
'name' => 'height',
'required' => true,
'maxlength' => 5,
'suffix' => $this->trans('pixels', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('Maximum image height in pixels.', array(), 'Admin.Design.Help'),
),
array(
'type' => 'switch',
'label' => $this->trans('Products', array(), 'Admin.Global'),
'name' => 'products',
'required' => false,
'is_bool' => true,
'hint' => $this->trans('This type will be used for Product images.', array(), 'Admin.Design.Help'),
'values' => array(
array(
'id' => 'products_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'products_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Categories', array(), 'Admin.Global'),
'name' => 'categories',
'required' => false,
'class' => 't',
'is_bool' => true,
'hint' => $this->trans('This type will be used for Category images.', array(), 'Admin.Design.Help'),
'values' => array(
array(
'id' => 'categories_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'categories_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Brands', array(), 'Admin.Global'),
'name' => 'manufacturers',
'required' => false,
'is_bool' => true,
'hint' => $this->trans('This type will be used for Brand images.', array(), 'Admin.Design.Help'),
'values' => array(
array(
'id' => 'manufacturers_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'manufacturers_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Suppliers', array(), 'Admin.Global'),
'name' => 'suppliers',
'required' => false,
'is_bool' => true,
'hint' => $this->trans('This type will be used for Supplier images.', array(), 'Admin.Design.Help'),
'values' => array(
array(
'id' => 'suppliers_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'suppliers_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Stores', array(), 'Admin.Global'),
'name' => 'stores',
'required' => false,
'is_bool' => true,
'hint' => $this->trans('This type will be used for Store images.', array(), 'Admin.Design.Help'),
'values' => array(
array(
'id' => 'stores_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'stores_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
}
public function postProcess()
{
// When moving images, if duplicate images were found they are moved to a folder named duplicates/
if (file_exists(_PS_PROD_IMG_DIR_ . 'duplicates/')) {
$this->warnings[] = $this->trans('Duplicate images were found when moving the product images. This is likely caused by unused demonstration images. Please make sure that the folder %folder% only contains demonstration images, and then delete it.', array('%folder%' => _PS_PROD_IMG_DIR_ . 'duplicates/'), 'Admin.Design.Notification');
}
if (Tools::isSubmit('submitRegenerate' . $this->table)) {
if ($this->access('edit')) {
if ($this->_regenerateThumbnails(Tools::getValue('type'), Tools::getValue('erase'))) {
Tools::redirectAdmin(self::$currentIndex . '&conf=9' . '&token=' . $this->token);
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('submitMoveImages' . $this->table)) {
if ($this->access('edit')) {
if ($this->_moveImagesToNewFileSystem()) {
Tools::redirectAdmin(self::$currentIndex . '&conf=25' . '&token=' . $this->token);
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('submitOptions' . $this->table)) {
if ($this->access('edit')) {
if ((int) Tools::getValue('PS_JPEG_QUALITY') < 0
|| (int) Tools::getValue('PS_JPEG_QUALITY') > 100) {
$this->errors[] = $this->trans('Incorrect value for the selected JPEG image compression.', array(), 'Admin.Design.Notification');
} elseif ((int) Tools::getValue('PS_PNG_QUALITY') < 0
|| (int) Tools::getValue('PS_PNG_QUALITY') > 9) {
$this->errors[] = $this->trans('Incorrect value for the selected PNG image compression.', array(), 'Admin.Design.Notification');
} elseif (!Configuration::updateValue('PS_IMAGE_QUALITY', Tools::getValue('PS_IMAGE_QUALITY'))
|| !Configuration::updateValue('PS_JPEG_QUALITY', Tools::getValue('PS_JPEG_QUALITY'))
|| !Configuration::updateValue('PS_PNG_QUALITY', Tools::getValue('PS_PNG_QUALITY'))) {
$this->errors[] = $this->trans('Unknown error.', array(), 'Admin.Notifications.Error');
} else {
$this->confirmations[] = $this->_conf[6];
}
return parent::postProcess();
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} else {
return parent::postProcess();
}
}
public static function printEntityActiveIcon($value, $object)
{
return $value ? '<span class="list-action-enable action-enabled"><i class="icon-check"></i></span>' : '<span class="list-action-enable action-disabled"><i class="icon-remove"></i></span>';
}
protected function _childValidation()
{
if (!Tools::getValue('id_image_type') && Validate::isImageTypeName($typeName = Tools::getValue('name')) && ImageType::typeAlreadyExists($typeName)) {
$this->errors[] = $this->trans('This name already exists.', array(), 'Admin.Design.Notification');
}
}
/**
* Init display for the thumbnails regeneration block.
*/
public function initRegenerate()
{
$types = array(
'categories' => $this->trans('Categories', array(), 'Admin.Global'),
'manufacturers' => $this->trans('Brands', array(), 'Admin.Global'),
'suppliers' => $this->trans('Suppliers', array(), 'Admin.Global'),
'products' => $this->trans('Products', array(), 'Admin.Global'),
'stores' => $this->trans('Stores', array(), 'Admin.Global'),
);
$formats = array();
foreach ($types as $i => $type) {
$formats[$i] = ImageType::getImagesTypes($i);
}
$this->context->smarty->assign(array(
'types' => $types,
'formats' => $formats,
));
}
/**
* Delete resized image then regenerate new one with updated settings.
*
* @param string $dir
* @param array $type
* @param bool $product
*
* @return bool
*/
protected function _deleteOldImages($dir, $type, $product = false)
{
if (!is_dir($dir)) {
return false;
}
$toDel = scandir($dir, SCANDIR_SORT_NONE);
foreach ($toDel as $d) {
foreach ($type as $imageType) {
if (preg_match('/^[0-9]+\-' . ($product ? '[0-9]+\-' : '') . $imageType['name'] . '\.jpg$/', $d)
|| (count($type) > 1 && preg_match('/^[0-9]+\-[_a-zA-Z0-9-]*\.jpg$/', $d))
|| preg_match('/^([[:lower:]]{2})\-default\-' . $imageType['name'] . '\.jpg$/', $d)) {
if (file_exists($dir . $d)) {
unlink($dir . $d);
}
}
}
}
// delete product images using new filesystem.
if ($product) {
$productsImages = Image::getAllImages();
foreach ($productsImages as $image) {
$imageObj = new Image($image['id_image']);
$imageObj->id_product = $image['id_product'];
if (file_exists($dir . $imageObj->getImgFolder())) {
$toDel = scandir($dir . $imageObj->getImgFolder(), SCANDIR_SORT_NONE);
foreach ($toDel as $d) {
foreach ($type as $imageType) {
if (preg_match('/^[0-9]+\-' . $imageType['name'] . '\.jpg$/', $d) || (count($type) > 1 && preg_match('/^[0-9]+\-[_a-zA-Z0-9-]*\.jpg$/', $d))) {
if (file_exists($dir . $imageObj->getImgFolder() . $d)) {
unlink($dir . $imageObj->getImgFolder() . $d);
}
}
}
}
}
}
}
}
/**
* Regenerate images.
*
* @param $dir
* @param $type
* @param bool $productsImages
*
* @return bool|string
*/
protected function _regenerateNewImages($dir, $type, $productsImages = false)
{
if (!is_dir($dir)) {
return false;
}
$generate_hight_dpi_images = (bool) Configuration::get('PS_HIGHT_DPI');
if (!$productsImages) {
$formated_medium = ImageType::getFormattedName('medium');
foreach (scandir($dir, SCANDIR_SORT_NONE) as $image) {
if (preg_match('/^[0-9]*\.jpg$/', $image)) {
foreach ($type as $k => $imageType) {
// Customizable writing dir
$newDir = $dir;
if (!file_exists($newDir)) {
continue;
}
if (($dir == _PS_CAT_IMG_DIR_) && ($imageType['name'] == $formated_medium) && is_file(_PS_CAT_IMG_DIR_ . str_replace('.', '_thumb.', $image))) {
$image = str_replace('.', '_thumb.', $image);
}
if (!file_exists($newDir . substr($image, 0, -4) . '-' . stripslashes($imageType['name']) . '.jpg')) {
if (!file_exists($dir . $image) || !filesize($dir . $image)) {
$this->errors[] = $this->trans('Source file does not exist or is empty (%filepath%)', array('%filepath%' => $dir . $image), 'Admin.Design.Notification');
} elseif (!ImageManager::resize($dir . $image, $newDir . substr(str_replace('_thumb.', '.', $image), 0, -4) . '-' . stripslashes($imageType['name']) . '.jpg', (int) $imageType['width'], (int) $imageType['height'])) {
$this->errors[] = $this->trans('Failed to resize image file (%filepath%)', array('%filepath%' => $dir . $image), 'Admin.Design.Notification');
}
if ($generate_hight_dpi_images) {
if (!ImageManager::resize($dir . $image, $newDir . substr($image, 0, -4) . '-' . stripslashes($imageType['name']) . '2x.jpg', (int) $imageType['width'] * 2, (int) $imageType['height'] * 2)) {
$this->errors[] = $this->trans('Failed to resize image file to high resolution (%filepath%)', array('%filepath%' => $dir . $image), 'Admin.Design.Notification');
}
}
}
// stop 4 seconds before the timeout, just enough time to process the end of the page on a slow server
if (time() - $this->start_time > $this->max_execution_time - 4) {
return 'timeout';
}
}
}
}
} else {
foreach (Image::getAllImages() as $image) {
$imageObj = new Image($image['id_image']);
$existing_img = $dir . $imageObj->getExistingImgPath() . '.jpg';
if (file_exists($existing_img) && filesize($existing_img)) {
foreach ($type as $imageType) {
if (!file_exists($dir . $imageObj->getExistingImgPath() . '-' . stripslashes($imageType['name']) . '.jpg')) {
if (!ImageManager::resize($existing_img, $dir . $imageObj->getExistingImgPath() . '-' . stripslashes($imageType['name']) . '.jpg', (int) $imageType['width'], (int) $imageType['height'])) {
$this->errors[] = $this->trans(
'Original image is corrupt (%filename%) for product ID %id% or bad permission on folder.',
array(
'%filename%' => $existing_img,
'%id%' => (int) $imageObj->id_product,
),
'Admin.Design.Notification'
);
}
if ($generate_hight_dpi_images) {
if (!ImageManager::resize($existing_img, $dir . $imageObj->getExistingImgPath() . '-' . stripslashes($imageType['name']) . '2x.jpg', (int) $imageType['width'] * 2, (int) $imageType['height'] * 2)) {
$this->errors[] = $this->trans(
'Original image is corrupt (%filename%) for product ID %id% or bad permission on folder.',
array(
'%filename%' => $existing_img,
'%id%' => (int) $imageObj->id_product,
),
'Admin.Design.Notification'
);
}
}
}
}
} else {
$this->errors[] = $this->trans(
'Original image is missing or empty (%filename%) for product ID %id%',
array(
'%filename%' => $existing_img,
'%id%' => (int) $imageObj->id_product,
),
'Admin.Design.Notification'
);
}
if (time() - $this->start_time > $this->max_execution_time - 4) { // stop 4 seconds before the tiemout, just enough time to process the end of the page on a slow server
return 'timeout';
}
}
}
return (bool) count($this->errors);
}
/**
* Regenerate no-pictures images.
*
* @param $dir
* @param $type
* @param $languages
*
* @return bool
*/
protected function _regenerateNoPictureImages($dir, $type, $languages)
{
$errors = false;
$generate_hight_dpi_images = (bool) Configuration::get('PS_HIGHT_DPI');
foreach ($type as $image_type) {
foreach ($languages as $language) {
$file = $dir . $language['iso_code'] . '.jpg';
if (!file_exists($file)) {
$file = _PS_PROD_IMG_DIR_ . Language::getIsoById((int) Configuration::get('PS_LANG_DEFAULT')) . '.jpg';
}
if (!file_exists($dir . $language['iso_code'] . '-default-' . stripslashes($image_type['name']) . '.jpg')) {
if (!ImageManager::resize($file, $dir . $language['iso_code'] . '-default-' . stripslashes($image_type['name']) . '.jpg', (int) $image_type['width'], (int) $image_type['height'])) {
$errors = true;
}
if ($generate_hight_dpi_images) {
if (!ImageManager::resize($file, $dir . $language['iso_code'] . '-default-' . stripslashes($image_type['name']) . '2x.jpg', (int) $image_type['width'] * 2, (int) $image_type['height'] * 2)) {
$errors = true;
}
}
}
}
}
return $errors;
}
/* Hook watermark optimization */
protected function _regenerateWatermark($dir, $type = null)
{
$result = Db::getInstance()->executeS('
SELECT m.`name` FROM `' . _DB_PREFIX_ . 'module` m
LEFT JOIN `' . _DB_PREFIX_ . 'hook_module` hm ON hm.`id_module` = m.`id_module`
LEFT JOIN `' . _DB_PREFIX_ . 'hook` h ON hm.`id_hook` = h.`id_hook`
WHERE h.`name` = \'actionWatermark\' AND m.`active` = 1');
if ($result && count($result)) {
$productsImages = Image::getAllImages();
foreach ($productsImages as $image) {
$imageObj = new Image($image['id_image']);
if (file_exists($dir . $imageObj->getExistingImgPath() . '.jpg')) {
foreach ($result as $module) {
$moduleInstance = Module::getInstanceByName($module['name']);
if ($moduleInstance && is_callable(array($moduleInstance, 'hookActionWatermark'))) {
call_user_func(array($moduleInstance, 'hookActionWatermark'), array('id_image' => $imageObj->id, 'id_product' => $imageObj->id_product, 'image_type' => $type));
}
if (time() - $this->start_time > $this->max_execution_time - 4) { // stop 4 seconds before the tiemout, just enough time to process the end of the page on a slow server
return 'timeout';
}
}
}
}
}
}
protected function _regenerateThumbnails($type = 'all', $deleteOldImages = false)
{
$this->start_time = time();
ini_set('max_execution_time', $this->max_execution_time); // ini_set may be disabled, we need the real value
$this->max_execution_time = (int) ini_get('max_execution_time');
$languages = Language::getLanguages(false);
$process = array(
array('type' => 'categories', 'dir' => _PS_CAT_IMG_DIR_),
array('type' => 'manufacturers', 'dir' => _PS_MANU_IMG_DIR_),
array('type' => 'suppliers', 'dir' => _PS_SUPP_IMG_DIR_),
array('type' => 'products', 'dir' => _PS_PROD_IMG_DIR_),
array('type' => 'stores', 'dir' => _PS_STORE_IMG_DIR_),
);
// Launching generation process
foreach ($process as $proc) {
if ($type != 'all' && $type != $proc['type']) {
continue;
}
// Getting format generation
$formats = ImageType::getImagesTypes($proc['type']);
if ($type != 'all') {
$format = (string) (Tools::getValue('format_' . $type));
if ($format != 'all') {
foreach ($formats as $k => $form) {
if ($form['id_image_type'] != $format) {
unset($formats[$k]);
}
}
}
}
if ($deleteOldImages) {
$this->_deleteOldImages($proc['dir'], $formats, ($proc['type'] == 'products' ? true : false));
}
if (($return = $this->_regenerateNewImages($proc['dir'], $formats, ($proc['type'] == 'products' ? true : false))) === true) {
if (!count($this->errors)) {
$this->errors[] = $this->trans('Cannot write images for this type: %1$s. Please check the %2$s folder\'s writing permissions.', array($proc['type'], $proc['dir']), 'Admin.Design.Notification');
}
} elseif ($return == 'timeout') {
$this->errors[] = $this->trans('Only part of the images have been regenerated. The server timed out before finishing.', array(), 'Admin.Design.Notification');
} else {
if ($proc['type'] == 'products') {
if ($this->_regenerateWatermark($proc['dir'], $formats) == 'timeout') {
$this->errors[] = $this->trans('Server timed out. The watermark may not have been applied to all images.', array(), 'Admin.Design.Notification');
}
}
if (!count($this->errors)) {
if ($this->_regenerateNoPictureImages($proc['dir'], $formats, $languages)) {
$this->errors[] = $this->trans('Cannot write "No picture" image to %s images folder. Please check the folder\'s writing permissions.', array($proc['type']), 'Admin.Design.Notification');
}
}
}
}
return count($this->errors) > 0 ? false : true;
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_image_type'] = array(
'href' => self::$currentIndex . '&addimage_type&token=' . $this->token,
'desc' => $this->trans('Add new image type', array(), 'Admin.Design.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
/**
* Move product images to the new filesystem.
*/
protected function _moveImagesToNewFileSystem()
{
if (!Image::testFileSystem()) {
$this->errors[] = $this->trans('Error: Your server configuration is not compatible with the new image system. No images were moved.', array(), 'Admin.Design.Notification');
} else {
ini_set('max_execution_time', $this->max_execution_time); // ini_set may be disabled, we need the real value
$this->max_execution_time = (int) ini_get('max_execution_time');
$result = Image::moveToNewFileSystem($this->max_execution_time);
if ($result === 'timeout') {
$this->errors[] = $this->trans('Not all images have been moved. The server timed out before finishing. Click on "Move images" again to resume the moving process.', array(), 'Admin.Design.Notification');
} elseif ($result === false) {
$this->errors[] = $this->trans('Error: Some -- or all -- images cannot be moved.', array(), 'Admin.Design.Notification');
}
}
return count($this->errors) > 0 ? false : true;
}
public function initContent()
{
if ($this->display != 'edit' && $this->display != 'add') {
$this->initRegenerate();
$this->context->smarty->assign(array(
'display_regenerate' => true,
'display_move' => $this->display_move,
));
}
if ($this->display == 'edit') {
$this->warnings[] = $this->trans('After modification, do not forget to regenerate thumbnails', array(), 'Admin.Design.Notification');
}
parent::initContent();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,150 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminLegacyLayoutControllerCore extends AdminController
{
public $outPutHtml = '';
protected $headerToolbarBtn = array();
protected $title;
protected $showContentHeader = true;
protected $headerTabContent = '';
protected $enableSidebar = false;
protected $helpLink;
public function __construct($controllerName = '', $title = '', $headerToolbarBtn = array(), $displayType = '', $showContentHeader = true, $headerTabContent = '', $enableSidebar = false, $helpLink = '')
{
// Compatibility with legacy behavior.
// Some controllers can only be used in "All shops" context.
// This makes sure that user cannot switch shop contexts
// when in one of pages (controller) below.
$controllers = ['AdminLanguages', 'AdminProfiles'];
if (in_array($controllerName, $controllers)) {
$this->multishop_context = Shop::CONTEXT_ALL;
}
parent::__construct($controllerName, 'new-theme');
$this->title = $title;
$this->meta_title = $title;
$this->display = $displayType;
$this->bootstrap = true;
$this->controller_name = $_GET['controller'] = $controllerName;
$this->id = Tab::getIdFromClassName($this->controller_name);
$this->headerToolbarBtn = $headerToolbarBtn;
$this->showContentHeader = $showContentHeader;
$this->headerTabContent = $headerTabContent;
$this->enableSidebar = $enableSidebar;
$this->helpLink = $helpLink;
$this->php_self = $controllerName;
$this->className = 'LegacyLayout';
}
public function setMedia($isNewTheme = false)
{
parent::setMedia(true);
}
public function viewAccess($disable = false)
{
return true;
}
//always return true, cause of legacy redirect in layout
public function checkAccess()
{
return true;
}
protected function addHeaderToolbarBtn()
{
$this->page_header_toolbar_btn = array_merge($this->page_header_toolbar_btn, $this->headerToolbarBtn);
}
public function initContent()
{
$this->addHeaderToolbarBtn();
$this->show_page_header_toolbar = (bool) $this->showContentHeader;
// @todo remove once the product page has been made responsive
$isProductPage = ('AdminProducts' === $this->controller_name);
$vars = array(
'viewport_scale' => $isProductPage ? '0.75' : '1',
'maintenance_mode' => !(bool) Configuration::get('PS_SHOP_ENABLE'),
'debug_mode' => (bool) _PS_MODE_DEV_,
'headerTabContent' => $this->headerTabContent,
'content' => '{$content}', //replace content by original smarty tag var
'enableSidebar' => $this->enableSidebar,
'lite_display' => $this->lite_display,
'url_post' => self::$currentIndex . '&token=' . $this->token,
'show_page_header_toolbar' => $this->show_page_header_toolbar,
'page_header_toolbar_title' => $this->page_header_toolbar_title,
'title' => $this->title ? $this->title : $this->page_header_toolbar_title,
'toolbar_btn' => $this->page_header_toolbar_btn,
'page_header_toolbar_btn' => $this->page_header_toolbar_btn,
'toggle_navigation_url' => $this->context->link->getAdminLink('AdminEmployees', true, [], [
'action' => 'toggleMenu',
]),
);
if ($this->helpLink === false || !empty($this->helpLink)) {
$vars['help_link'] = $this->helpLink;
}
$this->context->smarty->assign($vars);
}
public function initToolbarTitle()
{
$this->toolbar_title = array_unique($this->breadcrumbs);
parent::initToolbarTitle();
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
}
public function display()
{
ob_start();
parent::display();
$this->outPutHtml = ob_get_contents();
ob_end_clean();
$this->outPutHtml;
}
/**
* {@inheritdoc}
*/
public function addJquery($version = null, $folder = null, $minifier = true)
{
// jQuery is already included, so do nothing
@trigger_error(__FUNCTION__ . 'is deprecated and has no effect in the New Theme since version 1.7.6.0.', E_USER_DEPRECATED);
}
}

View File

@@ -0,0 +1,392 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminLoginControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
parent::__construct();
$this->errors = array();
$this->display_header = false;
$this->display_footer = false;
$this->layout = _PS_ADMIN_DIR_ . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $this->bo_theme
. DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . 'login'
. DIRECTORY_SEPARATOR . 'layout.tpl';
if (!headers_sent()) {
header('Login: true');
}
}
public function setMedia($isNewTheme = false)
{
$this->addJquery();
$this->addjqueryPlugin('validate');
$this->addJS(_PS_JS_DIR_ . 'jquery/plugins/validate/localization/messages_' . $this->context->language->iso_code . '.js');
$this->addCSS(__PS_BASE_URI__ . $this->admin_webpath . '/themes/' . $this->bo_theme . '/public/theme.css', 'all', 0);
$this->addJS(_PS_JS_DIR_ . 'vendor/spin.js');
$this->addJS(_PS_JS_DIR_ . 'vendor/ladda.js');
Media::addJsDef(array('img_dir' => _PS_IMG_));
Media::addJsDefL('one_error', $this->trans('There is one error.', array(), 'Admin.Notifications.Error'));
Media::addJsDefL('more_errors', $this->trans('There are several errors.', array(), 'Admin.Notifications.Error'));
Hook::exec('actionAdminLoginControllerSetMedia');
// Specific Admin Theme
$this->addCSS(__PS_BASE_URI__ . $this->admin_webpath . '/themes/' . $this->bo_theme . '/css/overrides.css', 'all', PHP_INT_MAX);
}
public function initContent()
{
if (!Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED')) {
// You can uncomment these lines if you want to force https even from localhost and automatically redirect
// header('HTTP/1.1 301 Moved Permanently');
// header('Location: '.Tools::getShopDomainSsl(true).$_SERVER['REQUEST_URI']);
// exit();
$clientIsMaintenanceOrLocal = in_array(Tools::getRemoteAddr(), array_merge(array('127.0.0.1'), explode(',', Configuration::get('PS_MAINTENANCE_IP'))));
// If ssl is enabled, https protocol is required. Exception for maintenance and local (127.0.0.1) IP
if ($clientIsMaintenanceOrLocal) {
$warningSslMessage = $this->trans('SSL is activated. However, your IP is allowed to enter unsecure mode for maintenance or local IP issues.', array(), 'Admin.Login.Notification');
} else {
$url = 'https://' . Tools::safeOutput(Tools::getServerName()) . Tools::safeOutput($_SERVER['REQUEST_URI']);
$warningSslMessage = $this->trans(
'SSL is activated. Please connect using the following link to [1]log in to secure mode (https://)[/1]',
array('[1]' => '<a href="' . $url . '">', '[/1]' => '</a>'),
'Admin.Login.Notification'
);
}
$this->context->smarty->assign('warningSslMessage', $warningSslMessage);
}
if (file_exists(_PS_ADMIN_DIR_ . '/../install')) {
$this->context->smarty->assign('wrong_install_name', true);
}
if (basename(_PS_ADMIN_DIR_) == 'admin' && file_exists(_PS_ADMIN_DIR_ . '/../admin/')) {
$rand = 'admin' . sprintf('%03d', mt_rand(0, 999)) . Tools::strtolower(Tools::passwdGen(6)) . '/';
if (@rename(_PS_ADMIN_DIR_ . '/../admin/', _PS_ADMIN_DIR_ . '/../' . $rand)) {
Tools::redirectAdmin('../' . $rand);
} else {
$this->context->smarty->assign(array(
'wrong_folder_name' => true,
));
}
} else {
$rand = basename(_PS_ADMIN_DIR_) . '/';
}
$this->context->smarty->assign(array(
'randomNb' => $rand,
'adminUrl' => Tools::getCurrentUrlProtocolPrefix() . Tools::getShopDomain() . __PS_BASE_URI__ . $rand,
));
// Redirect to admin panel
if (Tools::isSubmit('redirect') && Validate::isControllerName(Tools::getValue('redirect'))) {
$this->context->smarty->assign('redirect', Tools::getValue('redirect'));
} else {
$tab = new Tab((int) $this->context->employee->default_tab);
$this->context->smarty->assign('redirect', $this->context->link->getAdminLink($tab->class_name));
}
if ($nb_errors = count($this->errors)) {
$this->context->smarty->assign(array(
'errors' => $this->errors,
'nbErrors' => $nb_errors,
'shop_name' => Tools::safeOutput(Configuration::get('PS_SHOP_NAME')),
'disableDefaultErrorOutPut' => true,
));
}
if ($email = Tools::getValue('email')) {
$this->context->smarty->assign('email', $email);
}
if ($password = Tools::getValue('password')) {
$this->context->smarty->assign('password', $password);
}
// For reset password feature
if ($reset_token = Tools::getValue('reset_token')) {
$this->context->smarty->assign('reset_token', $reset_token);
}
if ($id_employee = Tools::getValue('id_employee')) {
$this->context->smarty->assign('id_employee', $id_employee);
$employee = new Employee($id_employee);
if (Validate::isLoadedObject($employee)) {
$this->context->smarty->assign('reset_email', $employee->email);
}
}
$this->setMedia($isNewTheme = false);
$this->initHeader();
parent::initContent();
$this->initFooter();
//force to disable modals
$this->context->smarty->assign('modals', null);
}
public function checkToken()
{
return true;
}
/**
* All BO users can access the login page.
*
* @return bool
*/
public function viewAccess($disable = false)
{
return true;
}
public function postProcess()
{
if (Tools::isSubmit('submitLogin')) {
$this->processLogin();
} elseif (Tools::isSubmit('submitForgot')) {
$this->processForgot();
} elseif (Tools::isSubmit('submitReset')) {
$this->processReset();
}
}
public function processLogin()
{
/* Check fields validity */
$passwd = trim(Tools::getValue('passwd'));
$email = trim(Tools::getValue('email'));
if (empty($email)) {
$this->errors[] = $this->trans('Email is empty.', array(), 'Admin.Notifications.Error');
} elseif (!Validate::isEmail($email)) {
$this->errors[] = $this->trans('Invalid email address.', array(), 'Admin.Notifications.Error');
}
if (empty($passwd)) {
$this->errors[] = $this->trans('The password field is blank.', array(), 'Admin.Notifications.Error');
} elseif (!Validate::isPasswd($passwd)) {
$this->errors[] = $this->trans('Invalid password.', array(), 'Admin.Notifications.Error');
}
if (!count($this->errors)) {
// Find employee
$this->context->employee = new Employee();
$is_employee_loaded = $this->context->employee->getByEmail($email, $passwd);
$employee_associated_shop = $this->context->employee->getAssociatedShops();
if (!$is_employee_loaded) {
$this->errors[] = $this->trans('The employee does not exist, or the password provided is incorrect.', array(), 'Admin.Login.Notification');
$this->context->employee->logout();
} elseif (empty($employee_associated_shop) && !$this->context->employee->isSuperAdmin()) {
$this->errors[] = $this->trans('This employee does not manage the shop anymore (either the shop has been deleted or permissions have been revoked).', array(), 'Admin.Login.Notification');
$this->context->employee->logout();
} else {
PrestaShopLogger::addLog($this->trans('Back office connection from %ip%', array('%ip%' => Tools::getRemoteAddr()), 'Admin.Advparameters.Feature'), 1, null, '', 0, true, (int) $this->context->employee->id);
$this->context->employee->remote_addr = (int) ip2long(Tools::getRemoteAddr());
// Update cookie
$cookie = Context::getContext()->cookie;
$cookie->id_employee = $this->context->employee->id;
$cookie->email = $this->context->employee->email;
$cookie->profile = $this->context->employee->id_profile;
$cookie->passwd = $this->context->employee->passwd;
$cookie->remote_addr = $this->context->employee->remote_addr;
$cookie->registerSession(new EmployeeSession());
if (!Tools::getValue('stay_logged_in')) {
$cookie->last_activity = time();
}
$cookie->write();
// If there is a valid controller name submitted, redirect to it
if (isset($_POST['redirect']) && Validate::isControllerName($_POST['redirect'])) {
$url = $this->context->link->getAdminLink($_POST['redirect']);
} else {
$tab = new Tab((int) $this->context->employee->default_tab);
$url = $this->context->link->getAdminLink($tab->class_name);
}
if (Tools::isSubmit('ajax')) {
die(json_encode(array('hasErrors' => false, 'redirect' => $url)));
} else {
$this->redirect_after = $url;
}
}
}
if (Tools::isSubmit('ajax')) {
die(json_encode(array('hasErrors' => true, 'errors' => $this->errors)));
}
}
public function processForgot()
{
if (_PS_MODE_DEMO_) {
$this->errors[] = $this->trans('This functionality has been disabled.', array(), 'Admin.Notifications.Error');
} elseif (!($email = trim(Tools::getValue('email_forgot')))) {
$this->errors[] = $this->trans('Email is empty.', array(), 'Admin.Notifications.Error');
} elseif (!Validate::isEmail($email)) {
$this->errors[] = $this->trans('Invalid email address.', array(), 'Admin.Notifications.Error');
} else {
$employee = new Employee();
if (!$employee->getByEmail($email) || !$employee) {
$this->errors[] = $this->trans('This account does not exist.', array(), 'Admin.Login.Notification');
} elseif ((strtotime($employee->last_passwd_gen . '+' . Configuration::get('PS_PASSWD_TIME_BACK') . ' minutes') - time()) > 0) {
$this->errors[] = $this->trans('You can reset your password every %interval% minute(s) only. Please try again later.', array('%interval%' => Configuration::get('PS_PASSWD_TIME_BACK')), 'Admin.Login.Notification');
}
}
if (!count($this->errors)) {
if (!$employee->hasRecentResetPasswordToken()) {
$employee->stampResetPasswordToken();
$employee->update();
}
$admin_url = $this->context->link->getAdminLink('AdminLogin');
$params = array(
'{email}' => $employee->email,
'{lastname}' => $employee->lastname,
'{firstname}' => $employee->firstname,
'{url}' => $admin_url . '&id_employee=' . (int) $employee->id . '&reset_token=' . $employee->reset_password_token,
);
$employeeLanguage = new Language((int) $employee->id_lang);
if (
Mail::Send(
$employee->id_lang,
'password_query',
$this->trans(
'Your new password',
array(),
'Emails.Subject',
$employeeLanguage->locale
),
$params,
$employee->email,
$employee->firstname . ' ' . $employee->lastname
)
) {
// Update employee only if the mail can be sent
Shop::setContext(Shop::CONTEXT_SHOP, (int) min($employee->getAssociatedShops()));
die(Tools::jsonEncode(array(
'hasErrors' => false,
'confirm' => $this->trans('Please, check your mailbox. A link to reset your password has been sent to you.', array(), 'Admin.Login.Notification'),
)));
} else {
die(Tools::jsonEncode(array(
'hasErrors' => true,
'errors' => array($this->trans('An error occurred while attempting to reset your password.', array(), 'Admin.Login.Notification')),
)));
}
} elseif (Tools::isSubmit('ajax')) {
die(Tools::jsonEncode(array('hasErrors' => true, 'errors' => $this->errors)));
}
}
public function processReset()
{
if (_PS_MODE_DEMO_) {
$this->errors[] = $this->trans('This functionality has been disabled.', array(), 'Admin.Notifications.Error');
} elseif (!($reset_token_value = trim(Tools::getValue('reset_token')))) {
// hidden fields
$this->errors[] = $this->trans('Some identification information is missing.', array(), 'Admin.Login.Notification');
} elseif (!($id_employee = trim(Tools::getValue('id_employee')))) {
$this->errors[] = $this->trans('Some identification information is missing.', array(), 'Admin.Login.Notification');
} elseif (!($reset_email = trim(Tools::getValue('reset_email')))) {
$this->errors[] = $this->trans('Some identification information is missing.', array(), 'Admin.Login.Notification');
} elseif (!($reset_password = trim(Tools::getValue('reset_passwd')))) {
// password (twice)
$this->errors[] = $this->trans('The password is missing: please enter your new password.', array(), 'Admin.Login.Notification');
} elseif (!Validate::isPasswd($reset_password)) {
$this->errors[] = $this->trans('The password is not in a valid format.', array(), 'Admin.Login.Notification');
} elseif (!($reset_confirm = trim(Tools::getValue('reset_confirm')))) {
$this->errors[] = $this->trans('The confirmation is empty: please fill in the password confirmation as well.', array(), 'Admin.Login.Notification');
} elseif ($reset_password !== $reset_confirm) {
$this->errors[] = $this->trans('The password and its confirmation do not match. Please double check both passwords.', array(), 'Admin.Login.Notification');
} else {
$employee = new Employee();
if (!$employee->getByEmail($reset_email) || !$employee || $employee->id != $id_employee) { // check matching employee id with its email
$this->errors[] = $this->trans('This account does not exist.', array(), 'Admin.Login.Notification');
} elseif ((strtotime($employee->last_passwd_gen . '+' . Configuration::get('PS_PASSWD_TIME_BACK') . ' minutes') - time()) > 0) {
$this->errors[] = $this->trans('You can reset your password every %interval% minute(s) only. Please try again later.', array('%interval%' => Configuration::get('PS_PASSWD_TIME_BACK')), 'Admin.Login.Notification');
} elseif ($employee->getValidResetPasswordToken() !== $reset_token_value) {
// To update password, we must have the temporary reset token that matches.
$this->errors[] = $this->trans('Your password reset request expired. Please start again.', array(), 'Admin.Login.Notification');
}
}
if (!count($this->errors)) {
$employee->passwd = $this->get('hashing')->hash($reset_password, _COOKIE_KEY_);
$employee->last_passwd_gen = date('Y-m-d H:i:s', time());
$params = array(
'{email}' => $employee->email,
'{lastname}' => $employee->lastname,
'{firstname}' => $employee->firstname,
);
$employeeLanguage = new Language((int) $this->context->employee->id_lang);
if (
Mail::Send(
$employee->id_lang,
'password',
$this->trans(
'Your new password',
array(),
'Emails.Subject',
$employeeLanguage->locale
),
$params,
$employee->email,
$employee->firstname . ' ' . $employee->lastname
)
) {
// Update employee only if the mail can be sent
Shop::setContext(Shop::CONTEXT_SHOP, (int) min($employee->getAssociatedShops()));
$result = $employee->update();
if (!$result) {
$this->errors[] = $this->trans('An error occurred while attempting to change your password.', array(), 'Admin.Login.Notification');
} else {
$employee->removeResetPasswordToken(); // Delete temporary reset token
$employee->update();
die(Tools::jsonEncode(array(
'hasErrors' => false,
'confirm' => $this->trans('The password has been changed successfully.', array(), 'Admin.Login.Notification'),
)));
}
} else {
die(Tools::jsonEncode(array(
'hasErrors' => true,
'errors' => array($this->trans('An error occurred while attempting to change your password.', array(), 'Admin.Login.Notification')),
)));
}
} elseif (Tools::isSubmit('ajax')) {
die(Tools::jsonEncode(array('hasErrors' => true, 'errors' => $this->errors)));
}
}
}

View File

@@ -0,0 +1,878 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Manufacturer $object
*/
class AdminManufacturersControllerCore extends AdminController
{
public $bootstrap = true;
/** @var array countries list */
protected $countries_array = array();
/**
* @deprecated since 1.7.6, to be removed in the next minor
*/
public function __construct()
{
@trigger_error(
'The AdminManufacturersController is deprecated and will be removed in the next minor',
E_USER_DEPRECATED
);
$this->table = 'manufacturer';
$this->className = 'Manufacturer';
$this->lang = false;
$this->deleted = false;
$this->allow_export = true;
$this->list_id = 'manufacturer';
$this->identifier = 'id_manufacturer';
$this->_defaultOrderBy = 'name';
$this->_defaultOrderWay = 'ASC';
parent::__construct();
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'icon' => 'icon-trash',
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
),
);
$this->fieldImageSettings = array(
'name' => 'logo',
'dir' => 'm',
);
$this->fields_list = array(
'id_manufacturer' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'logo' => array(
'title' => $this->trans('Logo', array(), 'Admin.Global'),
'image' => 'm',
'orderby' => false,
'search' => false,
'align' => 'center',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'width' => 'auto',
),
'addresses' => array(
'title' => $this->trans('Addresses', array(), 'Admin.Catalog.Feature'),
'search' => false,
'align' => 'center',
),
'products' => array(
'title' => $this->trans('Products', array(), 'Admin.Catalog.Feature'),
'search' => false,
'align' => 'center',
),
'active' => array(
'title' => $this->trans('Enabled', array(), 'Admin.Global'),
'active' => 'status',
'type' => 'bool',
'align' => 'center',
'class' => 'fixed-width-xs',
'orderby' => false,
),
);
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryUi('ui.widget');
$this->addJqueryPlugin('tagify');
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_manufacturer'] = array(
'href' => self::$currentIndex . '&addmanufacturer&token=' . $this->token,
'desc' => $this->trans('Add new brand', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
$this->page_header_toolbar_btn['new_manufacturer_address'] = array(
'href' => self::$currentIndex . '&addaddress&token=' . $this->token,
'desc' => $this->trans('Add new brand address', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
} elseif ($this->display == 'editaddresses' || $this->display == 'addaddress') {
// Default cancel button - like old back link
if (!isset($this->no_back) || $this->no_back == false) {
$back = Tools::safeOutput(Tools::getValue('back', ''));
if (empty($back)) {
$back = self::$currentIndex . '&token=' . $this->token;
}
$this->page_header_toolbar_btn['cancel'] = array(
'href' => $back,
'desc' => $this->trans('Cancel', array(), 'Admin.Actions'),
);
}
}
parent::initPageHeaderToolbar();
}
public function initListManufacturer()
{
$this->addRowAction('view');
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_select = '
COUNT(`id_product`) AS `products`, (
SELECT COUNT(ad.`id_manufacturer`) as `addresses`
FROM `' . _DB_PREFIX_ . 'address` ad
WHERE ad.`id_manufacturer` = a.`id_manufacturer`
AND ad.`deleted` = 0
GROUP BY ad.`id_manufacturer`) as `addresses`';
$this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON (a.`id_manufacturer` = p.`id_manufacturer`)';
$this->_group = 'GROUP BY a.`id_manufacturer`';
$this->context->smarty->assign('title_list', $this->trans('List of brands', array(), 'Admin.Catalog.Feature'));
$this->content .= parent::renderList();
}
protected function getAddressFieldsList()
{
// Sub tab addresses
$countries = Country::getCountries($this->context->language->id);
foreach ($countries as $country) {
$this->countries_array[$country['id_country']] = $country['name'];
}
return array(
'id_address' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'manufacturer_name' => array(
'title' => $this->trans('Brand', array(), 'Admin.Global'),
'width' => 'auto',
'filter_key' => 'm!name',
),
'firstname' => array(
'title' => $this->trans('First name', array(), 'Admin.Global'),
'maxlength' => 30,
),
'lastname' => array(
'title' => $this->trans('Last name', array(), 'Admin.Global'),
'filter_key' => 'a!lastname',
'maxlength' => 30,
),
'postcode' => array(
'title' => $this->trans('Zip/Postal code', array(), 'Admin.Global'),
'align' => 'right',
),
'city' => array(
'title' => $this->trans('City', array(), 'Admin.Global'),
),
'country' => array(
'title' => $this->trans('Country', array(), 'Admin.Global'),
'type' => 'select',
'list' => $this->countries_array,
'filter_key' => 'cl!id_country',
),
);
}
public function processExport($text_delimiter = '"')
{
if (strtolower($this->table) == 'address') {
$this->_defaultOrderBy = 'id_manufacturer';
$this->_where = 'AND a.`id_customer` = 0 AND a.`id_supplier` = 0 AND a.`id_warehouse` = 0 AND a.`deleted`= 0';
}
return parent::processExport($text_delimiter);
}
public function initListManufacturerAddresses()
{
$this->toolbar_title = $this->trans('Addresses', array(), 'Admin.Catalog.Feature');
// reset actions and query vars
$this->actions = array();
unset($this->fields_list, $this->_select, $this->_join, $this->_group, $this->_filterHaving, $this->_filter);
$this->table = 'address';
$this->list_id = 'address';
$this->identifier = 'id_address';
$this->deleted = true;
$this->_defaultOrderBy = 'id_address';
$this->_defaultOrderWay = 'ASC';
$this->_orderBy = null;
$this->addRowAction('editaddresses');
$this->addRowAction('delete');
// test if a filter is applied for this list
if (Tools::isSubmit('submitFilter' . $this->table) || $this->context->cookie->{'submitFilter' . $this->table} !== false) {
$this->filter = true;
}
// test if a filter reset request is required for this list
$this->action = (isset($_POST['submitReset' . $this->table]) ? 'reset_filters' : '');
$this->fields_list = $this->getAddressFieldsList();
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'icon' => 'icon-trash',
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
),
);
$this->_select = 'cl.`name` as country, m.`name` AS manufacturer_name';
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'country_lang` cl
ON (cl.`id_country` = a.`id_country` AND cl.`id_lang` = ' . (int) $this->context->language->id . ') ';
$this->_join .= '
LEFT JOIN `' . _DB_PREFIX_ . 'manufacturer` m
ON (a.`id_manufacturer` = m.`id_manufacturer`)';
$this->_where = 'AND a.`id_customer` = 0 AND a.`id_supplier` = 0 AND a.`id_warehouse` = 0 AND a.`deleted`= 0';
$this->context->smarty->assign('title_list', $this->trans('Brand addresses', array(), 'Admin.Catalog.Feature'));
// call postProcess() for take care about actions and filters
$this->postProcess();
$this->initToolbar();
$this->content .= parent::renderList();
}
public function renderList()
{
$this->initListManufacturer();
$this->initListManufacturerAddresses();
}
/**
* Display editaddresses action link.
*
* @param string $token the token to add to the link
* @param int $id the identifier to add to the link
*
* @return string
*/
public function displayEditaddressesLink($token, $id)
{
if (!array_key_exists('editaddresses', self::$cache_lang)) {
self::$cache_lang['editaddresses'] = $this->trans('Edit', array(), 'Admin.Actions');
}
$this->context->smarty->assign(array(
'href' => self::$currentIndex .
'&' . $this->identifier . '=' . $id .
'&editaddresses&token=' . ($token != null ? $token : $this->token),
'action' => self::$cache_lang['editaddresses'],
));
return $this->context->smarty->fetch('helpers/list/list_action_edit.tpl');
}
public function renderForm()
{
if (!($manufacturer = $this->loadObject(true))) {
return;
}
$image = _PS_MANU_IMG_DIR_ . $manufacturer->id . '.jpg';
$image_url = ImageManager::thumbnail(
$image,
$this->table . '_' . (int) $manufacturer->id . '.' . $this->imageType,
350,
$this->imageType,
true,
true
);
$image_size = file_exists($image) ? filesize($image) / 1000 : false;
$this->fields_form = array(
'tinymce' => true,
'legend' => array(
'title' => $this->trans('Brands', array(), 'Admin.Catalog.Feature'),
'icon' => 'icon-certificate',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'col' => 4,
'required' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'textarea',
'label' => $this->trans('Short description', array(), 'Admin.Catalog.Feature'),
'name' => 'short_description',
'lang' => true,
'cols' => 60,
'rows' => 10,
'autoload_rte' => 'rte', //Enable TinyMCE editor for short description
'col' => 6,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'textarea',
'label' => $this->trans('Description', array(), 'Admin.Global'),
'name' => 'description',
'lang' => true,
'cols' => 60,
'rows' => 10,
'col' => 6,
'autoload_rte' => 'rte', //Enable TinyMCE editor for description
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'file',
'label' => $this->trans('Logo', array(), 'Admin.Global'),
'name' => 'logo',
'image' => $image_url ? $image_url : false,
'size' => $image_size,
'display_image' => true,
'col' => 6,
'hint' => $this->trans('Upload a brand logo from your computer.', array(), 'Admin.Catalog.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Meta title', array(), 'Admin.Global'),
'name' => 'meta_title',
'lang' => true,
'col' => 4,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Meta description', array(), 'Admin.Global'),
'name' => 'meta_description',
'lang' => true,
'col' => 6,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'tags',
'label' => $this->trans('Meta keywords', array(), 'Admin.Global'),
'name' => 'meta_keywords',
'lang' => true,
'col' => 6,
'hint' => array(
$this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
$this->trans('To add "tags," click inside the field, write something, and then press "Enter."', array(), 'Admin.Catalog.Help'),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Enable', array(), 'Admin.Actions'),
'name' => 'active',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
),
);
if (!($manufacturer = $this->loadObject(true))) {
return;
}
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$this->fields_form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
foreach ($this->_languages as $language) {
$this->fields_value['short_description_' . $language['id_lang']] = htmlentities(stripslashes($this->getFieldValue(
$manufacturer,
'short_description',
$language['id_lang']
)), ENT_COMPAT, 'UTF-8');
$this->fields_value['description_' . $language['id_lang']] = htmlentities(stripslashes($this->getFieldValue(
$manufacturer,
'description',
$language['id_lang']
)), ENT_COMPAT, 'UTF-8');
}
return parent::renderForm();
}
public function renderFormAddress()
{
// Change table and className for addresses
$this->table = 'address';
$this->className = 'ManufacturerAddress';
$id_address = Tools::getValue('id_address');
// Create Object Address
$address = new ManufacturerAddress($id_address);
$res = $address->getFieldsRequiredDatabase();
$required_fields = array();
foreach ($res as $row) {
$required_fields[(int) $row['id_required_field']] = $row['field_name'];
}
$form = array(
'legend' => array(
'title' => $this->trans('Addresses', array(), 'Admin.Catalog.Feature'),
'icon' => 'icon-building',
),
);
if (!$address->id_manufacturer || !Manufacturer::manufacturerExists($address->id_manufacturer)) {
$form['input'][] = array(
'type' => 'select',
'label' => $this->trans('Choose the brand', array(), 'Admin.Catalog.Feature'),
'name' => 'id_manufacturer',
'options' => array(
'query' => Manufacturer::getManufacturers(),
'id' => 'id_manufacturer',
'name' => 'name',
),
);
} else {
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('Brand', array(), 'Admin.Global'),
'name' => 'name',
'col' => 4,
'disabled' => true,
);
$form['input'][] = array(
'type' => 'hidden',
'name' => 'id_manufacturer',
);
}
$form['input'][] = array(
'type' => 'hidden',
'name' => 'alias',
);
$form['input'][] = array(
'type' => 'hidden',
'name' => 'id_address',
);
if (in_array('company', $required_fields)) {
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('Company', array(), 'Admin.Global'),
'name' => 'company',
'display' => in_array('company', $required_fields),
'required' => in_array('company', $required_fields),
'maxlength' => 16,
'col' => 4,
'hint' => $this->trans('Company name for this brand', array(), 'Admin.Catalog.Help'),
);
}
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('Last name', array(), 'Admin.Global'),
'name' => 'lastname',
'required' => true,
'col' => 4,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' 0-9!&lt;&gt;,;?=+()@#"<22>{}_$%:',
);
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('First name', array(), 'Admin.Global'),
'name' => 'firstname',
'required' => true,
'col' => 4,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' 0-9!&lt;&gt;,;?=+()@#"<22>{}_$%:',
);
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('Address', array(), 'Admin.Global'),
'name' => 'address1',
'col' => 6,
'required' => true,
);
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('Address (2)', array(), 'Admin.Global'),
'name' => 'address2',
'col' => 6,
'required' => in_array('address2', $required_fields),
);
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('Zip/postal code', array(), 'Admin.Global'),
'name' => 'postcode',
'col' => 2,
'required' => in_array('postcode', $required_fields),
);
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('City', array(), 'Admin.Global'),
'name' => 'city',
'col' => 4,
'required' => true,
);
$form['input'][] = array(
'type' => 'select',
'label' => $this->trans('Country', array(), 'Admin.Global'),
'name' => 'id_country',
'required' => false,
'default_value' => (int) $this->context->country->id,
'col' => 4,
'options' => array(
'query' => Country::getCountries($this->context->language->id),
'id' => 'id_country',
'name' => 'name',
),
);
$form['input'][] = array(
'type' => 'select',
'label' => $this->trans('State', array(), 'Admin.Global'),
'name' => 'id_state',
'required' => false,
'col' => 4,
'options' => array(
'query' => array(),
'id' => 'id_state',
'name' => 'name',
),
);
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('Home phone', array(), 'Admin.Global'),
'name' => 'phone',
'col' => 4,
'required' => in_array('phone', $required_fields),
);
$form['input'][] = array(
'type' => 'text',
'label' => $this->trans('Mobile phone', array(), 'Admin.Global'),
'name' => 'phone_mobile',
'col' => 4,
'required' => in_array('phone_mobile', $required_fields),
);
$form['input'][] = array(
'type' => 'textarea',
'label' => $this->trans('Other', array(), 'Admin.Global'),
'name' => 'other',
'required' => false,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
'rows' => 2,
'cols' => 10,
'col' => 6,
);
$form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
$this->fields_value = array(
'name' => Manufacturer::getNameById($address->id_manufacturer),
'alias' => 'manufacturer',
'id_country' => $address->id_country,
);
$this->initToolbar();
$this->fields_form[0]['form'] = $form;
$this->getlanguages();
$helper = new HelperForm();
$helper->show_cancel_button = true;
$back = Tools::safeOutput(Tools::getValue('back', ''));
if (empty($back)) {
$back = self::$currentIndex . '&token=' . $this->token;
}
if (!Validate::isCleanHtml($back)) {
die(Tools::displayError());
}
$helper->back_url = $back;
$helper->currentIndex = self::$currentIndex;
$helper->token = $this->token;
$helper->table = $this->table;
$helper->identifier = $this->identifier;
$helper->title = $this->trans('Edit Addresses', array(), 'Admin.Catalog.Feature');
$helper->id = $address->id;
$helper->toolbar_scroll = true;
$helper->languages = $this->_languages;
$helper->default_form_language = $this->default_form_language;
$helper->allow_employee_form_lang = $this->allow_employee_form_lang;
$helper->fields_value = $this->getFieldsValue($address);
$helper->toolbar_btn = $this->toolbar_btn;
$this->content .= $helper->generateForm($this->fields_form);
}
/**
* AdminController::initToolbar() override.
*
* @see AdminController::initToolbar()
*/
public function initToolbar()
{
switch ($this->display) {
case 'editaddresses':
case 'addaddress':
$this->toolbar_btn['save'] = array(
'href' => '#',
'desc' => $this->trans('Save', array(), 'Admin.Actions'),
);
// Default cancel button - like old back link
if (!isset($this->no_back) || $this->no_back == false) {
$back = Tools::safeOutput(Tools::getValue('back', ''));
if (empty($back)) {
$back = self::$currentIndex . '&token=' . $this->token;
}
$this->toolbar_btn['cancel'] = array(
'href' => $back,
'desc' => $this->trans('Cancel', array(), 'Admin.Actions'),
);
}
break;
default:
parent::initToolbar();
if ($this->can_import) {
$this->toolbar_btn['import'] = array(
'href' => $this->context->link->getAdminLink('AdminImport', true) . '&import_type=manufacturers',
'desc' => $this->trans('Import', array(), 'Admin.Actions'),
);
}
}
}
public function renderView()
{
if (!($manufacturer = $this->loadObject())) {
return;
}
/* @var Manufacturer $manufacturer */
$this->toolbar_btn['new'] = array(
'href' => $this->context->link->getAdminLink('AdminManufacturers') . '&addaddress=1&id_manufacturer=' . (int) $manufacturer->id,
'desc' => $this->trans('Add address', array(), 'Admin.Catalog.Feature'),
);
$this->toolbar_title = is_array($this->breadcrumbs) ? array_unique($this->breadcrumbs) : array($this->breadcrumbs);
$this->toolbar_title[] = $manufacturer->name;
$addresses = $manufacturer->getAddresses($this->context->language->id);
$products = $manufacturer->getProductsLite($this->context->language->id);
$total_product = count($products);
for ($i = 0; $i < $total_product; ++$i) {
$products[$i] = new Product($products[$i]['id_product'], false, $this->context->language->id);
$products[$i]->loadStockData();
/* Build attributes combinations */
$combinations = $products[$i]->getAttributeCombinations($this->context->language->id);
foreach ($combinations as $combination) {
$comb_array[$combination['id_product_attribute']]['reference'] = $combination['reference'];
$comb_array[$combination['id_product_attribute']]['ean13'] = $combination['ean13'];
$comb_array[$combination['id_product_attribute']]['upc'] = $combination['upc'];
$comb_array[$combination['id_product_attribute']]['quantity'] = $combination['quantity'];
$comb_array[$combination['id_product_attribute']]['attributes'][] = array(
$combination['group_name'],
$combination['attribute_name'],
$combination['id_attribute'],
);
}
if (isset($comb_array)) {
foreach ($comb_array as $key => $product_attribute) {
$list = '';
foreach ($product_attribute['attributes'] as $attribute) {
$list .= $attribute[0] . ' - ' . $attribute[1] . ', ';
}
$comb_array[$key]['attributes'] = rtrim($list, ', ');
}
isset($comb_array) ? $products[$i]->combination = $comb_array : '';
unset($comb_array);
}
}
$this->tpl_view_vars = array(
'manufacturer' => $manufacturer,
'addresses' => $addresses,
'products' => $products,
'stock_management' => Configuration::get('PS_STOCK_MANAGEMENT'),
'shopContext' => Shop::getContext(),
);
return parent::renderView();
}
public function initContent()
{
if ($this->display == 'editaddresses' || $this->display == 'addaddress') {
$this->content .= $this->renderFormAddress();
} elseif ($this->display == 'edit' || $this->display == 'add') {
if (!$this->loadObject(true)) {
return;
}
$this->content .= $this->renderForm();
} elseif ($this->display == 'view') {
// Some controllers use the view action without an object
if ($this->className) {
$this->loadObject(true);
}
$this->content .= $this->renderView();
} elseif (!$this->ajax) {
$this->content .= $this->renderList();
$this->content .= $this->renderOptions();
}
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
/**
* AdminController::init() override.
*
* @see AdminController::init()
*/
public function init()
{
parent::init();
if (Tools::isSubmit('editaddresses')) {
$this->display = 'editaddresses';
} elseif (Tools::isSubmit('updateaddress')) {
$this->display = 'editaddresses';
} elseif (Tools::isSubmit('addaddress')) {
$this->display = 'addaddress';
} elseif (Tools::isSubmit('submitAddaddress')) {
$this->action = 'save';
} elseif (Tools::isSubmit('deleteaddress')) {
$this->action = 'delete';
}
}
public function initProcess()
{
if (Tools::isSubmit('submitAddaddress') || Tools::isSubmit('deleteaddress') || Tools::isSubmit('submitBulkdeleteaddress') || Tools::isSubmit('exportaddress')) {
$this->table = 'address';
$this->className = 'ManufacturerAddress';
$this->identifier = 'id_address';
$this->deleted = true;
$this->fields_list = $this->getAddressFieldsList();
}
parent::initProcess();
}
protected function afterImageUpload()
{
$res = true;
$generate_hight_dpi_images = (bool) Configuration::get('PS_HIGHT_DPI');
/* Generate image with differents size */
if (($id_manufacturer = (int) Tools::getValue('id_manufacturer')) &&
isset($_FILES) &&
count($_FILES) &&
file_exists(_PS_MANU_IMG_DIR_ . $id_manufacturer . '.jpg')) {
$images_types = ImageType::getImagesTypes('manufacturers');
foreach ($images_types as $image_type) {
$res &= ImageManager::resize(
_PS_MANU_IMG_DIR_ . $id_manufacturer . '.jpg',
_PS_MANU_IMG_DIR_ . $id_manufacturer . '-' . stripslashes($image_type['name']) . '.jpg',
(int) $image_type['width'],
(int) $image_type['height']
);
if ($generate_hight_dpi_images) {
$res &= ImageManager::resize(
_PS_MANU_IMG_DIR_ . $id_manufacturer . '.jpg',
_PS_MANU_IMG_DIR_ . $id_manufacturer . '-' . stripslashes($image_type['name']) . '2x.jpg',
(int) $image_type['width'] * 2,
(int) $image_type['height'] * 2
);
}
}
$current_logo_file = _PS_TMP_IMG_DIR_ . 'manufacturer_mini_' . $id_manufacturer . '_' . $this->context->shop->id . '.jpg';
if ($res && file_exists($current_logo_file)) {
unlink($current_logo_file);
}
}
if (!$res) {
$this->errors[] = $this->trans('Unable to resize one or more of your pictures.', array(), 'Admin.Catalog.Notification');
}
return $res;
}
protected function beforeDelete($object)
{
return true;
}
public function processSave()
{
if (Tools::isSubmit('submitAddaddress')) {
$this->display = 'editaddresses';
}
return parent::processSave();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,644 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminModulesPositionsControllerCore extends AdminController
{
protected $display_key = 0;
/**
* @deprecated since 1.7.6, to be removed in the next minor
*/
public function __construct()
{
@trigger_error(
'The AdminModulesPositionsController is deprecated and will be removed in the next minor',
E_USER_DEPRECATED
);
$this->bootstrap = true;
parent::__construct();
}
public function postProcess()
{
// Getting key value for display
if (Tools::getValue('show_modules') && (string) (Tools::getValue('show_modules')) != 'all') {
$this->display_key = (int) Tools::getValue('show_modules');
}
$this->addjQueryPlugin(array(
'select2',
));
$this->addJS(array(
_PS_JS_DIR_ . 'admin/modules-position.js',
_PS_JS_DIR_ . 'jquery/plugins/select2/select2_locale_' . $this->context->language->iso_code . '.js',
));
$baseUrl = $this->context->link->getAdminLink('AdminModulesPositions');
if (strpos($baseUrl, '?') === false) {
$baseUrl .= '?';
}
// Change position in hook
if (array_key_exists('changePosition', $_GET)) {
if ($this->access('edit')) {
$id_module = (int) Tools::getValue('id_module');
$id_hook = (int) Tools::getValue('id_hook');
$module = Module::getInstanceById($id_module);
if (Validate::isLoadedObject($module)) {
$module->updatePosition($id_hook, (int) Tools::getValue('direction'));
Tools::redirectAdmin($baseUrl . ($this->display_key ? '&show_modules=' . $this->display_key : '') . '&token=' . $this->token);
} else {
$this->errors[] = $this->trans('This module cannot be loaded.', array(), 'Admin.Modules.Notification');
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('submitAddToHook')) {
// Add new module in hook
if ($this->access('add')) {
// Getting vars...
$id_module = (int) Tools::getValue('id_module');
$module = Module::getInstanceById($id_module);
$id_hook = (int) Tools::getValue('id_hook');
$hook = new Hook($id_hook);
if (!$id_module || !Validate::isLoadedObject($module)) {
$this->errors[] = $this->trans('This module cannot be loaded.', array(), 'Admin.Modules.Notification');
} elseif (!$id_hook || !Validate::isLoadedObject($hook)) {
$this->errors[] = $this->trans('Hook cannot be loaded.', array(), 'Admin.Modules.Notification');
} elseif (Hook::getModulesFromHook($id_hook, $id_module)) {
$this->errors[] = $this->trans('This module has already been transplanted to this hook.', array(), 'Admin.Modules.Notification');
} elseif (!$module->isHookableOn($hook->name)) {
$this->errors[] = $this->trans('This module cannot be transplanted to this hook.', array(), 'Admin.Modules.Notification');
} else {
// Adding vars...
if (!$module->registerHook($hook->name, Shop::getContextListShopID())) {
$this->errors[] = $this->trans('An error occurred while transplanting the module to its hook.', array(), 'Admin.Modules.Notification');
} else {
$exceptions = Tools::getValue('exceptions');
$exceptions = (isset($exceptions[0])) ? $exceptions[0] : array();
$exceptions = explode(',', str_replace(' ', '', $exceptions));
$exceptions = array_unique($exceptions);
foreach ($exceptions as $key => $except) {
if (empty($except)) {
unset($exceptions[$key]);
} elseif (!empty($except) && !Validate::isFileName($except)) {
$this->errors[] = $this->trans('No valid value for field exceptions has been defined.', array(), 'Admin.Notifications.Error');
}
}
if (!$this->errors && !$module->registerExceptions($id_hook, $exceptions, Shop::getContextListShopID())) {
$this->errors[] = $this->trans('An error occurred while transplanting the module to its hook.', array(), 'Admin.Notifications.Error');
}
}
if (!$this->errors) {
Tools::redirectAdmin($baseUrl . '&conf=16' . ($this->display_key ? '&show_modules=' . $this->display_key : '') . '&token=' . $this->token);
}
}
} else {
$this->errors[] = $this->trans('You do not have permission to add this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('submitEditGraft')) {
// Edit module from hook
if ($this->access('add')) {
// Getting vars...
$id_module = (int) Tools::getValue('id_module');
$module = Module::getInstanceById($id_module);
$id_hook = (int) Tools::getValue('id_hook');
$new_hook = (int) Tools::getValue('new_hook');
$hook = new Hook($new_hook);
if (!$id_module || !Validate::isLoadedObject($module)) {
$this->errors[] = $this->trans('This module cannot be loaded.', array(), 'Admin.Modules.Notification');
} elseif (!$id_hook || !Validate::isLoadedObject($hook)) {
$this->errors[] = $this->trans('Hook cannot be loaded.', array(), 'Admin.Modules.Notification');
} else {
if ($new_hook !== $id_hook) {
/* Connect module to a newer hook */
if (!$module->registerHook($hook->name, Shop::getContextListShopID())) {
$this->errors[] = $this->trans('An error occurred while transplanting the module to its hook.', array(), 'Admin.Modules.Notification');
}
/* Unregister module from hook & exceptions linked to module */
if (!$module->unregisterHook($id_hook, Shop::getContextListShopID())
|| !$module->unregisterExceptions($id_hook, Shop::getContextListShopID())) {
$this->errors[] = $this->trans('An error occurred while deleting the module from its hook.', array(), 'Admin.Modules.Notification');
}
$id_hook = $new_hook;
}
$exceptions = Tools::getValue('exceptions');
if (is_array($exceptions)) {
foreach ($exceptions as $id => $exception) {
$exception = explode(',', str_replace(' ', '', $exception));
$exception = array_unique($exception);
// Check files name
foreach ($exception as $except) {
if (!empty($except) && !Validate::isFileName($except)) {
$this->errors[] = $this->trans('No valid value for field exceptions has been defined.', array(), 'Admin.Notifications.Error');
}
}
$exceptions[$id] = $exception;
}
// Add files exceptions
if (!$module->editExceptions($id_hook, $exceptions)) {
$this->errors[] = $this->trans('An error occurred while transplanting the module to its hook.', array(), 'Admin.Modules.Notification');
}
if (!$this->errors) {
Tools::redirectAdmin($baseUrl . '&conf=16' . ($this->display_key ? '&show_modules=' . $this->display_key : '') . '&token=' . $this->token);
}
} else {
$exceptions = explode(',', str_replace(' ', '', $exceptions));
$exceptions = array_unique($exceptions);
// Check files name
foreach ($exceptions as $except) {
if (!empty($except) && !Validate::isFileName($except)) {
$this->errors[] = $this->trans('No valid value for field exceptions has been defined.', array(), 'Admin.Notifications.Error');
}
}
// Add files exceptions
if (!$module->editExceptions($id_hook, $exceptions, Shop::getContextListShopID())) {
$this->errors[] = $this->trans('An error occurred while transplanting the module to its hook.', array(), 'Admin.Modules.Notification');
} else {
Tools::redirectAdmin($baseUrl . '&conf=16' . ($this->display_key ? '&show_modules=' . $this->display_key : '') . '&token=' . $this->token);
}
}
}
} else {
$this->errors[] = $this->trans('You do not have permission to add this.', array(), 'Admin.Notifications.Error');
}
} elseif (array_key_exists('deleteGraft', $_GET)) {
// Delete module from hook
if ($this->access('delete')) {
$id_module = (int) Tools::getValue('id_module');
$module = Module::getInstanceById($id_module);
$id_hook = (int) Tools::getValue('id_hook');
$hook = new Hook($id_hook);
if (!Validate::isLoadedObject($module)) {
$this->errors[] = $this->trans('This module cannot be loaded.', array(), 'Admin.Modules.Notification');
} elseif (!$id_hook || !Validate::isLoadedObject($hook)) {
$this->errors[] = $this->trans('Hook cannot be loaded.', array(), 'Admin.Modules.Notification');
} else {
if (!$module->unregisterHook($id_hook, Shop::getContextListShopID())
|| !$module->unregisterExceptions($id_hook, Shop::getContextListShopID())) {
$this->errors[] = $this->trans('An error occurred while deleting the module from its hook.', array(), 'Admin.Modules.Notification');
} else {
Tools::redirectAdmin($baseUrl . '&conf=17' . ($this->display_key ? '&show_modules=' . $this->display_key : '') . '&token=' . $this->token);
}
}
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('unhookform')) {
if (!($unhooks = Tools::getValue('unhooks')) || !is_array($unhooks)) {
$this->errors[] = $this->trans('Please select a module to unhook.', array(), 'Admin.Modules.Notification');
} else {
foreach ($unhooks as $unhook) {
$explode = explode('_', $unhook);
$id_hook = $explode[0];
$id_module = $explode[1];
$module = Module::getInstanceById((int) $id_module);
$hook = new Hook((int) $id_hook);
if (!Validate::isLoadedObject($module)) {
$this->errors[] = $this->trans('This module cannot be loaded.', array(), 'Admin.Modules.Notification');
} elseif (!$id_hook || !Validate::isLoadedObject($hook)) {
$this->errors[] = $this->trans('Hook cannot be loaded.', array(), 'Admin.Modules.Notification');
} else {
if (!$module->unregisterHook((int) $id_hook) || !$module->unregisterExceptions((int) $id_hook)) {
$this->errors[] = $this->trans('An error occurred while deleting the module from its hook.', array(), 'Admin.Modules.Notification');
}
}
}
if (!count($this->errors)) {
Tools::redirectAdmin($baseUrl . '&conf=17' . ($this->display_key ? '&show_modules=' . $this->display_key : '') . '&token=' . $this->token);
}
}
} else {
parent::postProcess();
}
}
public function initContent()
{
$this->addjqueryPlugin('sortable');
if (array_key_exists('addToHook', $_GET) || array_key_exists('editGraft', $_GET) || (Tools::isSubmit('submitAddToHook') && $this->errors)) {
$this->display = 'edit';
$this->content .= $this->renderForm();
} else {
$this->content .= $this->initMain();
}
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
public function initPageHeaderToolbar()
{
$this->page_header_toolbar_btn['save'] = array(
'href' => self::$currentIndex . '&addToHook' . ($this->display_key ? '&show_modules=' . $this->display_key : '') . '&token=' . $this->token,
'desc' => $this->trans('Transplant a module', array(), 'Admin.Design.Feature'),
'icon' => 'process-icon-anchor',
);
return parent::initPageHeaderToolbar();
}
public function initMain()
{
// Init toolbar
$this->initToolbarTitle();
$admin_dir = basename(_PS_ADMIN_DIR_);
$modules = Module::getModulesInstalled();
$assoc_modules_id = array();
foreach ($modules as $module) {
if ($tmp_instance = Module::getInstanceById((int) $module['id_module'])) {
// We want to be able to sort modules by display name
$module_instances[$tmp_instance->displayName] = $tmp_instance;
// But we also want to associate hooks to modules using the modules IDs
$assoc_modules_id[(int) $module['id_module']] = $tmp_instance->displayName;
}
}
ksort($module_instances);
$hooks = Hook::getHooks(false, false);
foreach ($hooks as $key => $hook) {
$hooks[$key]['position'] = Hook::isDisplayHookName($hook['name']);
// Get all modules for this hook or only the filtered module
$hooks[$key]['modules'] = Hook::getModulesFromHook($hook['id_hook'], $this->display_key);
$hooks[$key]['module_count'] = count($hooks[$key]['modules']);
if ($hooks[$key]['module_count']) {
// If modules were found, link to the previously created Module instances
if (is_array($hooks[$key]['modules']) && !empty($hooks[$key]['modules'])) {
foreach ($hooks[$key]['modules'] as $module_key => $module) {
if (isset($assoc_modules_id[$module['id_module']])) {
$hooks[$key]['modules'][$module_key]['instance'] = $module_instances[$assoc_modules_id[$module['id_module']]];
}
}
}
} else {
unset($hooks[$key]);
}
}
$this->addJqueryPlugin('tablednd');
$this->toolbar_btn['save'] = array(
'href' => self::$currentIndex . '&addToHook' . ($this->display_key ? '&show_modules=' . $this->display_key : '') . '&token=' . $this->token,
'desc' => $this->trans('Transplant a module', array(), 'Admin.Design.Feature'),
);
$this->context->smarty->assign(array(
'show_toolbar' => true,
'toolbar_btn' => $this->toolbar_btn,
'title' => $this->toolbar_title,
'toolbar_scroll' => 'false',
'token' => $this->token,
'url_show_modules' => self::$currentIndex . '&token=' . $this->token . '&show_modules=',
'modules' => $module_instances,
'url_show_invisible' => self::$currentIndex . '&token=' . $this->token . '&show_modules=' . (int) Tools::getValue('show_modules') . '&hook_position=',
'display_key' => $this->display_key,
'hooks' => $hooks,
'url_submit' => self::$currentIndex . '&token=' . $this->token,
'can_move' => (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_SHOP) ? false : true,
));
return $this->createTemplate('list_modules.tpl')->fetch();
}
public function renderForm()
{
// Init toolbar
$this->initToolbarTitle();
// toolbar (save, cancel, new, ..)
$this->initToolbar();
$id_module = (int) Tools::getValue('id_module');
$id_hook = (int) Tools::getValue('id_hook');
$show_modules = (int) Tools::getValue('show_modules');
if (Tools::isSubmit('editGraft')) {
// Check auth for this page
if (!$id_module || !$id_hook) {
Tools::redirectAdmin(self::$currentIndex . '&token=' . $this->token);
}
$sql = 'SELECT id_module
FROM ' . _DB_PREFIX_ . 'hook_module
WHERE id_module = ' . $id_module . '
AND id_hook = ' . $id_hook . '
AND id_shop IN(' . implode(', ', Shop::getContextListShopID()) . ')';
if (!Db::getInstance()->getValue($sql)) {
Tools::redirectAdmin(self::$currentIndex . '&token=' . $this->token);
}
$sl_module = Module::getInstanceById($id_module);
$excepts_list = $sl_module->getExceptions($id_hook, true);
$excepts_diff = false;
$excepts = '';
if ($excepts_list) {
$first = current($excepts_list);
foreach ($excepts_list as $k => $v) {
if (array_diff($v, $first) || array_diff($first, $v)) {
$excepts_diff = true;
}
}
if (!$excepts_diff) {
$excepts = implode(', ', $first);
}
}
} else {
$excepts_diff = false;
$excepts_list = Tools::getValue('exceptions', array(array()));
}
$modules = Module::getModulesInstalled(0);
$instances = array();
foreach ($modules as $module) {
if ($tmp_instance = Module::getInstanceById($module['id_module'])) {
$instances[$tmp_instance->displayName] = $tmp_instance;
}
}
ksort($instances);
$modules = $instances;
$hooks = array();
if ($show_modules || (Tools::getValue('id_hook') > 0)) {
$module_instance = Module::getInstanceById((int) Tools::getValue('id_module', $show_modules));
$hooks = $module_instance->getPossibleHooksList();
}
$exception_list_diff = array();
foreach ($excepts_list as $shop_id => $file_list) {
$exception_list_diff[] = $this->displayModuleExceptionList($file_list, $shop_id);
}
$tpl = $this->createTemplate('form.tpl');
$tpl->assign(array(
'url_submit' => self::$currentIndex . '&token=' . $this->token,
'edit_graft' => Tools::isSubmit('editGraft'),
'id_module' => (int) Tools::getValue('id_module'),
'id_hook' => (int) Tools::getValue('id_hook'),
'show_modules' => $show_modules,
'hooks' => $hooks,
'exception_list' => $this->displayModuleExceptionList(array_shift($excepts_list), 0),
'exception_list_diff' => $exception_list_diff,
'except_diff' => isset($excepts_diff) ? $excepts_diff : null,
'display_key' => $this->display_key,
'modules' => $modules,
'show_toolbar' => true,
'toolbar_btn' => $this->toolbar_btn,
'toolbar_scroll' => $this->toolbar_scroll,
'title' => $this->toolbar_title,
'table' => 'hook_module',
));
return $tpl->fetch();
}
public function displayModuleExceptionList($file_list, $shop_id)
{
if (!is_array($file_list)) {
$file_list = ($file_list) ? array($file_list) : array();
}
$content = '<p><input type="text" name="exceptions[' . $shop_id . ']" value="' . implode(', ', $file_list) . '" id="em_text_' . $shop_id . '" placeholder="' . $this->trans('E.g. address, addresses, attachment', array(), 'Admin.Design.Help') . '"/></p>';
if ($shop_id) {
$shop = new Shop($shop_id);
$content .= ' (' . $shop->name . ')';
}
$content .= '<p>
<select size="25" id="em_list_' . $shop_id . '" multiple="multiple">
<option disabled="disabled">'
. $this->trans('___________ CUSTOM ___________', array(), 'Admin.Design.Feature')
. '</option>';
/** @todo do something better with controllers */
$controllers = Dispatcher::getControllers(_PS_FRONT_CONTROLLER_DIR_);
ksort($controllers);
foreach ($file_list as $k => $v) {
if (!array_key_exists($v, $controllers)) {
$content .= '<option value="' . $v . '">' . $v . '</option>';
}
}
$content .= '<option disabled="disabled">' . $this->trans('____________ CORE ____________', array(), 'Admin.Design.Feature') . '</option>';
foreach ($controllers as $k => $v) {
$content .= '<option value="' . $k . '">' . $k . '</option>';
}
$modules_controllers_type = array('admin' => $this->trans('Admin modules controller', array(), 'Admin.Design.Feature'), 'front' => $this->trans('Front modules controller', array(), 'Admin.Design.Feature'));
foreach ($modules_controllers_type as $type => $label) {
$content .= '<option disabled="disabled">____________ ' . $label . ' ____________</option>';
$all_modules_controllers = Dispatcher::getModuleControllers($type);
foreach ($all_modules_controllers as $module => $modules_controllers) {
foreach ($modules_controllers as $cont) {
$content .= '<option value="module-' . $module . '-' . $cont . '">module-' . $module . '-' . $cont . '</option>';
}
}
}
$content .= '</select>
</p>';
return $content;
}
public function ajaxProcessUpdatePositions()
{
if ($this->access('edit')) {
$id_module = (int) (Tools::getValue('id_module'));
$id_hook = (int) (Tools::getValue('id_hook'));
$way = (int) (Tools::getValue('way'));
$positions = Tools::getValue((string) $id_hook);
$position = (is_array($positions)) ? array_search($id_hook . '_' . $id_module, $positions) : null;
$module = Module::getInstanceById($id_module);
if (Validate::isLoadedObject($module)) {
if ($module->updatePosition($id_hook, $way, $position)) {
die(true);
} else {
die('{"hasError" : true, "errors" : "Cannot update module position."}');
}
} else {
die('{"hasError" : true, "errors" : "This module cannot be loaded."}');
}
}
}
public function ajaxProcessGetHookableList()
{
if ($this->access('view')) {
/* PrestaShop demo mode */
if (_PS_MODE_DEMO_) {
die('{"hasError" : true, "errors" : ["Live Edit: This functionality has been disabled."]}');
}
if (!count(Tools::getValue('hooks_list'))) {
die('{"hasError" : true, "errors" : ["Live Edit: no module on this page."]}');
}
$modules_list = Tools::getValue('modules_list');
$hooks_list = Tools::getValue('hooks_list');
$hookableList = array();
foreach ($modules_list as $module) {
$module = trim($module);
if (!$module) {
continue;
}
if (!Validate::isModuleName($module)) {
die('{"hasError" : true, "errors" : ["Live Edit: module is invalid."]}');
}
$moduleInstance = Module::getInstanceByName($module);
foreach ($hooks_list as $hook_name) {
$hook_name = trim($hook_name);
if (!$hook_name) {
continue;
}
if (!array_key_exists($hook_name, $hookableList)) {
$hookableList[$hook_name] = array();
}
if ($moduleInstance->isHookableOn($hook_name)) {
$hookableList[$hook_name][] = str_replace('_', '-', $module);
}
}
}
$hookableList['hasError'] = false;
die(json_encode($hookableList));
}
}
public function ajaxProcessGetHookableModuleList()
{
if ($this->access('view')) {
/* PrestaShop demo mode */
if (_PS_MODE_DEMO_) {
die('{"hasError" : true, "errors" : ["Live Edit: This functionality has been disabled."]}');
}
/* PrestaShop demo mode*/
$hook_name = Tools::getValue('hook');
$hookableModulesList = array();
$modules = Db::getInstance()->executeS('SELECT id_module, name FROM `' . _DB_PREFIX_ . 'module` ');
foreach ($modules as $module) {
if (!Validate::isModuleName($module['name'])) {
continue;
}
if (file_exists(_PS_MODULE_DIR_ . $module['name'] . '/' . $module['name'] . '.php')) {
include_once _PS_MODULE_DIR_ . $module['name'] . '/' . $module['name'] . '.php';
/** @var Module $mod */
$mod = new $module['name']();
if ($mod->isHookableOn($hook_name)) {
$hookableModulesList[] = array('id' => (int) $mod->id, 'name' => $mod->displayName, 'display' => Hook::exec($hook_name, array(), (int) $mod->id));
}
}
}
die(json_encode($hookableModulesList));
}
}
public function ajaxProcessSaveHook()
{
if ($this->access('edit')) {
/* PrestaShop demo mode */
if (_PS_MODE_DEMO_) {
die('{"hasError" : true, "errors" : ["Live Edit: This functionality has been disabled."]}');
}
$hooks_list = explode(',', Tools::getValue('hooks_list'));
$id_shop = (int) Tools::getValue('id_shop');
if (!$id_shop) {
$id_shop = Context::getContext()->shop->id;
}
$res = true;
$hookableList = array();
// $_POST['hook'] is an array of id_module
$hooks_list = Tools::getValue('hook');
foreach ($hooks_list as $id_hook => $modules) {
// 1st, drop all previous hooked modules
$sql = 'DELETE FROM `' . _DB_PREFIX_ . 'hook_module` WHERE `id_hook` = ' . (int) $id_hook . ' AND id_shop = ' . (int) $id_shop;
$res &= Db::getInstance()->execute($sql);
$i = 1;
$value = '';
$ids = array();
// then prepare sql query to rehook all chosen modules(id_module, id_shop, id_hook, position)
// position is i (autoincremented)
if (is_array($modules) && count($modules)) {
foreach ($modules as $id_module) {
if ($id_module && !in_array($id_module, $ids)) {
$ids[] = (int) $id_module;
$value .= '(' . (int) $id_module . ', ' . (int) $id_shop . ', ' . (int) $id_hook . ', ' . (int) $i . '),';
}
++$i;
}
if ($value) {
$value = rtrim($value, ',');
$res &= Db::getInstance()->execute('INSERT INTO `' . _DB_PREFIX_ . 'hook_module` (id_module, id_shop, id_hook, position) VALUES ' . $value);
}
}
}
if ($res) {
$hasError = true;
} else {
$hasError = false;
}
die('{"hasError" : false, "errors" : ""}');
}
}
/**
* Return a json array containing the possible hooks for a module.
*/
public function ajaxProcessGetPossibleHookingListForModule()
{
$module_id = (int) Tools::getValue('module_id');
if ($module_id == 0) {
die('{"hasError" : true, "errors" : ["Wrong module ID."]}');
}
$module_instance = Module::getInstanceById($module_id);
die(json_encode($module_instance->getPossibleHooksList()));
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminNotFoundControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
parent::__construct();
}
public function checkAccess()
{
return true;
}
public function viewAccess($disable = false)
{
return true;
}
public function initContent()
{
$this->errors[] = $this->trans('Page not found', array(), 'Admin.Notifications.Error');
$tpl_vars['controller'] = Tools::getValue('controllerUri', Tools::getValue('controller'));
$this->context->smarty->assign($tpl_vars);
parent::initContent();
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property OrderMessage $object
*/
class AdminOrderMessageControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'order_message';
$this->className = 'OrderMessage';
$this->lang = true;
$this->addRowAction('edit');
$this->addRowAction('delete');
parent::__construct();
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
parent::__construct();
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'id_order_message' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
),
'message' => array(
'title' => $this->trans('Message', array(), 'Admin.Global'),
'maxlength' => 300,
),
);
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Order messages', array(), 'Admin.Orderscustomers.Feature'),
'icon' => 'icon-mail',
),
'input' => array(
array(
'type' => 'text',
'lang' => true,
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'size' => 53,
'required' => true,
),
array(
'type' => 'textarea',
'lang' => true,
'label' => $this->trans('Message', array(), 'Admin.Global'),
'name' => 'message',
'required' => true,
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_order_message'] = array(
'href' => self::$currentIndex . '&addorder_message&token=' . $this->token,
'desc' => $this->trans('Add new order message', array(), 'Admin.Orderscustomers.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,180 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property OrderInvoice $object
*/
class AdminOutstandingControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'order_invoice';
$this->className = 'OrderInvoice';
$this->addRowAction('view');
parent::__construct();
$this->_select = '`id_order_invoice` AS `id_invoice`,
`id_order_invoice` AS `outstanding`,
CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
c.`outstanding_allow_amount`,
r.`color`,
c.`company`,
rl.`name` AS `risk`';
$this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON (o.`id_order` = a.`id_order`)
LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = o.`id_customer`)
LEFT JOIN `' . _DB_PREFIX_ . 'risk` r ON (r.`id_risk` = c.`id_risk`)
LEFT JOIN `' . _DB_PREFIX_ . 'risk_lang` rl ON (r.`id_risk` = rl.`id_risk` AND rl.`id_lang` = ' . (int) $this->context->language->id . ')';
$this->_where = 'AND number > 0';
$this->_use_found_rows = false;
$risks = array();
foreach (Risk::getRisks() as $risk) {
/* @var Risk $risk */
$risks[$risk->id] = $risk->name;
}
$this->fields_list = array(
'number' => array(
'title' => $this->trans('Invoice', array(), 'Admin.Global'),
),
'date_add' => array(
'title' => $this->trans('Date', array(), 'Admin.Global'),
'type' => 'date',
'align' => 'right',
'filter_key' => 'a!date_add',
),
'customer' => array(
'title' => $this->trans('Customer', array(), 'Admin.Global'),
'filter_key' => 'customer',
'tmpTableFilter' => true,
),
'company' => array(
'title' => $this->trans('Company', array(), 'Admin.Global'),
'align' => 'center',
),
'risk' => array(
'title' => $this->trans('Risk', array(), 'Admin.Orderscustomers.Feature'),
'align' => 'center',
'orderby' => false,
'type' => 'select',
'color' => 'color',
'list' => $risks,
'filter_key' => 'r!id_risk',
'filter_type' => 'int',
),
'outstanding_allow_amount' => array(
'title' => $this->trans('Outstanding Allowance', array(), 'Admin.Orderscustomers.Feature'),
'align' => 'center',
'prefix' => '<b>',
'suffix' => '</b>',
'type' => 'price',
),
'outstanding' => array(
'title' => $this->trans('Current Outstanding', array(), 'Admin.Orderscustomers.Feature'),
'align' => 'center',
'callback' => 'printOutstandingCalculation',
'orderby' => false,
'search' => false,
),
'id_invoice' => array(
'title' => $this->trans('Invoice', array(), 'Admin.Global'),
'align' => 'center',
'callback' => 'printPDFIcons',
'orderby' => false,
'search' => false,
),
);
}
/**
* Toolbar initialisation.
*
* @return bool Force true (Hide New button)
*/
public function initToolbar()
{
return true;
}
/**
* Column callback for print PDF incon.
*
* @param $id_invoice integer Invoice ID
* @param $tr array Row data
*
* @return string HTML content
*/
public function printPDFIcons($id_invoice, $tr)
{
$this->context->smarty->assign(array(
'id_invoice' => $id_invoice,
));
return $this->createTemplate('_print_pdf_icon.tpl')->fetch();
}
public function printOutstandingCalculation($id_invoice, $tr)
{
$order_invoice = new OrderInvoice($id_invoice);
if (!Validate::isLoadedObject($order_invoice)) {
throw new PrestaShopException('object OrderInvoice cannot be loaded');
}
$order = new Order($order_invoice->id_order);
if (!Validate::isLoadedObject($order)) {
throw new PrestaShopException('object Order cannot be loaded');
}
$customer = new Customer((int) $order->id_customer);
if (!Validate::isLoadedObject($order_invoice)) {
throw new PrestaShopException('object Customer cannot be loaded');
}
return '<b>' . Tools::displayPrice($customer->getOutstanding(), Context::getContext()->currency) . '</b>';
}
/**
* View render.
*
* @throws PrestaShopException Invalid objects
*/
public function renderView()
{
$order_invoice = new OrderInvoice((int) Tools::getValue('id_order_invoice'));
if (!Validate::isLoadedObject($order_invoice)) {
throw new PrestaShopException('object OrderInvoice cannot be loaded');
}
$order = new Order($order_invoice->id_order);
if (!Validate::isLoadedObject($order)) {
throw new PrestaShopException('object Order cannot be loaded');
}
$link = $this->context->link->getAdminLink('AdminOrders');
$link .= '&vieworder&id_order=' . $order->id;
$this->redirect_after = $link;
$this->redirect();
}
}

View File

@@ -0,0 +1,687 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminPatternsControllerCore extends AdminController
{
public $name = 'patterns';
public function __construct()
{
$this->bootstrap = true;
$this->show_toolbar = false;
$this->context = Context::getContext();
parent::__construct();
}
public function viewAccess($disable = false)
{
return true;
}
public function renderForm()
{
$this->fields_value = array(
'type_text' => 'with value',
'type_text_readonly' => 'with value that you can\'t edit',
'type_switch' => 1,
'days' => 17,
'months' => 3,
'years' => 2014,
'groupBox_1' => false,
'groupBox_2' => true,
'groupBox_3' => false,
'groupBox_4' => true,
'groupBox_5' => true,
'groupBox_6' => false,
'type_color' => '#8BC954',
'tab_note' => 'The tabs are always pushed to the top of the form, wherever they are in the fields_form array.',
'type_free' => '<p class="form-control-static">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lacinia in enim iaculis malesuada. Quisque congue fermentum leo et porta. Pellentesque a quam dui. Pellentesque sed augue id sem aliquet faucibus eu vel odio. Nullam non libero volutpat, pulvinar turpis non, gravida mauris. Nullam tincidunt id est at euismod. Quisque euismod quam in pellentesque mollis. Nulla suscipit porttitor massa, nec eleifend risus egestas in. Aenean luctus porttitor tempus. Morbi dolor leo, dictum id interdum vel, semper ac est. Maecenas justo augue, accumsan in velit nec, consectetur fringilla orci. Nunc ut ante erat. Curabitur dolor augue, eleifend a luctus non, aliquet a mi. Curabitur ultricies lectus in rhoncus sodales. Maecenas quis dictum erat. Suspendisse blandit lacus sed felis facilisis, in interdum quam congue.<p>',
);
$this->fields_form = array(
'legend' => array(
'title' => 'patterns of helper form.tpl',
'icon' => 'icon-edit',
),
'tabs' => array(
'small' => 'Small Inputs',
'large' => 'Large Inputs',
),
'description' => 'You can use image instead of icon for the title.',
'input' => array(
array(
'type' => 'text',
'label' => 'simple input text',
'name' => 'type_text',
),
array(
'type' => 'text',
'label' => 'input text with desc',
'name' => 'type_text_desc',
'desc' => 'desc input text',
),
array(
'type' => 'text',
'label' => 'required input text',
'name' => 'type_text_required',
'required' => true,
),
array(
'type' => 'text',
'label' => 'input text with hint',
'name' => 'type_text_hint',
'hint' => 'hint input text',
),
array(
'type' => 'text',
'label' => 'input text with prefix',
'name' => 'type_text_prefix',
'prefix' => 'prefix',
),
array(
'type' => 'text',
'label' => 'input text with suffix',
'name' => 'type_text_suffix',
'suffix' => 'suffix',
),
array(
'type' => 'text',
'label' => 'input text with placeholder',
'name' => 'type_text_placeholder',
'placeholder' => 'placeholder',
),
array(
'type' => 'text',
'label' => 'input text with character counter',
'name' => 'type_text_maxchar',
'maxchar' => 30,
),
array(
'type' => 'text',
'lang' => true,
'label' => 'input text multilang',
'name' => 'type_text_multilang',
),
array(
'type' => 'text',
'label' => 'input readonly',
'readonly' => true,
'name' => 'type_text_readonly',
),
array(
'type' => 'text',
'label' => 'input fixed-width-xs',
'name' => 'type_text_xs',
'class' => 'input fixed-width-xs',
),
array(
'type' => 'text',
'label' => 'input fixed-width-sm',
'name' => 'type_text_sm',
'class' => 'input fixed-width-sm',
),
array(
'type' => 'text',
'label' => 'input fixed-width-md',
'name' => 'type_text_md',
'class' => 'input fixed-width-md',
),
array(
'type' => 'text',
'label' => 'input fixed-width-lg',
'name' => 'type_text_lg',
'class' => 'input fixed-width-lg',
),
array(
'type' => 'text',
'label' => 'input fixed-width-xl',
'name' => 'type_text_xl',
'class' => 'input fixed-width-xl',
),
array(
'type' => 'text',
'label' => 'input fixed-width-xxl',
'name' => 'type_text_xxl',
'class' => 'fixed-width-xxl',
),
array(
'type' => 'text',
'label' => 'input fixed-width-sm',
'name' => 'type_text_sm',
'class' => 'input fixed-width-sm',
'tab' => 'small',
),
array(
'type' => 'text',
'label' => 'input fixed-width-md',
'name' => 'type_text_md',
'class' => 'input fixed-width-md',
'tab' => 'small',
),
array(
'type' => 'text',
'label' => 'input fixed-width-lg',
'name' => 'type_text_lg',
'class' => 'input fixed-width-lg',
'tab' => 'large',
),
array(
'type' => 'text',
'label' => 'input fixed-width-xl',
'name' => 'type_text_xl',
'class' => 'input fixed-width-xl',
'tab' => 'large',
),
array(
'type' => 'text',
'label' => 'input fixed-width-xxl',
'name' => 'type_text_xxl',
'class' => 'fixed-width-xxl',
'tab' => 'large',
),
array(
'type' => 'free',
'label' => 'About tabs',
'name' => 'tab_note',
'tab' => 'small',
),
array(
'type' => 'text',
'label' => 'input fixed-width-md with prefix',
'name' => 'type_text_md',
'class' => 'input fixed-width-md',
'prefix' => 'prefix',
),
array(
'type' => 'text',
'label' => 'input fixed-width-md with sufix',
'name' => 'type_text_md',
'class' => 'input fixed-width-md',
'suffix' => 'suffix',
),
array(
'type' => 'tags',
'label' => 'input tags',
'name' => 'type_text_tags',
),
array(
'type' => 'textbutton',
'label' => 'input with button',
'name' => 'type_textbutton',
'button' => array(
'label' => 'do something',
'attributes' => array(
'onclick' => 'alert(\'something done\');',
),
),
),
array(
'type' => 'select',
'label' => 'select',
'name' => 'type_select',
'options' => array(
'query' => Zone::getZones(),
'id' => 'id_zone',
'name' => 'name',
),
),
array(
'type' => 'select',
'label' => 'select with chosen',
'name' => 'type_select_chosen',
'class' => 'chosen',
'options' => array(
'query' => Country::getCountries((int) Context::getContext()->cookie->id_lang),
'id' => 'id_zone',
'name' => 'name',
),
),
array(
'type' => 'select',
'label' => 'select multiple with chosen',
'name' => 'type_select_multiple_chosen',
'class' => 'chosen',
'multiple' => true,
'options' => array(
'query' => Country::getCountries((int) Context::getContext()->cookie->id_lang),
'id' => 'id_zone',
'name' => 'name',
),
),
array(
'type' => 'radio',
'label' => 'radios',
'name' => 'type_radio',
'values' => array(
array(
'id' => 'type_male',
'value' => 0,
'label' => 'first',
),
array(
'id' => 'type_female',
'value' => 1,
'label' => 'second',
),
array(
'id' => 'type_neutral',
'value' => 2,
'label' => 'third',
),
),
),
array(
'type' => 'checkbox',
'label' => 'checkbox',
'name' => 'type_checkbox',
'values' => array(
'query' => Zone::getZones(),
'id' => 'id_zone',
'name' => 'name',
),
),
array(
'type' => 'switch',
'label' => 'switch',
'name' => 'type_switch',
'values' => array(
array(
'id' => 'type_switch_on',
'value' => 1,
),
array(
'id' => 'type_switch_off',
'value' => 0,
),
),
),
array(
'type' => 'switch',
'label' => 'switch disabled',
'name' => 'type_switch_disabled',
'disabled' => 'true',
'values' => array(
array(
'id' => 'type_switch_disabled_on',
'value' => 1,
),
array(
'id' => 'type_switch_disabled_off',
'value' => 0,
),
),
),
array(
'type' => 'textarea',
'label' => 'text area (with autoresize)',
'name' => 'type_textarea',
),
array(
'type' => 'textarea',
'label' => 'text area with rich text editor',
'name' => 'type_textarea_rte',
'autoload_rte' => true,
),
array(
'type' => 'password',
'label' => 'input password',
'name' => 'type_password',
),
array(
'type' => 'birthday',
'label' => 'input birthday',
'name' => 'type_birthday',
'options' => array(
'days' => Tools::dateDays(),
'months' => Tools::dateMonths(),
'years' => Tools::dateYears(),
),
),
array(
'type' => 'group',
'label' => 'group',
'name' => 'type_group',
'values' => Group::getGroups(Context::getContext()->language->id),
),
array(
'type' => 'categories',
'label' => 'tree categories',
'name' => 'type_categories',
'tree' => array(
'root_category' => 1,
'id' => 'id_category',
'name' => 'name_category',
'selected_categories' => array(3),
),
),
array(
'type' => 'file',
'label' => 'input file',
'name' => 'type_file',
),
array(
'type' => 'color',
'label' => 'input color',
'name' => 'type_color',
),
array(
'type' => 'date',
'label' => 'input date',
'name' => 'type_date',
),
array(
'type' => 'datetime',
'label' => 'input date and time',
'name' => 'type_datetime',
),
array(
'type' => 'html',
'name' => 'html_data',
'html_content' => '<hr><strong>html:</strong> for writing free html like this <span class="label label-danger">i\'m a label</span> <span class="badge badge-info">i\'m a badge</span> <button type="button" class="btn btn-default">i\'m a button</button><hr>',
),
array(
'type' => 'free',
'label' => 'input free',
'name' => 'type_free',
),
//...
),
'submit' => array(
'title' => 'Save',
),
'buttons' => array(),
);
return parent::renderForm();
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addjQueryPlugin('tagify', null, false);
}
public function renderList()
{
$return = '';
$return .= $this->renderListSimpleHeader();
$return .= $this->renderListSmallColumns();
$return .= $this->renderListWithParentClass();
return $return;
}
public function renderListSimpleHeader()
{
$content = array(
array(
'id_carrier' => 5,
'name' => 'Lorem ipsum dolor, sit amet, consectetur adipiscing elit. Nunc lacinia in enim iaculis malesuada. Quisque congue ferm',
'type_name' => 'Azerty',
'active' => 1,
),
array(
'id_carrier' => 6,
'name' => 'Lorem ipsum dolor sit amet, consectetur lacinia in enim iaculis malesuada. Quisque congue ferm',
'type_name' => 'Qwerty',
'active' => 1,
),
array(
'id_carrier' => 9,
'name' => "Lorem ipsum dolor sit amet: \ / : * ? \" < > |",
'type_name' => 'Azerty',
'active' => 0,
),
array(
'id_carrier' => 3,
'name' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc lacinia in enim iaculis malesuada. Quisque congue ferm',
'type_name' => 'Azerty',
'active' => 1,
),
);
$fields_list = array(
'id_carrier' => array(
'title' => 'ID',
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => 'Name',
),
'type_name' => array(
'title' => 'Type',
'type' => 'text',
),
'active' => array(
'title' => 'Status',
'active' => 'status',
'type' => 'bool',
),
);
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->simple_header = true;
$helper->actions = array('edit', 'delete');
$helper->show_toolbar = false;
$helper->module = $this;
$helper->listTotal = count($content);
$helper->identifier = 'id_carrier';
$helper->title = 'This list use a simple Header with no toolbar';
$helper->table = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
return $helper->generateList($content, $fields_list);
}
public function renderListSmallColumns()
{
$content = array(
array(
'id' => 5,
'badge_success' => 153,
'badge_warning' => 6,
'badge_danger' => -2,
'text' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
'color_value' => 'red',
'blue' => 'Content in custom color in blue field',
'activeVisu_field' => 1,
'editable_text' => 'PrestaShop',
),
array(
'id' => 1,
'badge_success' => 15561533,
'badge_warning' => 0,
'badge_danger' => 0,
'text' => 'Lorem ip, consectetur adipiscing elit.',
'color_value' => 'blue',
'blue' => 'Content in custom color in blue field',
'activeVisu_field' => 0,
'editable_text' => 'PrestaShop',
),
array(
'id' => 2,
'badge_success' => 0,
'badge_warning' => 65,
'badge_danger' => -200,
'text' => 'WITH VERY LONG TEXT: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. ',
'color_value' => 'yellow',
'blue' => 'Content in custom color in blue field',
'activeVisu_field' => 1,
'editable_text' => 'PrestaShop Lorem ipsum dolor sit amet, consectetur adipiscing elit. ',
),
array(
'id' => 9,
'badge_success' => 3,
'badge_warning' => 2,
'badge_danger' => 1,
'text' => "WITH HTML: <br> <strong>strong</strong> <span style='background: black;'>span content</span>",
'color_value' => '#CCCC99',
'blue' => 'Content in custom color in blue field',
'activeVisu_field' => 1,
'editable_text' => 'PrestaShop',
),
);
$fields_list = array(
'id' => array(
'title' => 'ID',
'align' => 'center',
'class' => 'fixed-width-xs',
),
'badge_success' => array(
'title' => 'Success',
'badge_success' => true,
),
'badge_warning' => array(
'title' => 'Warning',
'badge_warning' => true,
),
'badge_danger' => array(
'title' => 'Danger',
'badge_danger' => true,
),
'text' => array(
'title' => 'Content with prefix',
'prefix' => 'This is a prefix: ',
'class' => 'class-prefix',
),
'blue' => array(
'title' => 'Content with no link',
'color' => 'color_value',
'class' => 'class-custom-nolink',
),
'activeVisu_field' => array(
'title' => 'ActiveVisu',
'activeVisu' => true,
),
'editable_text' => array(
'title' => 'edit this !',
'type' => 'editable',
'class' => 'another-custom_class',
),
);
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->simple_header = false;
$helper->actions = array();
$helper->show_toolbar = false;
$helper->module = $this;
$helper->listTotal = count($content);
$helper->identifier = 'id';
$helper->title = 'This list shows a lot of small columns';
$helper->table = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
return $helper->generateList($content, $fields_list);
}
public function renderListModel()
{
$content = array();
$fields_list = array();
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->simple_header = true;
$helper->actions = null;
$helper->show_toolbar = false;
$helper->module = $this;
$helper->listTotal = count($content);
$helper->identifier = 'id_product_comment';
$helper->title = 'Moderate Comments';
$helper->table = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
return $helper->generateList($content, $fields_list);
}
public function renderListWithParentClass()
{
$this->bulk_actions = array(
'delete' => array(
'text' => 'Delete selected',
'confirm' => 'Delete selected items?',
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'id_carrier' => array(
'title' => 'ID',
'align' => 'center',
'class' => 'fixed-width-xs',
),
'image' => array(
'title' => 'Logo',
'align' => 'center',
'image' => 's',
'class' => 'fixed-width-xs',
'orderby' => false,
'search' => false,
),
'name' => array(
'title' => 'Name',
),
);
return parent::renderList();
}
public function renderOptions()
{
$this->fields_options = array(
'general' => array(
'title' => 'General',
'icon' => 'icon-cogs',
'fields' => array(),
'submit' => array('title' => 'Save'),
),
);
return parent::renderOptions();
}
public function initContent()
{
$this->display = 'view';
$this->page_header_toolbar_title = $this->toolbar_title = 'Patterns design sample';
parent::initContent();
$this->content .= $this->renderForm();
$this->content .= $this->renderList();
$this->content .= $this->renderOptions();
$this->context->smarty->assign(array('content' => $this->content));
}
}

View File

@@ -0,0 +1,211 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminPdfControllerCore extends AdminController
{
public function postProcess()
{
parent::postProcess();
// We want to be sure that displaying PDF is the last thing this controller will do
exit;
}
public function initProcess()
{
parent::initProcess();
$this->checkCacheFolder();
$access = Profile::getProfileAccess($this->context->employee->id_profile, (int) Tab::getIdFromClassName('AdminOrders'));
if ($access['view'] === '1' && ($action = Tools::getValue('submitAction'))) {
$this->action = $action;
} else {
$this->errors[] = $this->trans('You do not have permission to view this.', array(), 'Admin.Notifications.Error');
}
}
public function checkCacheFolder()
{
if (!is_dir(_PS_CACHE_DIR_ . 'tcpdf/')) {
mkdir(_PS_CACHE_DIR_ . 'tcpdf/');
}
}
public function processGenerateInvoicePdf()
{
if (Tools::isSubmit('id_order')) {
$this->generateInvoicePDFByIdOrder(Tools::getValue('id_order'));
} elseif (Tools::isSubmit('id_order_invoice')) {
$this->generateInvoicePDFByIdOrderInvoice(Tools::getValue('id_order_invoice'));
} else {
die($this->trans('The order ID -- or the invoice order ID -- is missing.', array(), 'Admin.Orderscustomers.Notification'));
}
}
public function processGenerateOrderSlipPDF()
{
$order_slip = new OrderSlip((int) Tools::getValue('id_order_slip'));
$order = new Order((int) $order_slip->id_order);
if (!Validate::isLoadedObject($order)) {
die($this->trans('The order cannot be found within your database.', array(), 'Admin.Orderscustomers.Notification'));
}
$order->products = OrderSlip::getOrdersSlipProducts($order_slip->id, $order);
$this->generatePDF($order_slip, PDF::TEMPLATE_ORDER_SLIP);
}
public function processGenerateDeliverySlipPDF()
{
if (Tools::isSubmit('id_order')) {
$this->generateDeliverySlipPDFByIdOrder((int) Tools::getValue('id_order'));
} elseif (Tools::isSubmit('id_order_invoice')) {
$this->generateDeliverySlipPDFByIdOrderInvoice((int) Tools::getValue('id_order_invoice'));
} elseif (Tools::isSubmit('id_delivery')) {
$order = Order::getByDelivery((int) Tools::getValue('id_delivery'));
$this->generateDeliverySlipPDFByIdOrder((int) $order->id);
} else {
die($this->trans('The order ID -- or the invoice order ID -- is missing.', array(), 'Admin.Orderscustomers.Notification'));
}
}
public function processGenerateInvoicesPDF()
{
$order_invoice_collection = OrderInvoice::getByDateInterval(Tools::getValue('date_from'), Tools::getValue('date_to'));
if (!count($order_invoice_collection)) {
die($this->trans('No invoice was found.', array(), 'Admin.Orderscustomers.Notification'));
}
$this->generatePDF($order_invoice_collection, PDF::TEMPLATE_INVOICE);
}
public function processGenerateInvoicesPDF2()
{
$order_invoice_collection = array();
foreach (explode('-', Tools::getValue('id_order_state')) as $id_order_state) {
if (is_array($order_invoices = OrderInvoice::getByStatus((int) $id_order_state))) {
$order_invoice_collection = array_merge($order_invoices, $order_invoice_collection);
}
}
if (!count($order_invoice_collection)) {
die($this->trans('No invoice was found.', array(), 'Admin.Orderscustomers.Notification'));
}
$this->generatePDF($order_invoice_collection, PDF::TEMPLATE_INVOICE);
}
public function processGenerateOrderSlipsPDF()
{
$id_order_slips_list = OrderSlip::getSlipsIdByDate(Tools::getValue('date_from'), Tools::getValue('date_to'));
if (!count($id_order_slips_list)) {
die($this->trans('No order slips were found.', array(), 'Admin.Orderscustomers.Notification'));
}
$order_slips = array();
foreach ($id_order_slips_list as $id_order_slips) {
$order_slips[] = new OrderSlip((int) $id_order_slips);
}
$this->generatePDF($order_slips, PDF::TEMPLATE_ORDER_SLIP);
}
public function processGenerateDeliverySlipsPDF()
{
$order_invoice_collection = OrderInvoice::getByDeliveryDateInterval(Tools::getValue('date_from'), Tools::getValue('date_to'));
if (!count($order_invoice_collection)) {
die($this->trans('No invoice was found.', array(), 'Admin.Orderscustomers.Notification'));
}
$this->generatePDF($order_invoice_collection, PDF::TEMPLATE_DELIVERY_SLIP);
}
public function processGenerateSupplyOrderFormPDF()
{
if (!Tools::isSubmit('id_supply_order')) {
die($this->trans('The supply order ID is missing.', array(), 'Admin.Orderscustomers.Notification'));
}
$id_supply_order = (int) Tools::getValue('id_supply_order');
$supply_order = new SupplyOrder($id_supply_order);
if (!Validate::isLoadedObject($supply_order)) {
die($this->trans('The supply order cannot be found within your database.', array(), 'Admin.Orderscustomers.Notification'));
}
$this->generatePDF($supply_order, PDF::TEMPLATE_SUPPLY_ORDER_FORM);
}
public function generateDeliverySlipPDFByIdOrder($id_order)
{
$order = new Order((int) $id_order);
if (!Validate::isLoadedObject($order)) {
throw new PrestaShopException('Can\'t load Order object');
}
$order_invoice_collection = $order->getInvoicesCollection();
$this->generatePDF($order_invoice_collection, PDF::TEMPLATE_DELIVERY_SLIP);
}
public function generateDeliverySlipPDFByIdOrderInvoice($id_order_invoice)
{
$order_invoice = new OrderInvoice((int) $id_order_invoice);
if (!Validate::isLoadedObject($order_invoice)) {
throw new PrestaShopException('Can\'t load Order Invoice object');
}
$this->generatePDF($order_invoice, PDF::TEMPLATE_DELIVERY_SLIP);
}
public function generateInvoicePDFByIdOrder($id_order)
{
$order = new Order((int) $id_order);
if (!Validate::isLoadedObject($order)) {
die($this->trans('The order cannot be found within your database.', array(), 'Admin.Orderscustomers.Notification'));
}
$order_invoice_list = $order->getInvoicesCollection();
Hook::exec('actionPDFInvoiceRender', array('order_invoice_list' => $order_invoice_list));
$this->generatePDF($order_invoice_list, PDF::TEMPLATE_INVOICE);
}
public function generateInvoicePDFByIdOrderInvoice($id_order_invoice)
{
$order_invoice = new OrderInvoice((int) $id_order_invoice);
if (!Validate::isLoadedObject($order_invoice)) {
die($this->trans('The order invoice cannot be found within your database.', array(), 'Admin.Orderscustomers.Notification'));
}
Hook::exec('actionPDFInvoiceRender', array('order_invoice_list' => array($order_invoice)));
$this->generatePDF($order_invoice, PDF::TEMPLATE_INVOICE);
}
public function generatePDF($object, $template)
{
$pdf = new PDF($object, $template, Context::getContext()->smarty);
$pdf->render();
}
}

View File

@@ -0,0 +1,246 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Configuration $object
*/
class AdminPreferencesControllerCore extends AdminController
{
/**
* @deprecated since 1.7.6, to be removed in the next minor
*/
public function __construct()
{
@trigger_error(
'The AdminPreferencesController is deprecated and will be removed in the next minor',
E_USER_DEPRECATED
);
$this->bootstrap = true;
$this->className = 'Configuration';
$this->table = 'configuration';
parent::__construct();
// Prevent classes which extend AdminPreferences to load useless data
if (get_class($this) == 'AdminPreferencesController') {
$round_mode = array(
array(
'value' => PS_ROUND_HALF_UP,
'name' => $this->trans('Round up away from zero, when it is half way there (recommended)', array(), 'Admin.Shopparameters.Feature'),
),
array(
'value' => PS_ROUND_HALF_DOWN,
'name' => $this->trans('Round down towards zero, when it is half way there', array(), 'Admin.Shopparameters.Feature'),
),
array(
'value' => PS_ROUND_HALF_EVEN,
'name' => $this->trans('Round towards the next even value', array(), 'Admin.Shopparameters.Feature'),
),
array(
'value' => PS_ROUND_HALF_ODD,
'name' => $this->trans('Round towards the next odd value', array(), 'Admin.Shopparameters.Feature'),
),
array(
'value' => PS_ROUND_UP,
'name' => $this->trans('Round up to the nearest value', array(), 'Admin.Shopparameters.Feature'),
),
array(
'value' => PS_ROUND_DOWN,
'name' => $this->trans('Round down to the nearest value', array(), 'Admin.Shopparameters.Feature'),
),
);
$activities1 = array(
0 => $this->trans('-- Please choose your main activity --', array(), 'Install'),
2 => $this->trans('Animals and Pets', array(), 'Install'),
3 => $this->trans('Art and Culture', array(), 'Install'),
4 => $this->trans('Babies', array(), 'Install'),
5 => $this->trans('Beauty and Personal Care', array(), 'Install'),
6 => $this->trans('Cars', array(), 'Install'),
7 => $this->trans('Computer Hardware and Software', array(), 'Install'),
8 => $this->trans('Download', array(), 'Install'),
9 => $this->trans('Fashion and accessories', array(), 'Install'),
10 => $this->trans('Flowers, Gifts and Crafts', array(), 'Install'),
11 => $this->trans('Food and beverage', array(), 'Install'),
12 => $this->trans('HiFi, Photo and Video', array(), 'Install'),
13 => $this->trans('Home and Garden', array(), 'Install'),
14 => $this->trans('Home Appliances', array(), 'Install'),
15 => $this->trans('Jewelry', array(), 'Install'),
1 => $this->trans('Lingerie and Adult', array(), 'Install'),
16 => $this->trans('Mobile and Telecom', array(), 'Install'),
17 => $this->trans('Services', array(), 'Install'),
18 => $this->trans('Shoes and accessories', array(), 'Install'),
19 => $this->trans('Sport and Entertainment', array(), 'Install'),
20 => $this->trans('Travel', array(), 'Install'),
);
$activities2 = array();
foreach ($activities1 as $value => $name) {
$activities2[] = array('value' => $value, 'name' => $name);
}
$fields = array(
'PS_SSL_ENABLED' => array(
'title' => $this->trans('Enable SSL', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('If you own an SSL certificate for your shop\'s domain name, you can activate SSL encryption (https://) for customer account identification and order processing.', array(), 'Admin.Shopparameters.Help'),
'hint' => $this->trans('If you want to enable SSL on all the pages of your shop, activate the "Enable on all the pages" option below.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0',
),
);
$fields['PS_SSL_ENABLED_EVERYWHERE'] = array(
'title' => $this->trans('Enable SSL on all pages', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('When enabled, all the pages of your shop will be SSL-secured.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0',
'disabled' => (Tools::getValue('PS_SSL_ENABLED', Configuration::get('PS_SSL_ENABLED'))) ? false : true,
);
$fields = array_merge($fields, array(
'PS_TOKEN_ENABLE' => array(
'title' => $this->trans('Increase front office security', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('Enable or disable token in the Front Office to improve PrestaShop\'s security.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0',
'visibility' => Shop::CONTEXT_ALL,
),
'PS_ALLOW_HTML_IFRAME' => array(
'title' => $this->trans('Allow iframes on HTML fields', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('Allow iframes on text fields like product description. We recommend that you leave this option disabled.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0',
),
'PS_USE_HTMLPURIFIER' => array(
'title' => $this->trans('Use HTMLPurifier Library', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('Clean the HTML content on text fields. We recommend that you leave this option enabled.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => '0',
),
'PS_PRICE_ROUND_MODE' => array(
'title' => $this->trans('Round mode', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('You can choose among 6 different ways of rounding prices. "Round up away from zero ..." is the recommended behavior.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isInt',
'cast' => 'intval',
'type' => 'select',
'list' => $round_mode,
'identifier' => 'value',
),
'PS_ROUND_TYPE' => array(
'title' => $this->trans('Round type', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('You can choose when to round prices: either on each item, each line or the total (of an invoice, for example).', array(), 'Admin.Shopparameters.Help'),
'cast' => 'intval',
'type' => 'select',
'list' => array(
array(
'name' => $this->trans('Round on each item', array(), 'Admin.Shopparameters.Feature'),
'id' => Order::ROUND_ITEM,
),
array(
'name' => $this->trans('Round on each line', array(), 'Admin.Shopparameters.Feature'),
'id' => Order::ROUND_LINE,
),
array(
'name' => $this->trans('Round on the total', array(), 'Admin.Shopparameters.Feature'),
'id' => Order::ROUND_TOTAL,
),
),
'identifier' => 'id',
),
'PS_PRICE_DISPLAY_PRECISION' => array(
'title' => $this->trans('Number of decimals', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('Choose how many decimals you want to display', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isUnsignedInt',
'cast' => 'intval',
'type' => 'text',
'class' => 'fixed-width-xxl',
),
'PS_DISPLAY_SUPPLIERS' => array(
'title' => $this->trans('Display brands and suppliers', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('Enable brands and suppliers pages on your front office even when their respective modules are disabled.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
),
'PS_DISPLAY_BEST_SELLERS' => array(
'title' => $this->trans('Display best sellers', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('Enable best sellers page on your front office even when its respective module is disabled.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
),
'PS_MULTISHOP_FEATURE_ACTIVE' => array(
'title' => $this->trans('Enable Multistore', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('The multistore feature allows you to manage several e-shops with one Back Office. If this feature is enabled, a "Multistore" page will be available in the "Advanced Parameters" menu.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'visibility' => Shop::CONTEXT_ALL,
),
'PS_SHOP_ACTIVITY' => array(
'title' => $this->trans('Main Shop Activity', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isInt',
'cast' => 'intval',
'type' => 'select',
'list' => $activities2,
'identifier' => 'value',
),
));
// No HTTPS activation if you haven't already.
if (!Tools::usingSecureMode() && !Configuration::get('PS_SSL_ENABLED')) {
$requestUri = '';
if (array_key_exists('REQUEST_URI', $_SERVER)) {
$requestUri = $_SERVER['REQUEST_URI'];
}
$fields['PS_SSL_ENABLED']['type'] = 'disabled';
$fields['PS_SSL_ENABLED']['disabled'] = '<a class="btn btn-link" href="https://' .
Tools::getShopDomainSsl() .
Tools::safeOutput($requestUri) . '">' .
$this->trans('Please click here to check if your shop supports HTTPS.', array(), 'Admin.Shopparameters.Feature') . '</a>';
}
$this->fields_options = array(
'general' => array(
'title' => $this->trans('General', array(), 'Admin.Global'),
'icon' => 'icon-cogs',
'fields' => $fields,
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,241 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property QuickAccess $object
*/
class AdminQuickAccessesControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'quick_access';
$this->className = 'QuickAccess';
$this->lang = true;
$this->addRowAction('edit');
$this->addRowAction('delete');
parent::__construct();
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'id_quick_access' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
),
'link' => array(
'title' => $this->trans('Link', array(), 'Admin.Navigation.Header'),
),
'new_window' => array(
'title' => $this->trans('New window', array(), 'Admin.Navigation.Header'),
'align' => 'center',
'type' => 'bool',
'active' => 'new_window',
'class' => 'fixed-width-sm',
),
);
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Quick Access menu', array(), 'Admin.Navigation.Header'),
'icon' => 'icon-align-justify',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'maxlength' => 32,
'required' => true,
'hint' => $this->trans('Forbidden characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('URL', array(), 'Admin.Global'),
'name' => 'link',
'maxlength' => 128,
'required' => true,
'hint' => $this->trans('If it\'s a URL that comes from your back office, you MUST remove the security token.', array(), 'Admin.Navigation.Header'),
),
array(
'type' => 'switch',
'label' => $this->trans('Open in new window', array(), 'Admin.Navigation.Header'),
'name' => 'new_window',
'required' => false,
'values' => array(
array(
'id' => 'new_window_on',
'value' => 1,
'label' => '<img src="../img/admin/enabled.gif" alt="' . $this->trans('Enabled', array(), 'Admin.Global') . '" title="' . $this->trans('Enabled', array(), 'Admin.Global') . '" />',
),
array(
'id' => 'new_window_off',
'value' => 0,
'label' => '<img src="../img/admin/disabled.gif" alt="' . $this->trans('Disabled', array(), 'Admin.Global') . '" title="' . $this->trans('Disabled', array(), 'Admin.Global') . '" />',
),
),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
}
public function getTabSlug()
{
return 'ROLE_MOD_TAB_ADMINACCESS_';
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_quick_access'] = array(
'href' => self::$currentIndex . '&addquick_access&token=' . $this->token,
'desc' => $this->trans('Add new quick access', array(), 'Admin.Navigation.Header'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function initProcess()
{
if ((isset($_GET['new_window' . $this->table]) || isset($_GET['new_window'])) && Tools::getValue($this->identifier)) {
if ($this->access('edit')) {
$this->action = 'newWindow';
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
}
parent::initProcess();
}
public function getQuickAccessesList()
{
$links = QuickAccess::getQuickAccessesWithToken($this->context->language->id, (int) $this->context->employee->id);
return json_encode($links);
}
public function addQuickLink()
{
if (!isset($this->className) || empty($this->className)) {
return false;
}
$this->validateRules();
if (count($this->errors) <= 0) {
$this->object = new $this->className();
$this->copyFromPost($this->object, $this->table);
$exists = Db::getInstance()->getValue('SELECT id_quick_access FROM ' . _DB_PREFIX_ . 'quick_access WHERE link = "' . pSQL($this->object->link) . '"');
if ($exists) {
return true;
}
$this->beforeAdd($this->object);
if (method_exists($this->object, 'add') && !$this->object->add()) {
$this->errors[] = $this->trans('An error occurred while creating an object.', array(), 'Admin.Notifications.Error') .
' <b>' . $this->table . ' (' . Db::getInstance()->getMsgError() . ')</b>';
} elseif (($_POST[$this->identifier] = $this->object->id) && $this->postImage($this->object->id) && !count($this->errors) && $this->_redirect) {
// voluntary do affectation here
PrestaShopLogger::addLog($this->trans('%class_name% addition', array('%class_name%' => $this->className), 'Admin.Advparameters.Feature'), 1, null, $this->className, (int) $this->object->id, true, (int) $this->context->employee->id);
$this->afterAdd($this->object);
}
}
$this->errors = array_unique($this->errors);
if (!empty($this->errors)) {
$this->errors['has_errors'] = true;
$this->ajaxRender(json_encode($this->errors));
return false;
}
return $this->getQuickAccessesList();
}
public function processDelete()
{
parent::processDelete();
return $this->getQuickAccessesList();
}
public function ajaxProcessGetUrl()
{
if (Tools::strtolower(Tools::getValue('method')) === 'add') {
$params['new_window'] = 0;
$params['name_' . (int) Configuration::get('PS_LANG_DEFAULT')] = Tools::getValue('name');
$params['link'] = Tools::getValue('url');
$params['submitAddquick_access'] = 1;
unset($_POST['name']);
$_POST = array_merge($_POST, $params);
die($this->addQuickLink());
} elseif (Tools::strtolower(Tools::getValue('method')) === 'remove') {
$params['deletequick_access'] = 1;
$_POST = array_merge($_POST, $params);
die($this->processDelete());
}
}
public function processNewWindow()
{
if (Validate::isLoadedObject($object = $this->loadObject())) {
/** @var QuickAccess $object */
if ($object->toggleNewWindow()) {
$this->redirect_after = self::$currentIndex . '&conf=5&token=' . $this->token;
} else {
$this->errors[] = $this->trans('An error occurred while updating new window property.', array(), 'Admin.Navigation.Notification');
}
} else {
$this->errors[] = $this->trans('An error occurred while updating the new window property for this object.', array(), 'Admin.Navigation.Notification') .
' <b>' . $this->table . '</b> ' .
$this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
}
return $object;
}
}

View File

@@ -0,0 +1,525 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;
/**
* @property Referrer $object
*/
class AdminReferrersControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'referrer';
$this->className = 'Referrer';
parent::__construct();
$this->fields_list = array(
'id_referrer' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'width' => 25,
'align' => 'center',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'width' => 80,
),
'cache_visitors' => array(
'title' => $this->trans('Visitors', array(), 'Admin.Shopparameters.Feature'),
'width' => 30,
'align' => 'center',
),
'cache_visits' => array(
'title' => $this->trans('Visits', array(), 'Admin.Shopparameters.Feature'),
'width' => 30,
'align' => 'center',
),
'cache_pages' => array(
'title' => $this->trans('Pages', array(), 'Admin.Shopparameters.Feature'),
'width' => 30,
'align' => 'center',
),
'cache_registrations' => array(
'title' => $this->trans('Reg.', array(), 'Admin.Shopparameters.Feature'),
'width' => 30,
'align' => 'center',
),
'cache_orders' => array(
'title' => $this->trans('Orders', array(), 'Admin.Global'),
'width' => 30,
'align' => 'center',
),
'cache_sales' => array(
'title' => $this->trans('Sales', array(), 'Admin.Global'),
'width' => 80,
'align' => 'right',
'prefix' => '<b>',
'suffix' => '</b>',
'price' => true,
),
'cart' => array(
'title' => $this->trans('Avg. cart', array(), 'Admin.Shopparameters.Feature'),
'width' => 50,
'align' => 'right',
'price' => true,
'havingFilter' => true,
),
'cache_reg_rate' => array(
'title' => $this->trans('Reg. rate', array(), 'Admin.Shopparameters.Feature'),
'width' => 30,
'align' => 'center',
),
'cache_order_rate' => array(
'title' => $this->trans('Order rate', array(), 'Admin.Shopparameters.Feature'),
'width' => 30,
'align' => 'center',
),
'fee0' => array(
'title' => $this->trans('Click', array(), 'Admin.Shopparameters.Feature'),
'width' => 30,
'align' => 'right',
'price' => true,
'havingFilter' => true,
),
'fee1' => array(
'title' => $this->trans('Base', array(), 'Admin.Shopparameters.Feature'),
'width' => 30,
'align' => 'right',
'price' => true,
'havingFilter' => true,
),
'fee2' => array(
'title' => $this->trans('Percent', array(), 'Admin.Global'),
'width' => 30,
'align' => 'right',
'price' => true,
'havingFilter' => true,
),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->context->controller->addJqueryUI('ui.datepicker');
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_referrer'] = array(
'href' => self::$currentIndex . '&addreferrer&token=' . $this->token,
'desc' => $this->trans('Add new referrer', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderList()
{
// Display list Referrers:
$this->addRowAction('view');
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_select = 'SUM(sa.cache_visitors) AS cache_visitors, SUM(sa.cache_visits) AS cache_visits, SUM(sa.cache_pages) AS cache_pages,
SUM(sa.cache_registrations) AS cache_registrations, SUM(sa.cache_orders) AS cache_orders, SUM(sa.cache_sales) AS cache_sales,
IF(sa.cache_orders > 0, ROUND(sa.cache_sales/sa.cache_orders, 2), 0) as cart, (sa.cache_visits*click_fee) as fee0,
(sa.cache_orders*base_fee) as fee1, (sa.cache_sales*percent_fee/100) as fee2';
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'referrer_shop` sa
ON (sa.`' . bqSQL($this->identifier) . '` = a.`' . bqSQL($this->identifier) . '` AND sa.id_shop IN (' . implode(', ', Shop::getContextListShopID()) . '))';
$this->_group = 'GROUP BY sa.id_referrer';
$this->tpl_list_vars = array(
'enable_calendar' => $this->enableCalendar(),
'calendar_form' => $this->displayCalendar(),
'settings_form' => $this->displaySettings(),
);
return parent::renderList();
}
public function renderForm()
{
$uri = Tools::getHttpHost(true, true) . __PS_BASE_URI__;
$this->fields_form[0] = array('form' => array(
'legend' => array(
'title' => $this->trans('Affiliate', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-group',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'required' => true,
'autocomplete' => false,
),
array(
'type' => 'password',
'label' => $this->trans('Password', array(), 'Admin.Global'),
'name' => 'passwd',
'desc' => $this->trans('Leave blank if no change.', array(), 'Admin.Shopparameters.Help'),
'autocomplete' => false,
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
));
$moduleManagerBuilder = ModuleManagerBuilder::getInstance();
$moduleManager = $moduleManagerBuilder->build();
if ($moduleManager->isInstalled('trackingfront')) {
$this->fields_form[0]['form']['desc'] = array(
$this->trans('Affiliates can access their data with this name and password.', array(), 'Admin.Shopparameters.Feature'),
$this->trans('Front access:', array(), 'Admin.Shopparameters.Feature') . ' <a class="btn btn-link" href="' . $uri . 'modules/trackingfront/stats.php" onclick="return !window.open(this.href);"><i class="icon-external-link-sign"></i> ' . $uri . 'modules/trackingfront/stats.php</a>',
);
} else {
$this->fields_form[0]['form']['desc'] = array(
$this->trans(
'Please install the "%modulename%" module in order to give your affiliates access to their own statistics.',
array(
'%modulename%' => Module::getModuleName('trackingfront'),
),
'Admin.Shopparameters.Notification'
),
);
}
$this->fields_form[1] = array('form' => array(
'legend' => array(
'title' => $this->trans('Commission plan', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-dollar',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Click fee', array(), 'Admin.Shopparameters.Feature'),
'name' => 'click_fee',
'desc' => $this->trans('Fee given for each visit.', array(), 'Admin.Shopparameters.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Base fee', array(), 'Admin.Shopparameters.Feature'),
'name' => 'base_fee',
'desc' => $this->trans('Fee given for each order placed.', array(), 'Admin.Shopparameters.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Percent fee', array(), 'Admin.Shopparameters.Feature'),
'name' => 'percent_fee',
'desc' => $this->trans('Percent of the sales.', array(), 'Admin.Shopparameters.Notification'),
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
));
if (Shop::isFeatureActive()) {
$this->fields_form[1]['form']['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$this->fields_form[2] = array('form' => array(
'legend' => array(
'title' => $this->trans('Technical information -- Simple mode', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-cogs',
),
'help' => true,
'input' => array(
array(
'type' => 'textarea',
'label' => $this->trans('Include', array(), 'Admin.Shopparameters.Feature'),
'name' => 'http_referer_like',
'cols' => 40,
'rows' => 1,
'legend' => $this->trans('HTTP referrer', array(), 'Admin.Shopparameters.Feature'),
),
array(
'type' => 'textarea',
'label' => $this->trans('Exclude', array(), 'Admin.Shopparameters.Feature'),
'name' => 'http_referer_like_not',
'cols' => 40,
'rows' => 1,
),
array(
'type' => 'textarea',
'label' => $this->trans('Include', array(), 'Admin.Shopparameters.Feature'),
'name' => 'request_uri_like',
'cols' => 40,
'rows' => 1,
'legend' => $this->trans('Request URI', array(), 'Admin.Shopparameters.Feature'),
),
array(
'type' => 'textarea',
'label' => $this->trans('Exclude', array(), 'Admin.Shopparameters.Feature'),
'name' => 'request_uri_like_not',
'cols' => 40,
'rows' => 1,
),
),
'desc' => $this->trans(
'If you know how to use MySQL regular expressions, you can use the [1]expert mode[/1].',
array(
'[1]' => '<a style="cursor: pointer; font-weight: bold;" onclick="$(\'#tracking_expert\').slideToggle();">',
'[/1]' => '</a>',
),
'Admin.Shopparameters.Help'
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
));
$this->fields_form[3] = array('form' => array(
'legend' => array(
'title' => $this->trans('Technical information -- Expert mode', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-cogs',
),
'input' => array(
array(
'type' => 'textarea',
'label' => $this->trans('Include', array(), 'Admin.Shopparameters.Feature'),
'name' => 'http_referer_regexp',
'cols' => 40,
'rows' => 1,
'legend' => $this->trans('HTTP referrer', array(), 'Admin.Shopparameters.Feature'),
),
array(
'type' => 'textarea',
'label' => $this->trans('Exclude', array(), 'Admin.Shopparameters.Feature'),
'name' => 'http_referer_regexp_not',
'cols' => 40,
'rows' => 1,
),
array(
'type' => 'textarea',
'label' => $this->trans('Include', array(), 'Admin.Shopparameters.Feature'),
'name' => 'request_uri_regexp',
'cols' => 40,
'rows' => 1,
'legend' => $this->trans('Request URI', array(), 'Admin.Shopparameters.Feature'),
),
array(
'type' => 'textarea',
'label' => $this->trans('Exclude', array(), 'Admin.Shopparameters.Feature'),
'name' => 'request_uri_regexp_not',
'cols' => 40,
'rows' => 1,
),
),
));
$this->multiple_fieldsets = true;
if (!($obj = $this->loadObject(true))) {
return;
}
$this->fields_value = array(
'click_fee' => number_format((float) ($this->getFieldValue($obj, 'click_fee')), 2),
'base_fee' => number_format((float) ($this->getFieldValue($obj, 'base_fee')), 2),
'percent_fee' => number_format((float) ($this->getFieldValue($obj, 'percent_fee')), 2),
'http_referer_like' => str_replace('\\', '\\\\', htmlentities($this->getFieldValue($obj, 'http_referer_like'), ENT_COMPAT, 'UTF-8')),
'http_referer_like_not' => str_replace('\\', '\\\\', htmlentities($this->getFieldValue($obj, 'http_referer_like_not'), ENT_COMPAT, 'UTF-8')),
'request_uri_like' => str_replace('\\', '\\\\', htmlentities($this->getFieldValue($obj, 'request_uri_like'), ENT_COMPAT, 'UTF-8')),
'request_uri_like_not' => str_replace('\\', '\\\\', htmlentities($this->getFieldValue($obj, 'request_uri_like_not'), ENT_COMPAT, 'UTF-8')),
);
$this->tpl_form_vars = array('uri' => $uri);
return parent::renderForm();
}
public function displayAjaxProductFilter()
{
$this->ajaxRender(
Referrer::getAjaxProduct(
(int) Tools::getValue('id_referrer'),
(int) Tools::getValue('id_product'),
new Employee((int) Tools::getValue('id_employee'))
));
}
public function displayAjaxFillProducts()
{
$json_array = array();
$result = Db::getInstance()->executeS('
SELECT p.id_product, pl.name
FROM ' . _DB_PREFIX_ . 'product p
LEFT JOIN ' . _DB_PREFIX_ . 'product_lang pl
ON (p.id_product = pl.id_product AND pl.id_lang = ' . (int) Tools::getValue('id_lang') . ')
' . (Tools::getValue('filter') != 'undefined' ? 'WHERE name LIKE "%' . pSQL(Tools::getValue('filter')) . '%"' : '')
);
foreach ($result as $row) {
$json_array[] = [
'id_product' => (int) $row['id_product'],
'name' => $row['name'],
];
}
$this->ajaxRender('[' . implode(',', $json_array) . ']');
}
public function displayCalendar($action = null, $table = null, $identifier = null, $id = null)
{
return AdminReferrersController::displayCalendarForm(array(
'Calendar' => $this->trans('Calendar', array(), 'Admin.Global'),
'Day' => $this->trans('Today', array(), 'Admin.Global'),
'Month' => $this->trans('Month', array(), 'Admin.Global'),
'Year' => $this->trans('Year', array(), 'Admin.Global'),
), $this->token, $action, $table, $identifier, $id);
}
public static function displayCalendarForm($translations, $token, $action = null, $table = null, $identifier = null, $id = null)
{
$context = Context::getContext();
$tpl = $context->controller->createTemplate('calendar.tpl');
$context->controller->addJqueryUI('ui.datepicker');
$tpl->assign(array(
'current' => self::$currentIndex,
'token' => $token,
'action' => $action,
'table' => $table,
'identifier' => $identifier,
'id' => $id,
'translations' => $translations,
'datepickerFrom' => Tools::getValue('datepickerFrom', $context->employee->stats_date_from),
'datepickerTo' => Tools::getValue('datepickerTo', $context->employee->stats_date_to),
));
return $tpl->fetch();
}
public function displaySettings()
{
if (!Tools::isSubmit('viewreferrer')) {
$tpl = $this->createTemplate('form_settings.tpl');
$statsdata = Module::getInstanceByName('statsdata');
$statsdata_name = false;
if (Validate::isLoadedObject($statsdata)) {
$statsdata_name = $statsdata->displayName;
}
$tpl->assign(array(
'statsdata_name' => $statsdata_name,
'current' => self::$currentIndex,
'token' => $this->token,
'tracking_dt' => (int) Tools::getValue('tracking_dt', Configuration::get('TRACKING_DIRECT_TRAFFIC')),
'exclude_tx' => (int) Tools::getValue('exclude_tx', Configuration::get('REFERER_TAX')),
'exclude_ship' => (int) Tools::getValue('exclude_ship', Configuration::get('REFERER_SHIPPING')),
));
return $tpl->fetch();
}
}
protected function enableCalendar()
{
return !Tools::isSubmit('add' . $this->table) && !Tools::isSubmit('submitAdd' . $this->table) && !Tools::isSubmit('update' . $this->table);
}
public function postProcess()
{
if ($this->enableCalendar()) {
// Warning, instantiating a controller here changes the controller in the Context...
$calendar_tab = new AdminStatsController();
$calendar_tab->postProcess();
// ...so we set it back to the correct one here
$this->context->controller = $this;
}
if (Tools::isSubmit('submitSettings')) {
if ($this->access('edit')) {
if (Configuration::updateValue('TRACKING_DIRECT_TRAFFIC', (int) Tools::getValue('tracking_dt'))
&& Configuration::updateValue('REFERER_TAX', (int) Tools::getValue('exclude_tx'))
&& Configuration::updateValue('REFERER_SHIPPING', (int) Tools::getValue('exclude_ship'))) {
Tools::redirectAdmin(self::$currentIndex . '&conf=4&token=' . Tools::getValue('token'));
}
}
}
if (ModuleGraph::getDateBetween() != Configuration::get('PS_REFERRERS_CACHE_LIKE') || Tools::isSubmit('submitRefreshCache')) {
Referrer::refreshCache();
}
if (Tools::isSubmit('submitRefreshIndex')) {
Referrer::refreshIndex();
}
return parent::postProcess();
}
public function renderView()
{
$referrer = new Referrer((int) Tools::getValue('id_referrer'));
$display_tab = array(
'uniqs' => $this->trans('Unique visitors', array(), 'Admin.Shopparameters.Feature'),
'visitors' => $this->trans('Visitors', array(), 'Admin.Shopparameters.Feature'),
'visits' => $this->trans('Visits', array(), 'Admin.Shopparameters.Feature'),
'pages' => $this->trans('Pages viewed', array(), 'Admin.Shopparameters.Feature'),
'registrations' => $this->trans('Registrations', array(), 'Admin.Shopparameters.Feature'),
'orders' => $this->trans('Orders', array(), 'Admin.Global'),
'sales' => $this->trans('Sales', array(), 'Admin.Global'),
'reg_rate' => $this->trans('Registration rate', array(), 'Admin.Shopparameters.Feature'),
'order_rate' => $this->trans('Order rate', array(), 'Admin.Shopparameters.Feature'),
'click_fee' => $this->trans('Click fee', array(), 'Admin.Shopparameters.Feature'),
'base_fee' => $this->trans('Base fee', array(), 'Admin.Shopparameters.Feature'),
'percent_fee' => $this->trans('Percent fee', array(), 'Admin.Shopparameters.Feature'),
);
$this->tpl_view_vars = array(
'enable_calendar' => $this->enableCalendar(),
'calendar_form' => $this->displayCalendar($this->action, $this->table, $this->identifier, (int) Tools::getValue($this->identifier)),
'referrer' => $referrer,
'display_tab' => $display_tab,
'id_employee' => (int) $this->context->employee->id,
'id_lang' => (int) $this->context->language->id,
);
return parent::renderView();
}
}

View File

@@ -0,0 +1,555 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property RequestSql $object
*/
class AdminRequestSqlControllerCore extends AdminController
{
/**
* @var array : List of encoding type for a file
*/
public static $encoding_file = array(
array('value' => 1, 'name' => 'utf-8'),
array('value' => 2, 'name' => 'iso-8859-1'),
);
/**
* @deprecated since 1.7.6, to be removed in the next minor
*/
public function __construct()
{
@trigger_error(
'The AdminRequestSqlController is deprecated and will be removed in the next minor',
E_USER_DEPRECATED
);
$this->bootstrap = true;
$this->table = 'request_sql';
$this->className = 'RequestSql';
$this->lang = false;
$this->export = true;
parent::__construct();
$this->fields_list = array(
'id_request_sql' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'class' => 'fixed-width-xs'),
'name' => array('title' => $this->trans('SQL query Name', array(), 'Admin.Advparameters.Feature')),
'sql' => array(
'title' => $this->trans('SQL query', array(), 'Admin.Advparameters.Feature'),
'filter_key' => 'a!sql',
),
);
$this->fields_options = array(
'general' => array(
'title' => $this->trans('Settings', array(), 'Admin.Global'),
'fields' => array(
'PS_ENCODING_FILE_MANAGER_SQL' => array(
'title' => $this->trans('Select your default file encoding', array(), 'Admin.Advparameters.Feature'),
'cast' => 'intval',
'type' => 'select',
'identifier' => 'value',
'list' => self::$encoding_file,
'visibility' => Shop::CONTEXT_ALL,
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
}
public function renderOptions()
{
// Set toolbar options
$this->display = 'options';
$this->show_toolbar = true;
$this->toolbar_scroll = true;
$this->initToolbar();
return parent::renderOptions();
}
public function initToolbar()
{
if ($this->display == 'view' && $id_request = Tools::getValue('id_request_sql')) {
$this->toolbar_btn['edit'] = array(
'href' => self::$currentIndex . '&amp;updaterequest_sql&amp;token=' . $this->token . '&amp;id_request_sql=' . (int) $id_request,
'desc' => $this->trans('Edit this SQL query', array(), 'Admin.Advparameters.Feature'),
);
}
parent::initToolbar();
if ($this->display == 'options') {
unset($this->toolbar_btn['new']);
}
}
public function renderList()
{
// Set toolbar options
$this->display = null;
$this->initToolbar();
$this->displayWarning($this->trans('When saving the query, only the "SELECT" SQL statement is allowed.', array(), 'Admin.Advparameters.Notification'));
$this->displayInformation('
<strong>' . $this->trans('How do I create a new SQL query?', array(), 'Admin.Advparameters.Help') . '</strong><br />
<ul>
<li>' . $this->trans('Click "Add New".', array(), 'Admin.Advparameters.Help') . '</li>
<li>' . $this->trans('Fill in the fields and click "Save".', array(), 'Admin.Advparameters.Help') . '</li>
<li>' . $this->trans('You can then view the query results by clicking on the Edit action in the dropdown menu', array(), 'Admin.Advparameters.Help') . ' <i class="icon-pencil"></i></li>
<li>' . $this->trans('You can also export the query results as a CSV file by clicking on the Export button', array(), 'Admin.Advparameters.Help') . ' <i class="icon-cloud-upload"></i></li>
</ul>');
$this->addRowAction('export');
$this->addRowAction('view');
$this->addRowAction('edit');
$this->addRowAction('delete');
return parent::renderList();
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('SQL query', array(), 'Admin.Advparameters.Feature'),
'icon' => 'icon-cog',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('SQL query name', array(), 'Admin.Advparameters.Feature'),
'name' => 'name',
'size' => 103,
'required' => true,
),
array(
'type' => 'textarea',
'label' => $this->trans('SQL query', array(), 'Admin.Advparameters.Feature'),
'name' => 'sql',
'cols' => 100,
'rows' => 10,
'required' => true,
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
$request = new RequestSql();
$this->tpl_form_vars = array('tables' => $request->getTables());
return parent::renderForm();
}
public function postProcess()
{
/* PrestaShop demo mode */
if (_PS_MODE_DEMO_) {
$this->errors[] = $this->trans('This functionality has been disabled.', array(), 'Admin.Notifications.Error');
return;
}
return parent::postProcess();
}
/**
* method call when ajax request is made with the details row action.
*
* @see AdminController::postProcess()
*/
public function ajaxProcess()
{
/* PrestaShop demo mode */
if (_PS_MODE_DEMO_) {
die($this->trans('This functionality has been disabled.', array(), 'Admin.Notifications.Error'));
}
if ($table = Tools::getValue('table')) {
$request_sql = new RequestSql();
$attributes = $request_sql->getAttributesByTable($table);
foreach ($attributes as $key => $attribute) {
unset(
$attributes[$key]['Null'],
$attributes[$key]['Key'],
$attributes[$key]['Default'],
$attributes[$key]['Extra']
);
}
die(json_encode($attributes));
}
}
public function renderView()
{
/** @var RequestSql $obj */
if (!($obj = $this->loadObject(true))) {
return;
}
$view = array();
if ($results = Db::getInstance()->executeS($obj->sql)) {
foreach (array_keys($results[0]) as $key) {
$tab_key[] = $key;
}
$view['name'] = $obj->name;
$view['key'] = $tab_key;
$view['results'] = $results;
$this->toolbar_title = $obj->name;
$request_sql = new RequestSql();
$view['attributes'] = $request_sql->attributes;
} else {
$view['error'] = true;
}
$this->tpl_view_vars = array(
'view' => $view,
);
return parent::renderView();
}
public function _childValidation()
{
if (Tools::getValue('submitAdd' . $this->table) && $sql = Tools::getValue('sql')) {
$request_sql = new RequestSql();
$parser = $request_sql->parsingSql($sql);
$validate = $request_sql->validateParser($parser, false, $sql);
if (!$validate || count($request_sql->error_sql)) {
$this->displayError($request_sql->error_sql);
}
}
}
/**
* Display export action link.
*
* @param $token
* @param int $id
*
* @return string
*
* @throws Exception
* @throws SmartyException
*/
public function displayExportLink($token, $id)
{
$tpl = $this->createTemplate('list_action_export.tpl');
$tpl->assign(array(
'href' => self::$currentIndex . '&token=' . $this->token . '&' . $this->identifier . '=' . $id . '&export' . $this->table . '=1',
'action' => $this->trans('Export', array(), 'Admin.Actions'),
));
return $tpl->fetch();
}
public function initProcess()
{
parent::initProcess();
if (Tools::getValue('export' . $this->table)) {
$this->display = 'export';
$this->action = 'export';
}
}
public function initContent()
{
if ($this->display == 'edit' || $this->display == 'add') {
if (!$this->loadObject(true)) {
return;
}
$this->content .= $this->renderForm();
} elseif ($this->display == 'view') {
// Some controllers use the view action without an object
if ($this->className) {
$this->loadObject(true);
}
$this->content .= $this->renderView();
} elseif ($this->display == 'export') {
$this->processExport();
} elseif (!$this->ajax) {
$this->content .= $this->renderList();
$this->content .= $this->renderOptions();
}
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_request'] = array(
'href' => self::$currentIndex . '&addrequest_sql&token=' . $this->token,
'desc' => $this->trans('Add new SQL query', array(), 'Admin.Advparameters.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
/**
* Genrating a export file.
*/
public function processExport($textDelimiter = '"')
{
$id = Tools::getValue($this->identifier);
$export_dir = defined('_PS_HOST_MODE_') ? _PS_ROOT_DIR_ . '/export/' : _PS_ADMIN_DIR_ . '/export/';
if (!Validate::isFileName($id)) {
die(Tools::displayError());
}
$file = 'request_sql_' . $id . '.csv';
if ($csv = fopen($export_dir . $file, 'wb')) {
$sql = RequestSql::getRequestSqlById($id);
if ($sql) {
$results = Db::getInstance()->executeS($sql[0]['sql']);
foreach (array_keys($results[0]) as $key) {
$tab_key[] = $key;
fwrite($csv, $key . ';');
}
foreach ($results as $result) {
fwrite($csv, "\n");
foreach ($tab_key as $name) {
fwrite($csv, $textDelimiter . strip_tags($result[$name]) . $textDelimiter . ';');
}
}
if (file_exists($export_dir . $file)) {
$filesize = filesize($export_dir . $file);
$upload_max_filesize = Tools::convertBytes(ini_get('upload_max_filesize'));
if ($filesize < $upload_max_filesize) {
if (Configuration::get('PS_ENCODING_FILE_MANAGER_SQL')) {
$charset = Configuration::get('PS_ENCODING_FILE_MANAGER_SQL');
} else {
$charset = self::$encoding_file[0]['name'];
}
header('Content-Type: text/csv; charset=' . $charset);
header('Cache-Control: no-store, no-cache');
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Content-Length: ' . $filesize);
readfile($export_dir . $file);
die();
} else {
$this->errors[] = $this->trans('The file is too large and cannot be downloaded. Please use the LIMIT clause in this query.', array(), 'Admin.Advparameters.Notification');
}
}
}
}
}
/**
* Display all errors.
*
* @param $e : array of errors
*/
public function displayError($e)
{
foreach (array_keys($e) as $key) {
switch ($key) {
case 'checkedFrom':
if (isset($e[$key]['table'])) {
$this->errors[] = $this->trans(
'The "%tablename%" table does not exist.',
array(
'%tablename%' => $e[$key]['table'],
),
'Admin.Advparameters.Notification'
);
} elseif (isset($e[$key]['attribut'])) {
$this->errors[] = $this->trans(
'The "%attribute%" attribute does not exist in the "%table%" table.',
array(
'%attribute%' => $e[$key]['attribut'][0],
'%table%' => $e[$key]['attribut'][1],
),
'Admin.Advparameters.Notification'
);
} else {
$this->errors[] = $this->trans('Undefined "%s" error', array('checkedForm'), 'Admin.Advparameters.Notification');
}
break;
case 'checkedSelect':
if (isset($e[$key]['table'])) {
$this->errors[] = $this->trans(
'The "%tablename%" table does not exist.',
array(
'%tablename%' => $e[$key]['table'],
),
'Admin.Advparameters.Notification'
);
} elseif (isset($e[$key]['attribut'])) {
$this->errors[] = $this->trans(
'The "%attribute%" attribute does not exist in the "%table%" table.',
array(
'%attribute%' => $e[$key]['attribut'][0],
'%table%' => $e[$key]['attribut'][1],
),
'Admin.Advparameters.Notification'
);
} elseif (isset($e[$key]['*'])) {
$this->errors[] = $this->trans('The "*" operator cannot be used in a nested query.', array(), 'Admin.Advparameters.Notification');
} else {
$this->errors[] = $this->trans('Undefined "%s" error', array('checkedSelect'), 'Admin.Advparameters.Notification');
}
break;
case 'checkedWhere':
if (isset($e[$key]['operator'])) {
$this->errors[] = $this->trans(
'The operator "%s" is incorrect.',
array(
'%operator%' => $e[$key]['operator'],
),
'Admin.Advparameters.Notification'
);
} elseif (isset($e[$key]['attribut'])) {
$this->errors[] = $this->trans(
'The "%attribute%" attribute does not exist in the "%table%" table.',
array(
'%attribute%' => $e[$key]['attribut'][0],
'%table%' => $e[$key]['attribut'][1],
),
'Admin.Advparameters.Notification'
);
} else {
$this->errors[] = $this->trans('Undefined "%s" error', array('checkedWhere'), 'Admin.Advparameters.Notification');
}
break;
case 'checkedHaving':
if (isset($e[$key]['operator'])) {
$this->errors[] = $this->trans(
'The "%operator%" operator is incorrect.',
array(
'%operator%' => $e[$key]['operator'],
),
'Admin.Advparameters.Notification'
);
} elseif (isset($e[$key]['attribut'])) {
$this->errors[] = $this->trans(
'The "%attribute%" attribute does not exist in the "%table%" table.',
array(
'%attribute%' => $e[$key]['attribut'][0],
'%table%' => $e[$key]['attribut'][1],
),
'Admin.Advparameters.Notification'
);
} else {
$this->errors[] = $this->trans('Undefined "%s" error', array('checkedHaving'), 'Admin.Advparameters.Notification');
}
break;
case 'checkedOrder':
if (isset($e[$key]['attribut'])) {
$this->errors[] = $this->trans(
'The "%attribute%" attribute does not exist in the "%table%" table.',
array(
'%attribute%' => $e[$key]['attribut'][0],
'%table%' => $e[$key]['attribut'][1],
),
'Admin.Advparameters.Notification'
);
} else {
$this->errors[] = $this->trans('Undefined "%s" error', array('checkedOrder'), 'Admin.Advparameters.Notification');
}
break;
case 'checkedGroupBy':
if (isset($e[$key]['attribut'])) {
$this->errors[] = $this->trans(
'The "%attribute%" attribute does not exist in the "%table%" table.',
array(
'%attribute%' => $e[$key]['attribut'][0],
'%table%' => $e[$key]['attribut'][1],
),
'Admin.Advparameters.Notification'
);
} else {
$this->errors[] = $this->trans('Undefined "%s" error', array('checkedGroupBy'), 'Admin.Advparameters.Notification');
}
break;
case 'checkedLimit':
$this->errors[] = $this->trans('The LIMIT clause must contain numeric arguments.', array(), 'Admin.Advparameters.Notification');
break;
case 'returnNameTable':
if (isset($e[$key]['reference'])) {
$this->errors[] = $this->trans(
'The "%reference%" reference does not exist in the "%table%" table.',
array(
'%reference%' => $e[$key]['reference'][0],
'%table%' => $e[$key]['attribut'][1],
),
'Admin.Advparameters.Notification'
);
} else {
$this->errors[] = $this->trans('When multiple tables are used, each attribute must refer back to a table.', array(), 'Admin.Advparameters.Notification');
}
break;
case 'testedRequired':
$this->errors[] = $this->trans('"%key%" does not exist.', array('%key%' => $e[$key]), 'Admin.Notifications.Error');
break;
case 'testedUnauthorized':
$this->errors[] = $this->trans('"%key%" is an unauthorized keyword.', array('%key%' => $e[$key]), 'Admin.Advparameters.Notification');
break;
}
}
}
}

View File

@@ -0,0 +1,293 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property OrderReturn $object
*/
class AdminReturnControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'order_return';
$this->className = 'OrderReturn';
$this->colorOnBackground = true;
parent::__construct();
$this->_select = 'ors.color, orsl.`name`, o.`id_shop`';
$this->_join = 'LEFT JOIN ' . _DB_PREFIX_ . 'order_return_state ors ON (ors.`id_order_return_state` = a.`state`)';
$this->_join .= 'LEFT JOIN ' . _DB_PREFIX_ . 'order_return_state_lang orsl ON (orsl.`id_order_return_state` = a.`state` AND orsl.`id_lang` = ' . (int) $this->context->language->id . ')';
$this->_join .= ' LEFT JOIN ' . _DB_PREFIX_ . 'orders o ON (o.`id_order` = a.`id_order`)';
$this->fields_list = array(
'id_order_return' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'align' => 'center', 'width' => 25),
'id_order' => array('title' => $this->trans('Order ID', array(), 'Admin.Orderscustomers.Feature'), 'width' => 100, 'align' => 'center', 'filter_key' => 'a!id_order', 'havingFilter' => true),
'name' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'color' => 'color', 'width' => 'auto', 'align' => 'left'),
'date_add' => array('title' => $this->trans('Date issued', array(), 'Admin.Orderscustomers.Feature'), 'width' => 150, 'type' => 'date', 'align' => 'right', 'filter_key' => 'a!date_add'),
);
$this->fields_options = array(
'general' => array(
'title' => $this->trans('Merchandise return (RMA) options', array(), 'Admin.Orderscustomers.Feature'),
'fields' => array(
'PS_ORDER_RETURN' => array(
'title' => $this->trans('Enable returns', array(), 'Admin.Orderscustomers.Feature'),
'desc' => $this->trans('Would you like to allow merchandise returns in your shop?', array(), 'Admin.Orderscustomers.Help'),
'cast' => 'intval', 'type' => 'bool', ),
'PS_ORDER_RETURN_NB_DAYS' => array(
'title' => $this->trans('Time limit of validity', array(), 'Admin.Orderscustomers.Feature'),
'desc' => $this->trans('How many days after the delivery date does the customer have to return a product?', array(), 'Admin.Orderscustomers.Help'),
'cast' => 'intval',
'type' => 'text',
'size' => '2', ),
'PS_RETURN_PREFIX' => array(
'title' => $this->trans('Returns prefix', array(), 'Admin.Orderscustomers.Feature'),
'desc' => $this->trans('Prefix used for return name (e.g. RE00001).', array(), 'Admin.Orderscustomers.Help'),
'size' => 6,
'type' => 'textLang',
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
$this->_where = Shop::addSqlRestriction(false, 'o');
$this->_use_found_rows = false;
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Return Merchandise Authorization (RMA)', array(), 'Admin.Orderscustomers.Feature'),
'icon' => 'icon-clipboard',
),
'input' => array(
array(
'type' => 'hidden',
'name' => 'id_order',
),
array(
'type' => 'hidden',
'name' => 'id_customer',
),
array(
'type' => 'text_customer',
'label' => $this->trans('Customer', array(), 'Admin.Global'),
'name' => '',
'size' => '',
'required' => false,
),
array(
'type' => 'text_order',
'label' => $this->trans('Order', array(), 'Admin.Global'),
'name' => '',
'size' => '',
'required' => false,
),
array(
'type' => 'free',
'label' => $this->trans('Customer explanation', array(), 'Admin.Orderscustomers.Feature'),
'name' => 'question',
'size' => '',
'required' => false,
),
array(
'type' => 'select',
'label' => $this->trans('Status', array(), 'Admin.Global'),
'name' => 'state',
'required' => false,
'options' => array(
'query' => OrderReturnState::getOrderReturnStates($this->context->language->id),
'id' => 'id_order_return_state',
'name' => 'name',
),
'desc' => $this->trans('Merchandise return (RMA) status.', array(), 'Admin.Orderscustomers.Help'),
),
array(
'type' => 'list_products',
'label' => $this->trans('Products', array(), 'Admin.Global'),
'name' => '',
'size' => '',
'required' => false,
'desc' => $this->trans('List of products in return package.', array(), 'Admin.Orderscustomers.Help'),
),
array(
'type' => 'pdf_order_return',
'label' => $this->trans('Returns form', array(), 'Admin.Orderscustomers.Feature'),
'name' => '',
'size' => '',
'required' => false,
'desc' => $this->trans('The link is only available after validation and before the parcel gets delivered.', array(), 'Admin.Orderscustomers.Help'),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
$order = new Order($this->object->id_order);
$quantity_displayed = array();
// Customized products */
if ($returned_customizations = OrderReturn::getReturnedCustomizedProducts((int) ($this->object->id_order))) {
foreach ($returned_customizations as $returned_customization) {
$quantity_displayed[(int) $returned_customization['id_order_detail']] = isset($quantity_displayed[(int) $returned_customization['id_order_detail']]) ? $quantity_displayed[(int) $returned_customization['id_order_detail']] + (int) $returned_customization['product_quantity'] : (int) $returned_customization['product_quantity'];
}
}
// Classic products
$products = OrderReturn::getOrdersReturnProducts($this->object->id, $order);
// Prepare customer explanation for display
$this->object->question = '<span class="normal-text">' . nl2br($this->object->question) . '</span>';
$this->tpl_form_vars = array(
'customer' => new Customer($this->object->id_customer),
'url_customer' => $this->context->link->getAdminLink('AdminCustomers', true, [], [
'id_customer' => $this->object->id_customer,
'viewcustomer' => 1,
]),
'text_order' => $this->trans(
'Order #%id% from %date%',
array(
'%id%' => $order->id,
'%date%' => Tools::displayDate($order->date_upd),
),
'Admin.Orderscustomers.Feature'
),
'url_order' => 'index.php?tab=AdminOrders&id_order=' . (int) $order->id . '&vieworder&token=' . Tools::getAdminToken('AdminOrders' . (int) Tab::getIdFromClassName('AdminOrders') . (int) $this->context->employee->id),
'picture_folder' => _THEME_PROD_PIC_DIR_,
'returnedCustomizations' => $returned_customizations,
'customizedDatas' => Product::getAllCustomizedDatas((int) ($order->id_cart)),
'products' => $products,
'quantityDisplayed' => $quantity_displayed,
'id_order_return' => $this->object->id,
'state_order_return' => $this->object->state,
);
return parent::renderForm();
}
public function initToolbar()
{
// If display list, we don't want the "add" button
if (!$this->display || $this->display == 'list') {
return;
} elseif ($this->display != 'options') {
$this->toolbar_btn['save-and-stay'] = array(
'short' => 'SaveAndStay',
'href' => '#',
'desc' => $this->trans('Save and stay', array(), 'Admin.Actions'),
'force_desc' => true,
);
}
parent::initToolbar();
}
public function postProcess()
{
$this->context = Context::getContext();
if (Tools::isSubmit('deleteorder_return_detail')) {
if ($this->access('delete')) {
if (($id_order_detail = (int) (Tools::getValue('id_order_detail'))) && Validate::isUnsignedId($id_order_detail)) {
if (($id_order_return = (int) (Tools::getValue('id_order_return'))) && Validate::isUnsignedId($id_order_return)) {
$orderReturn = new OrderReturn($id_order_return);
if (!Validate::isLoadedObject($orderReturn)) {
die(Tools::displayError());
}
if ((int) ($orderReturn->countProduct()) > 1) {
if (OrderReturn::deleteOrderReturnDetail($id_order_return, $id_order_detail, (int) (Tools::getValue('id_customization', 0)))) {
Tools::redirectAdmin(self::$currentIndex . '&conf=4token=' . $this->token);
} else {
$this->errors[] = $this->trans('An error occurred while deleting the details of your order return.', array(), 'Admin.Orderscustomers.Notification');
}
} else {
$this->errors[] = $this->trans('You need at least one product.', array(), 'Admin.Orderscustomers.Notification');
}
} else {
$this->errors[] = $this->trans('The order return is invalid.', array(), 'Admin.Orderscustomers.Notification');
}
} else {
$this->errors[] = $this->trans('The order return content is invalid.', array(), 'Admin.Orderscustomers.Notification');
}
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('submitAddorder_return') || Tools::isSubmit('submitAddorder_returnAndStay')) {
if ($this->access('edit')) {
if (($id_order_return = (int) (Tools::getValue('id_order_return'))) && Validate::isUnsignedId($id_order_return)) {
$orderReturn = new OrderReturn($id_order_return);
$order = new Order($orderReturn->id_order);
$customer = new Customer($orderReturn->id_customer);
$orderLanguage = new Language((int) $order->id_lang);
$orderReturn->state = (int) (Tools::getValue('state'));
if ($orderReturn->save()) {
$orderReturnState = new OrderReturnState($orderReturn->state);
$vars = array(
'{lastname}' => $customer->lastname,
'{firstname}' => $customer->firstname,
'{id_order_return}' => $id_order_return,
'{state_order_return}' => (isset($orderReturnState->name[(int) $order->id_lang]) ? $orderReturnState->name[(int) $order->id_lang] : $orderReturnState->name[(int) Configuration::get('PS_LANG_DEFAULT')]),
);
Mail::Send(
(int) $order->id_lang,
'order_return_state',
$this->trans(
'Your order return status has changed',
array(),
'Emails.Subject',
$orderLanguage->locale
),
$vars,
$customer->email,
$customer->firstname . ' ' . $customer->lastname,
null,
null,
null,
null,
_PS_MAIL_DIR_,
true,
(int) $order->id_shop
);
if (Tools::isSubmit('submitAddorder_returnAndStay')) {
Tools::redirectAdmin(self::$currentIndex . '&conf=4&token=' . $this->token . '&updateorder_return&id_order_return=' . (int) $id_order_return);
} else {
Tools::redirectAdmin(self::$currentIndex . '&conf=4&token=' . $this->token);
}
}
} else {
$this->errors[] = $this->trans('No order return ID has been specified.', array(), 'Admin.Orderscustomers.Notification');
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
}
parent::postProcess();
}
}

View File

@@ -0,0 +1,427 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Alias $object
*/
class AdminSearchConfControllerCore extends AdminController
{
protected $toolbar_scroll = false;
public function __construct()
{
$this->bootstrap = true;
$this->table = 'alias';
$this->className = 'Alias';
$this->lang = false;
parent::__construct();
// Alias fields
$this->addRowAction('edit');
$this->addRowAction('delete');
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Info'),
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'alias' => array('title' => $this->trans('Aliases', array(), 'Admin.Shopparameters.Feature')),
// Search is a noum here.
'search' => array('title' => $this->trans('Search', array(), 'Admin.Shopparameters.Feature')),
'active' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'class' => 'fixed-width-sm', 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false),
);
$params = [
'action' => 'searchCron',
'ajax' => 1,
'full' => 1,
'token' => $this->getTokenForCron(),
];
if (Shop::getContext() == Shop::CONTEXT_SHOP) {
$params['id_shop'] = (int) Context::getContext()->shop->id;
}
// Search options
$cron_url = Context::getContext()->link->getAdminLink(
'AdminSearch',
false,
[],
$params
);
list($total, $indexed) = Db::getInstance()->getRow('SELECT COUNT(*) as "0", SUM(product_shop.indexed) as "1" FROM ' . _DB_PREFIX_ . 'product p ' . Shop::addSqlAssociation('product', 'p') . ' WHERE product_shop.`visibility` IN ("both", "search") AND product_shop.`active` = 1');
$this->fields_options = array(
'indexation' => array(
'title' => $this->trans('Indexing', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-cogs',
'info' => '<p>
' . $this->trans('The "indexed" products have been analyzed by PrestaShop and will appear in the results of a front office search.', array(), 'Admin.Shopparameters.Feature') . '<br />
' . $this->trans('Indexed products', array(), 'Admin.Shopparameters.Feature') . ' <strong>' . (int) $indexed . ' / ' . (int) $total . '</strong>.
</p>
<p>
' . $this->trans('Building the product index may take a few minutes.', array(), 'Admin.Shopparameters.Feature') . '
' . $this->trans('If your server stops before the process ends, you can resume the indexing by clicking "Add missing products to the index".', array(), 'Admin.Shopparameters.Feature') . '
</p>
<a href="' . Context::getContext()->link->getAdminLink('AdminSearch', false) . '&action=searchCron&ajax=1&token=' . $this->getTokenForCron() . '&amp;redirect=1' . (Shop::getContext() == Shop::CONTEXT_SHOP ? '&id_shop=' . (int) Context::getContext()->shop->id : '') . '" class="btn-link">
<i class="icon-external-link-sign"></i>
' . $this->trans('Add missing products to the index', array(), 'Admin.Shopparameters.Feature') . '
</a><br />
<a href="' . Context::getContext()->link->getAdminLink('AdminSearch', false) . '&action=searchCron&ajax=1&full=1&amp;token=' . $this->getTokenForCron() . '&amp;redirect=1' . (Shop::getContext() == Shop::CONTEXT_SHOP ? '&id_shop=' . (int) Context::getContext()->shop->id : '') . '" class="btn-link">
<i class="icon-external-link-sign"></i>
' . $this->trans('Re-build the entire index', array(), 'Admin.Shopparameters.Feature') . '
</a><br /><br />
<p>
' . $this->trans('You can set a cron job that will rebuild your index using the following URL:', array(), 'Admin.Shopparameters.Feature') . '<br />
<a href="' . Tools::safeOutput($cron_url) . '">
<i class="icon-external-link-sign"></i>
' . Tools::safeOutput($cron_url) . '
</a>
</p><br />',
'fields' => array(
'PS_SEARCH_INDEXATION' => array(
'title' => $this->trans('Indexing', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isBool',
'type' => 'bool',
'cast' => 'intval',
'desc' => $this->trans('Enable the automatic indexing of products. If you enable this feature, the products will be indexed in the search automatically when they are saved. If the feature is disabled, you will have to index products manually by using the links provided in the field set.', array(), 'Admin.Shopparameters.Help'),
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
'search' => array(
'title' => $this->trans('Search', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-search',
'fields' => array(
'PS_SEARCH_START' => array(
'title' => $this->trans('Search within word', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'desc' => $this->trans(
'By default, to search for “blouse”, you have to enter “blous”, “blo”, etc (beginning of the word) but not “lous” (within the word).',
array(),
'Admin.Shopparameters.Help'
) . '<br/>' .
$this->trans(
'With this option enabled, it also gives the good result if you search for “lous”, “ouse”, or anything contained in the word.',
array(),
'Admin.Shopparameters.Help'
),
'hint' => array(
$this->trans(
'Enable search within a whole word, rather than from its beginning only.',
array(),
'Admin.Shopparameters.Help'
),
$this->trans(
'It checks if the searched term is contained in the indexed word. This may be resource-consuming.',
array(),
'Admin.Shopparameters.Help'
),
),
),
'PS_SEARCH_END' => array(
'title' => $this->trans('Search exact end match', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'desc' => $this->trans(
'By default, if you search "book", you will have "book", "bookcase" and "bookend".',
array(),
'Admin.Shopparameters.Help'
) . '<br/>' .
$this->trans(
'With this option enabled, it only gives one result “book”, as exact end of the indexed word is matching.',
array(),
'Admin.Shopparameters.Help'
),
'hint' => array(
$this->trans(
'Enable more precise search with the end of the word.',
array(),
'Admin.Shopparameters.Help'
),
$this->trans(
'It checks if the searched term is the exact end of the indexed word.',
array(),
'Admin.Shopparameters.Help'
),
),
),
'PS_SEARCH_MINWORDLEN' => array(
'title' => $this->trans(
'Minimum word length (in characters)',
array(),
'Admin.Shopparameters.Feature'
),
'hint' => $this->trans(
'Only words this size or larger will be indexed.',
array(),
'Admin.Shopparameters.Help'
),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_BLACKLIST' => array(
'title' => $this->trans('Blacklisted words', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isGenericName',
'hint' => $this->trans(
'Please enter the index words separated by a "|".',
array(),
'Admin.Shopparameters.Help'
),
'type' => 'textareaLang',
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
'relevance' => array(
'title' => $this->trans('Weight', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-cogs',
'info' => $this->trans(
'The "weight" represents its importance and relevance for the ranking of the products when completing a new search.',
array(),
'Admin.Shopparameters.Feature'
) . '<br />
' . $this->trans(
'A word with a weight of eight will have four times more value than a word with a weight of two.',
array(),
'Admin.Shopparameters.Feature'
) . '<br /><br />
' . $this->trans(
'We advise you to set a greater weight for words which appear in the name or reference of a product. This will allow the search results to be as precise and relevant as possible.',
array(),
'Admin.Shopparameters.Feature'
) . '<br /><br />
' . $this->trans(
'Setting a weight to 0 will exclude that field from search index. Re-build of the entire index is required when changing to or from 0',
array(),
'Admin.Shopparameters.Feature'
),
'fields' => array(
'PS_SEARCH_WEIGHT_PNAME' => array(
'title' => $this->trans('Product name weight', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_WEIGHT_REF' => array(
'title' => $this->trans('Reference weight', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_WEIGHT_SHORTDESC' => array(
'title' => $this->trans(
'Short description weight',
array(),
'Admin.Shopparameters.Feature'
),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_WEIGHT_DESC' => array(
'title' => $this->trans('Description weight', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_WEIGHT_CNAME' => array(
'title' => $this->trans('Category weight', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_WEIGHT_MNAME' => array(
'title' => $this->trans('Brand weight', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_WEIGHT_TAG' => array(
'title' => $this->trans('Tags weight', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_WEIGHT_ATTRIBUTE' => array(
'title' => $this->trans('Attributes weight', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
'PS_SEARCH_WEIGHT_FEATURE' => array(
'title' => $this->trans('Features weight', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isUnsignedInt',
'type' => 'text',
'cast' => 'intval',
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_alias'] = array(
'href' => self::$currentIndex . '&addalias&token=' . $this->token,
'desc' => $this->trans('Add new alias', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
}
$this->identifier_name = 'alias';
parent::initPageHeaderToolbar();
if ($this->can_import) {
$this->toolbar_btn['import'] = array(
'href' => $this->context->link->getAdminLink('AdminImport', true) . '&import_type=alias',
'desc' => $this->trans('Import', array(), 'Admin.Actions'),
);
}
}
public function initProcess()
{
parent::initProcess();
// This is a composite page, we don't want the "options" display mode
if ($this->display == 'options') {
$this->display = '';
}
}
/**
* Function used to render the options for this controller.
*/
public function renderOptions()
{
if ($this->fields_options && is_array($this->fields_options)) {
$helper = new HelperOptions($this);
$this->setHelperDisplay($helper);
$helper->toolbar_scroll = true;
$helper->toolbar_btn = array('save' => array(
'href' => '#',
'desc' => $this->trans('Save', array(), 'Admin.Actions'),
));
$helper->id = $this->id;
$helper->tpl_vars = $this->tpl_option_vars;
$options = $helper->generateOptions($this->fields_options);
return $options;
}
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Aliases', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-search',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Alias', array(), 'Admin.Shopparameters.Feature'),
'name' => 'alias',
'required' => true,
'hint' => array(
$this->trans('Enter each alias separated by a comma (e.g. \'prestshop,preztashop,prestasohp\').', array(), 'Admin.Shopparameters.Help'),
$this->trans('Forbidden characters: &lt;&gt;;=#{}', array(), 'Admin.Shopparameters.Help'),
),
),
array(
'type' => 'text',
'label' => $this->trans('Result', array(), 'Admin.Shopparameters.Feature'),
'name' => 'search',
'required' => true,
'hint' => $this->trans('Search this word instead.', array(), 'Admin.Shopparameters.Help'),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
$this->fields_value = array('alias' => $this->object->getAliases());
return parent::renderForm();
}
public function processSave()
{
$search = (string) Tools::getValue('search');
$string = (string) Tools::getValue('alias');
$aliases = explode(',', $string);
if (empty($search) || empty($string)) {
$this->errors[] = $this->trans('Aliases and results are both required.', array(), 'Admin.Shopparameters.Notification');
}
if (!Validate::isValidSearch($search)) {
$this->errors[] = Tools::safeOutput($search) . ' ' . $this->trans('Is not a valid result', array(), 'Admin.Shopparameters.Notification');
}
foreach ($aliases as $alias) {
if (!Validate::isValidSearch($alias)) {
$this->errors[] = Tools::safeOutput($alias) . ' ' . $this->trans('Is not a valid alias', array(), 'Admin.Shopparameters.Notification');
}
}
if (!count($this->errors)) {
foreach ($aliases as $alias) {
$obj = new Alias(null, trim($alias), trim($search));
$obj->save();
}
}
if (empty($this->errors)) {
$this->confirmations[] = $this->trans('Creation successful', array(), 'Admin.Shopparameters.Notification');
}
}
/**
* Retrieve a part of the cookie key for token check. (needs to be static).
*
* @return string Token
*/
private function getTokenForCron()
{
return substr(
_COOKIE_KEY_,
AdminSearchController::TOKEN_CHECK_START_POS,
AdminSearchController::TOKEN_CHECK_LENGTH
);
}
}

View File

@@ -0,0 +1,525 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class AdminSearchControllerCore extends AdminController
{
const TOKEN_CHECK_START_POS = 34;
const TOKEN_CHECK_LENGTH = 8;
public function __construct()
{
$this->bootstrap = true;
parent::__construct();
}
/**
* {@inheritdoc}
*/
public function init()
{
if ($this->isCronTask()
&& substr(
_COOKIE_KEY_,
static::TOKEN_CHECK_START_POS,
static::TOKEN_CHECK_LENGTH
) === Tools::getValue('token')
) {
$this->setAllowAnonymous(true);
}
parent::init();
}
public function getTabSlug()
{
return 'ROLE_MOD_TAB_ADMINSEARCHCONF_';
}
public function postProcess()
{
$this->context = Context::getContext();
$this->query = trim(Tools::getValue('bo_query'));
$searchType = (int) Tools::getValue('bo_search_type');
/* 1.6 code compatibility, as we use HelperList, we need to handle click to go to product */
$action = Tools::getValue('action');
if ($action == 'redirectToProduct') {
$id_product = (int) Tools::getValue('id_product');
$link = $this->context->link->getAdminLink('AdminProducts', false, array('id_product' => $id_product));
Tools::redirectAdmin($link);
}
/* Handle empty search field */
if (!empty($this->query)) {
if (!$searchType && strlen($this->query) > 1) {
$this->searchFeatures();
}
/* Product research */
if (!$searchType || $searchType == 1) {
/* Handle product ID */
if ($searchType == 1 && (int) $this->query && Validate::isUnsignedInt((int) $this->query)) {
if (($product = new Product($this->query)) && Validate::isLoadedObject($product)) {
Tools::redirectAdmin('index.php?tab=AdminProducts&id_product=' . (int) ($product->id) . '&token=' . Tools::getAdminTokenLite('AdminProducts'));
}
}
/* Normal catalog search */
$this->searchCatalog();
}
/* Customer */
if (!$searchType || $searchType == 2 || $searchType == 6) {
if (!$searchType || $searchType == 2) {
/* Handle customer ID */
if ($searchType && (int) $this->query && Validate::isUnsignedInt((int) $this->query)) {
if (($customer = new Customer($this->query)) && Validate::isLoadedObject($customer)) {
Tools::redirectAdmin($this->context->link->getAdminLink(
'AdminCustomers',
true,
[],
[
'id_customer' => $customer->id,
'viewcustomer' => 1,
]
));
}
}
/* Normal customer search */
$this->searchCustomer();
}
if ($searchType == 6) {
$this->searchIP();
}
}
/* Order */
if (!$searchType || $searchType == 3) {
if (Validate::isUnsignedInt(trim($this->query)) && (int) $this->query && ($order = new Order((int) $this->query)) && Validate::isLoadedObject($order)) {
if ($searchType == 3) {
Tools::redirectAdmin('index.php?tab=AdminOrders&id_order=' . (int) $order->id . '&vieworder' . '&token=' . Tools::getAdminTokenLite('AdminOrders'));
} else {
$row = get_object_vars($order);
$row['id_order'] = $row['id'];
$customer = $order->getCustomer();
$row['customer'] = $customer->firstname . ' ' . $customer->lastname;
$order_state = $order->getCurrentOrderState();
$row['osname'] = $order_state->name[$this->context->language->id];
$this->_list['orders'] = array($row);
}
} else {
$orders = Order::getByReference($this->query);
$nb_orders = count($orders);
if ($nb_orders == 1 && $searchType == 3) {
Tools::redirectAdmin('index.php?tab=AdminOrders&id_order=' . (int) $orders[0]->id . '&vieworder' . '&token=' . Tools::getAdminTokenLite('AdminOrders'));
} elseif ($nb_orders) {
$this->_list['orders'] = array();
foreach ($orders as $order) {
/** @var Order $order */
$row = get_object_vars($order);
$row['id_order'] = $row['id'];
$customer = $order->getCustomer();
$row['customer'] = $customer->firstname . ' ' . $customer->lastname;
$order_state = $order->getCurrentOrderState();
$row['osname'] = $order_state->name[$this->context->language->id];
$this->_list['orders'][] = $row;
}
} elseif ($searchType == 3) {
$this->errors[] = $this->trans('No order was found with this ID:', array(), 'Admin.Orderscustomers.Notification') . ' ' . Tools::htmlentitiesUTF8($this->query);
}
}
}
/* Invoices */
if ($searchType == 4) {
if (Validate::isOrderInvoiceNumber($this->query) && ($invoice = OrderInvoice::getInvoiceByNumber($this->query))) {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminPdf') . '&submitAction=generateInvoicePDF&id_order=' . (int) ($invoice->id_order));
}
$this->errors[] = $this->trans('No invoice was found with this ID:', array(), 'Admin.Orderscustomers.Notification') . ' ' . Tools::htmlentitiesUTF8($this->query);
}
/* Cart */
if ($searchType == 5) {
if ((int) $this->query && Validate::isUnsignedInt((int) $this->query) && ($cart = new Cart($this->query)) && Validate::isLoadedObject($cart)) {
Tools::redirectAdmin('index.php?tab=AdminCarts&id_cart=' . (int) ($cart->id) . '&viewcart' . '&token=' . Tools::getAdminToken('AdminCarts' . (int) (Tab::getIdFromClassName('AdminCarts')) . (int) $this->context->employee->id));
}
$this->errors[] = $this->trans('No cart was found with this ID:', array(), 'Admin.Orderscustomers.Notification') . ' ' . Tools::htmlentitiesUTF8($this->query);
}
/* IP */
// 6 - but it is included in the customer block
/* Module search */
if (!$searchType || $searchType == 7) {
/* Handle module name */
if ($searchType == 7 && Validate::isModuleName($this->query) && ($module = Module::getInstanceByName($this->query)) && Validate::isLoadedObject($module)) {
Tools::redirectAdmin('index.php?tab=AdminModules&tab_module=' . $module->tab . '&module_name=' . $module->name . '&anchor=' . ucfirst($module->name) . '&token=' . Tools::getAdminTokenLite('AdminModules'));
}
/* Normal catalog search */
$this->searchModule();
}
}
$this->display = 'view';
}
public function searchIP()
{
if (!ip2long(trim($this->query))) {
$this->errors[] = $this->trans('This is not a valid IP address:', array(), 'Admin.Shopparameters.Notification') . ' ' . Tools::htmlentitiesUTF8($this->query);
return;
}
$this->_list['customers'] = Customer::searchByIp($this->query);
}
/**
* Search a specific string in the products and categories.
*
* @param string $query String to find in the catalog
*/
public function searchCatalog()
{
$this->context = Context::getContext();
$this->_list['products'] = Product::searchByName($this->context->language->id, $this->query);
$this->_list['categories'] = Category::searchByName($this->context->language->id, $this->query);
}
/**
* Search a specific name in the customers.
*
* @param string $query String to find in the catalog
*/
public function searchCustomer()
{
$this->_list['customers'] = Customer::searchByName($this->query);
}
public function searchModule()
{
$this->_list['modules'] = array();
$all_modules = Module::getModulesOnDisk(true, true, Context::getContext()->employee->id);
foreach ($all_modules as $module) {
if (stripos($module->name, $this->query) !== false || stripos($module->displayName, $this->query) !== false || stripos($module->description, $this->query) !== false) {
$module->linkto = 'index.php?tab=AdminModules&tab_module=' . $module->tab . '&module_name=' . $module->name . '&anchor=' . ucfirst($module->name) . '&token=' . Tools::getAdminTokenLite('AdminModules');
$this->_list['modules'][] = $module;
}
}
if (!is_numeric(trim($this->query)) && !Validate::isEmail($this->query)) {
$iso_lang = Tools::strtolower(Context::getContext()->language->iso_code);
$iso_country = Tools::strtolower(Country::getIsoById(Configuration::get('PS_COUNTRY_DEFAULT')));
if (($json_content = Tools::file_get_contents('https://api-addons.prestashop.com/' . _PS_VERSION_ . '/search/' . urlencode($this->query) . '/' . $iso_country . '/' . $iso_lang . '/')) != false) {
$results = json_decode($json_content, true);
if (isset($results['id'])) {
$this->_list['addons'] = array($results);
} else {
$this->_list['addons'] = $results;
}
}
}
}
/**
* Search a feature in all store.
*
* @param string $query String to find in the catalog
*/
public function searchFeatures()
{
$this->_list['features'] = array();
global $_LANGADM;
if ($_LANGADM === null) {
return;
}
$tabs = array();
$key_match = array();
$result = Db::getInstance()->executeS(
'
SELECT class_name, name
FROM ' . _DB_PREFIX_ . 'tab t
INNER JOIN ' . _DB_PREFIX_ . 'tab_lang tl ON (t.id_tab = tl.id_tab AND tl.id_lang = ' . (int) $this->context->employee->id_lang . ')
WHERE active = 1' . (defined('_PS_HOST_MODE_') ? ' AND t.`hide_host_mode` = 0' : '')
);
foreach ($result as $row) {
if (Access::isGranted('ROLE_MOD_TAB_' . strtoupper($row['class_name']) . '_READ', $this->context->employee->id_profile)) {
$tabs[strtolower($row['class_name'])] = $row['name'];
$key_match[strtolower($row['class_name'])] = $row['class_name'];
}
}
$this->_list['features'] = array();
foreach ($_LANGADM as $key => $value) {
if (stripos($value, $this->query) !== false) {
$value = stripslashes($value);
$key = strtolower(substr($key, 0, -32));
if (in_array($key, array('AdminTab', 'index'))) {
continue;
}
// if class name doesn't exists, just ignore it
if (!isset($tabs[$key])) {
continue;
}
if (!isset($this->_list['features'][$tabs[$key]])) {
$this->_list['features'][$tabs[$key]] = array();
}
$this->_list['features'][$tabs[$key]][] = array('link' => Context::getContext()->link->getAdminLink($key_match[$key]), 'value' => Tools::safeOutput($value));
}
}
}
protected function initOrderList()
{
$this->fields_list['orders'] = array(
'reference' => array('title' => $this->trans('Reference', array(), 'Admin.Global'), 'align' => 'center', 'width' => 65),
'id_order' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'align' => 'center', 'width' => 25),
'customer' => array('title' => $this->trans('Customer', array(), 'Admin.Global')),
'total_paid_tax_incl' => array('title' => $this->trans('Total', array(), 'Admin.Global'), 'width' => 70, 'align' => 'right', 'type' => 'price', 'currency' => true),
'payment' => array('title' => $this->trans('Payment', array(), 'Admin.Global'), 'width' => 100),
'osname' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'width' => 280),
'date_add' => array('title' => $this->trans('Date', array(), 'Admin.Global'), 'width' => 130, 'align' => 'right', 'type' => 'datetime'),
);
}
protected function initCustomerList()
{
$genders_icon = array('default' => 'unknown.gif');
$genders = array(0 => $this->trans('?', array(), 'Admin.Global'));
foreach (Gender::getGenders() as $gender) {
/* @var Gender $gender */
$genders_icon[$gender->id] = '../genders/' . (int) $gender->id . '.jpg';
$genders[$gender->id] = $gender->name;
}
$this->fields_list['customers'] = (array(
'id_customer' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'align' => 'center', 'width' => 25),
'id_gender' => array('title' => $this->trans('Social title', array(), 'Admin.Global'), 'align' => 'center', 'icon' => $genders_icon, 'list' => $genders, 'width' => 25),
'firstname' => array('title' => $this->trans('First name', array(), 'Admin.Global'), 'align' => 'left', 'width' => 150),
'lastname' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'align' => 'left', 'width' => 'auto'),
'email' => array('title' => $this->trans('Email address', array(), 'Admin.Global'), 'align' => 'left', 'width' => 250),
'company' => array('title' => $this->trans('Company', array(), 'Admin.Global'), 'align' => 'left', 'width' => 150),
'birthday' => array('title' => $this->trans('Birth date', array(), 'Admin.Global'), 'align' => 'center', 'type' => 'date', 'width' => 75),
'date_add' => array('title' => $this->trans('Registration date', array(), 'Admin.Shopparameters.Feature'), 'align' => 'center', 'type' => 'date', 'width' => 75),
'orders' => array('title' => $this->trans('Orders', array(), 'Admin.Global'), 'align' => 'center', 'width' => 50),
'active' => array('title' => $this->trans('Enabled', array(), 'Admin.Global'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'width' => 25),
));
}
protected function initProductList()
{
$this->show_toolbar = false;
$this->fields_list['products'] = array(
'id_product' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'width' => 25),
'manufacturer_name' => array('title' => $this->trans('Brand', array(), 'Admin.Global'), 'align' => 'center', 'width' => 200),
'reference' => array('title' => $this->trans('Reference', array(), 'Admin.Global'), 'align' => 'center', 'width' => 150),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'width' => 'auto'),
'price_tax_excl' => array('title' => $this->trans('Price (tax excl.)', array(), 'Admin.Catalog.Feature'), 'align' => 'right', 'type' => 'price', 'width' => 60),
'price_tax_incl' => array('title' => $this->trans('Price (tax incl.)', array(), 'Admin.Catalog.Feature'), 'align' => 'right', 'type' => 'price', 'width' => 60),
'active' => array('title' => $this->trans('Active', array(), 'Admin.Global'), 'width' => 70, 'active' => 'status', 'align' => 'center', 'type' => 'bool'),
);
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryPlugin('highlight');
}
/* Override because we don't want any buttons */
public function initToolbar()
{
}
public function initToolbarTitle()
{
$this->toolbar_title = $this->trans('Search results', array(), 'Admin.Global');
}
public function renderView()
{
$this->tpl_view_vars['query'] = Tools::safeOutput($this->query);
$this->tpl_view_vars['show_toolbar'] = true;
if (count($this->errors)) {
return parent::renderView();
} else {
$nb_results = 0;
foreach ($this->_list as $list) {
if ($list != false) {
$nb_results += count($list);
}
}
$this->tpl_view_vars['nb_results'] = $nb_results;
if ($this->isCountableAndNotEmpty($this->_list, 'features')) {
$this->tpl_view_vars['features'] = $this->_list['features'];
}
if ($this->isCountableAndNotEmpty($this->_list, 'categories')) {
$categories = array();
foreach ($this->_list['categories'] as $category) {
$categories[] = Tools::getPath(
$this->context->link->getAdminLink('AdminCategories', false),
$category['id_category']
);
}
$this->tpl_view_vars['categories'] = $categories;
}
if ($this->isCountableAndNotEmpty($this->_list, 'products')) {
$view = '';
$this->initProductList();
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->simple_header = true;
$helper->identifier = 'id_product';
$helper->actions = array('edit');
$helper->show_toolbar = false;
$helper->table = 'product';
/* 1.6 code compatibility, as we use HelperList, we need to handle click to go to product, a better way need to be find */
$helper->currentIndex = $this->context->link->getAdminLink('AdminSearch', false);
$helper->currentIndex .= '&action=redirectToProduct';
$query = trim(Tools::getValue('bo_query'));
$searchType = (int) Tools::getValue('bo_search_type');
if ($query) {
$helper->currentIndex .= '&bo_query=' . $query . '&bo_search_type=' . $searchType;
}
$helper->token = Tools::getAdminTokenLite('AdminSearch');
if ($this->_list['products']) {
$view = $helper->generateList($this->_list['products'], $this->fields_list['products']);
}
$this->tpl_view_vars['products'] = $view;
$this->tpl_view_vars['productsCount'] = count($this->_list['products']);
}
if ($this->isCountableAndNotEmpty($this->_list, 'customers')) {
$view = '';
$this->initCustomerList();
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->simple_header = true;
$helper->identifier = 'id_customer';
$helper->actions = array('edit', 'view');
$helper->show_toolbar = false;
$helper->table = 'customer';
$helper->currentIndex = $this->context->link->getAdminLink('AdminCustomers', false);
$helper->token = Tools::getAdminTokenLite('AdminCustomers');
foreach ($this->_list['customers'] as $key => $val) {
$this->_list['customers'][$key]['orders'] = Order::getCustomerNbOrders((int) $val['id_customer']);
}
$view = $helper->generateList($this->_list['customers'], $this->fields_list['customers']);
$this->tpl_view_vars['customers'] = $view;
$this->tpl_view_vars['customerCount'] = count($this->_list['customers']);
}
if ($this->isCountableAndNotEmpty($this->_list, 'orders')) {
$view = '';
$this->initOrderList();
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->simple_header = true;
$helper->identifier = 'id_order';
$helper->actions = array('view');
$helper->show_toolbar = false;
$helper->table = 'order';
$helper->currentIndex = $this->context->link->getAdminLink('AdminOrders', false);
$helper->token = Tools::getAdminTokenLite('AdminOrders');
$view = $helper->generateList($this->_list['orders'], $this->fields_list['orders']);
$this->tpl_view_vars['orders'] = $view;
$this->tpl_view_vars['orderCount'] = count($this->_list['orders']);
}
if ($this->isCountableAndNotEmpty($this->_list, 'modules')) {
$this->tpl_view_vars['modules'] = $this->_list['modules'];
}
if ($this->isCountableAndNotEmpty($this->_list, 'addons')) {
$this->tpl_view_vars['addons'] = $this->_list['addons'];
}
return parent::renderView();
}
}
/**
* Check if key is present in array, is countable and has data.
*
* @param array $array Array
* @param string $key Key
*
* @return bool
*/
protected function isCountableAndNotEmpty(array $array, $key)
{
return isset($array[$key]) &&
is_countable($array[$key]) &&
count($array[$key]);
}
/**
* Request triggering the search indexation.
*
* Kept as GET request for backward compatibility purpose, but should be modified as POST when migrated.
* NOTE the token is different for that method, check the method checkToken() for more details.
*/
public function displayAjaxSearchCron()
{
if (!Tools::getValue('id_shop')) {
Context::getContext()->shop->setContext(Shop::CONTEXT_ALL);
} else {
Context::getContext()->shop->setContext(Shop::CONTEXT_SHOP, (int) Tools::getValue('id_shop'));
}
// Considering the indexing task can be really long, we ask the PHP process to not stop before 2 hours.
ini_set('max_execution_time', 7200);
Search::indexation(Tools::getValue('full'));
if (Tools::getValue('redirect')) {
Tools::redirectAdmin($_SERVER['HTTP_REFERER'] . '&conf=4');
}
}
/**
* Check if a task is a cron task
*
* @return bool
*/
protected function isCronTask()
{
return Tools::isSubmit('action') && 'searchCron' === Tools::getValue('action');
}
}

View File

@@ -0,0 +1,102 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property SearchEngine $object
*/
class AdminSearchEnginesControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'search_engine';
$this->className = 'SearchEngine';
$this->lang = false;
parent::__construct();
$this->addRowAction('edit');
$this->addRowAction('delete');
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'id_search_engine' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'width' => 25),
'server' => array('title' => $this->trans('Server', array(), 'Admin.Shopparameters.Feature')),
'getvar' => array('title' => $this->trans('GET variable', array(), 'Admin.Shopparameters.Feature'), 'width' => 100),
);
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Referrer', array(), 'Admin.Shopparameters.Feature'),
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Server', array(), 'Admin.Shopparameters.Feature'),
'name' => 'server',
'size' => 20,
'required' => true,
),
array(
'type' => 'text',
'label' => $this->trans('$_GET variable', array(), 'Admin.Shopparameters.Feature'),
'name' => 'getvar',
'size' => 40,
'required' => true,
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_search_engine'] = array(
'href' => self::$currentIndex . '&addsearch_engine&token=' . $this->token,
'desc' => $this->trans('Add new search engine', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
}
$this->identifier_name = 'server';
parent::initPageHeaderToolbar();
}
}

View File

@@ -0,0 +1,864 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder;
class AdminShopControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'shop';
$this->className = 'Shop';
$this->multishop_context = Shop::CONTEXT_ALL;
parent::__construct();
$this->id_shop_group = (int) Tools::getValue('id_shop_group');
/* if $_GET['id_shop'] is transmitted, virtual url can be loaded in config.php, so we wether transmit shop_id in herfs */
if ($this->id_shop = (int) Tools::getValue('shop_id')) {
$_GET['id_shop'] = $this->id_shop;
}
$this->list_skip_actions['delete'] = array((int) Configuration::get('PS_SHOP_DEFAULT'));
$this->fields_list = array(
'id_shop' => array(
'title' => $this->trans('Shop ID', array(), 'Admin.Shopparameters.Feature'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Shop name', array(), 'Admin.Shopparameters.Feature'),
'filter_key' => 'a!name',
'width' => 200,
),
'shop_group_name' => array(
'title' => $this->trans('Shop group', array(), 'Admin.Shopparameters.Feature'),
'width' => 150,
'filter_key' => 'gs!name',
),
'category_name' => array(
'title' => $this->trans('Root category', array(), 'Admin.Shopparameters.Feature'),
'width' => 150,
'filter_key' => 'cl!name',
),
'url' => array(
'title' => $this->trans('Main URL for this shop', array(), 'Admin.Shopparameters.Feature'),
'havingFilter' => 'url',
),
);
}
public function getTabSlug()
{
return 'ROLE_MOD_TAB_ADMINSHOPGROUP_';
}
public function viewAccess($disable = false)
{
return Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE');
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
if (!$this->display && $this->id_shop_group) {
if ($this->id_object) {
$this->loadObject();
}
if (!$this->id_shop_group && $this->object && $this->object->id_shop_group) {
$this->id_shop_group = $this->object->id_shop_group;
}
$this->page_header_toolbar_btn['edit'] = array(
'desc' => $this->trans('Edit this shop group', array(), 'Admin.Shopparameters.Feature'),
'href' => $this->context->link->getAdminLink('AdminShopGroup') . '&updateshop_group&id_shop_group='
. $this->id_shop_group,
);
$this->page_header_toolbar_btn['new'] = array(
'desc' => $this->trans('Add new shop', array(), 'Admin.Shopparameters.Feature'),
'href' => $this->context->link->getAdminLink('AdminShop') . '&add' . $this->table . '&id_shop_group='
. $this->id_shop_group,
);
}
}
public function initToolbar()
{
parent::initToolbar();
if ($this->display != 'edit' && $this->display != 'add') {
if ($this->id_object) {
$this->loadObject();
}
if (!$this->id_shop_group && $this->object && $this->object->id_shop_group) {
$this->id_shop_group = $this->object->id_shop_group;
}
$this->toolbar_btn['new'] = array(
'desc' => $this->trans('Add new shop', array(), 'Admin.Shopparameters.Feature'),
'href' => $this->context->link->getAdminLink('AdminShop') . '&add' . $this->table . '&id_shop_group='
. $this->id_shop_group,
);
}
}
public function initContent()
{
parent::initContent();
$this->addJqueryPlugin('cooki-plugin');
$data = Shop::getTree();
foreach ($data as &$group) {
foreach ($group['shops'] as &$shop) {
$current_shop = new Shop($shop['id_shop']);
$urls = $current_shop->getUrls();
foreach ($urls as &$url) {
$title = $url['domain'] . $url['physical_uri'] . $url['virtual_uri'];
if (strlen($title) > 23) {
$title = substr($title, 0, 23) . '...';
}
$url['name'] = $title;
$shop['urls'][$url['id_shop_url']] = $url;
}
}
}
$shops_tree = new HelperTreeShops('shops-tree', $this->trans('Multistore tree', array(), 'Admin.Shopparameters.Feature'));
$shops_tree->setNodeFolderTemplate('shop_tree_node_folder.tpl')->setNodeItemTemplate('shop_tree_node_item.tpl')
->setHeaderTemplate('shop_tree_header.tpl')->setActions(array(
new TreeToolbarLink(
'Collapse All',
'#',
'$(\'#' . $shops_tree->getId() . '\').tree(\'collapseAll\'); return false;',
'icon-collapse-alt'
),
new TreeToolbarLink(
'Expand All',
'#',
'$(\'#' . $shops_tree->getId() . '\').tree(\'expandAll\'); return false;',
'icon-expand-alt'
),
))
->setAttribute('url_shop_group', $this->context->link->getAdminLink('AdminShopGroup'))
->setAttribute('url_shop', $this->context->link->getAdminLink('AdminShop'))
->setAttribute('url_shop_url', $this->context->link->getAdminLink('AdminShopUrl'))
->setData($data);
$shops_tree = $shops_tree->render(null, false, false);
if ($this->display == 'edit') {
$this->toolbar_title[] = $this->object->name;
} elseif (!$this->display && $this->id_shop_group) {
$group = new ShopGroup($this->id_shop_group);
$this->toolbar_title[] = $group->name;
}
$this->context->smarty->assign(array(
'toolbar_scroll' => 1,
'toolbar_btn' => $this->toolbar_btn,
'title' => $this->toolbar_title,
'shops_tree' => $shops_tree,
));
}
public function renderList()
{
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_select = 'gs.name shop_group_name, cl.name category_name, CONCAT(\'http://\', su.domain, su.physical_uri, su.virtual_uri) AS url';
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'shop_group` gs
ON (a.id_shop_group = gs.id_shop_group)
LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl
ON (a.id_category = cl.id_category AND cl.id_lang=' . (int) $this->context->language->id . ')
LEFT JOIN ' . _DB_PREFIX_ . 'shop_url su
ON a.id_shop = su.id_shop AND su.main = 1
';
$this->_group = 'GROUP BY a.id_shop';
if ($id_shop_group = (int) Tools::getValue('id_shop_group')) {
$this->_where = 'AND a.id_shop_group = ' . $id_shop_group;
}
return parent::renderList();
}
public function displayAjaxGetCategoriesFromRootCategory()
{
if (Tools::isSubmit('id_category')) {
$selected_cat = array((int) Tools::getValue('id_category'));
$children = Category::getChildren((int) Tools::getValue('id_category'), $this->context->language->id);
foreach ($children as $child) {
$selected_cat[] = $child['id_category'];
}
$helper = new HelperTreeCategories('categories-tree', null, (int) Tools::getValue('id_category'), null, false);
$this->content = $helper->setSelectedCategories($selected_cat)->setUseSearch(true)->setUseCheckBox(true)
->render();
}
parent::displayAjax();
}
public function postProcess()
{
if (Tools::isSubmit('id_category_default')) {
$_POST['id_category'] = Tools::getValue('id_category_default');
}
if (Tools::isSubmit('submitAddshopAndStay') || Tools::isSubmit('submitAddshop')) {
$shop_group = new ShopGroup((int) Tools::getValue('id_shop_group'));
if ($shop_group->shopNameExists(Tools::getValue('name'), (int) Tools::getValue('id_shop'))) {
$this->errors[] = $this->trans('You cannot have two shops with the same name in the same group.', array(), 'Admin.Advparameters.Notification');
}
}
if (count($this->errors)) {
return false;
}
/** @var Shop|bool $result */
$result = parent::postProcess();
if ($result != false && (Tools::isSubmit('submitAddshopAndStay') || Tools::isSubmit('submitAddshop')) && (int) $result->id_category != (int) Configuration::get('PS_HOME_CATEGORY', null, null, (int) $result->id)) {
Configuration::updateValue('PS_HOME_CATEGORY', (int) $result->id_category, false, null, (int) $result->id);
}
if ($this->redirect_after) {
$this->redirect_after .= '&id_shop_group=' . $this->id_shop_group;
}
return $result;
}
public function processDelete()
{
if (!Validate::isLoadedObject($object = $this->loadObject())) {
$this->errors[] = $this->trans('Unable to load this shop.', array(), 'Admin.Advparameters.Notification');
} elseif (!Shop::hasDependency($object->id)) {
$result = Category::deleteCategoriesFromShop($object->id) && parent::processDelete();
Tools::generateHtaccess();
return $result;
} else {
$this->errors[] = $this->trans('You cannot delete this shop (customer and/or order dependency).', array(), 'Admin.Shopparameters.Notification');
}
return false;
}
/**
* @param Shop $new_shop
*
* @return bool
*/
protected function afterAdd($new_shop)
{
$import_data = Tools::getValue('importData', array());
// The root category should be at least imported
$new_shop->copyShopData((int) Tools::getValue('importFromShop'), $import_data);
// copy default data
if (!Tools::getValue('useImportData') || (is_array($import_data) && !isset($import_data['group']))) {
$sql = 'INSERT INTO `' . _DB_PREFIX_ . 'group_shop` (`id_shop`, `id_group`)
VALUES
(' . (int) $new_shop->id . ', ' . (int) Configuration::get('PS_UNIDENTIFIED_GROUP') . '),
(' . (int) $new_shop->id . ', ' . (int) Configuration::get('PS_GUEST_GROUP') . '),
(' . (int) $new_shop->id . ', ' . (int) Configuration::get('PS_CUSTOMER_GROUP') . ')
';
Db::getInstance()->execute($sql);
}
return parent::afterAdd($new_shop);
}
/**
* @param Shop $new_shop
*
* @return bool
*/
protected function afterUpdate($new_shop)
{
$categories = Tools::getValue('categoryBox');
if (!is_array($categories)) {
$this->errors[] = $this->trans('Please create some sub-categories for this root category.', array(), 'Admin.Shopparameters.Notification');
return false;
}
array_unshift($categories, Configuration::get('PS_ROOT_CATEGORY'));
if (!Category::updateFromShop($categories, $new_shop->id)) {
$this->errors[] = $this->trans('You need to select at least the root category.', array(), 'Admin.Shopparameters.Notification');
}
if (Tools::getValue('useImportData') && ($import_data = Tools::getValue('importData')) && is_array($import_data)) {
$new_shop->copyShopData((int) Tools::getValue('importFromShop'), $import_data);
}
if (Tools::isSubmit('submitAddshopAndStay') || Tools::isSubmit('submitAddshop')) {
$this->redirect_after = self::$currentIndex . '&shop_id=' . (int) $new_shop->id . '&conf=4&token=' . $this->token;
}
return parent::afterUpdate($new_shop);
}
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
if (Shop::getContext() == Shop::CONTEXT_GROUP) {
$this->_where .= ' AND a.id_shop_group = ' . (int) Shop::getContextShopGroupID();
}
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
$shop_delete_list = array();
// don't allow to remove shop which have dependencies (customers / orders / ... )
foreach ($this->_list as &$shop) {
if (Shop::hasDependency($shop['id_shop'])) {
$shop_delete_list[] = $shop['id_shop'];
}
}
$this->context->smarty->assign('shops_having_dependencies', $shop_delete_list);
}
public function renderForm()
{
/** @var Shop $obj */
if (!($obj = $this->loadObject(true))) {
return;
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Shop', array(), 'Admin.Global'),
'icon' => 'icon-shopping-cart',
),
'identifier' => 'shop_id',
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Shop name', array(), 'Admin.Shopparameters.Feature'),
'desc' => array(
$this->trans('This field does not refer to the shop name visible in the front office.', array(), 'Admin.Shopparameters.Help'),
$this->trans('Follow [1]this link[/1] to edit the shop name used on the front office.', array(
'[1]' => '<a href="' . $this->context->link->getAdminLink('AdminStores') . '#store_fieldset_general">',
'[/1]' => '</a>',
), 'Admin.Shopparameters.Help'), ),
'name' => 'name',
'required' => true,
),
),
);
$display_group_list = true;
if ($this->display == 'edit') {
$group = new ShopGroup($obj->id_shop_group);
if ($group->share_customer || $group->share_order || $group->share_stock) {
$display_group_list = false;
}
}
if ($display_group_list) {
$options = array();
foreach (ShopGroup::getShopGroups() as $group) {
/** @var ShopGroup $group */
if ($this->display == 'edit' && ($group->share_customer || $group->share_order || $group->share_stock) && ShopGroup::hasDependency($group->id)) {
continue;
}
$options[] = array(
'id_shop_group' => $group->id,
'name' => $group->name,
);
}
if ($this->display == 'add') {
$group_desc = $this->trans('Warning: You won\'t be able to change the group of this shop if this shop belongs to a group with one of these options activated: Share Customers, Share Quantities or Share Orders.', array(), 'Admin.Shopparameters.Notification');
} else {
$group_desc = $this->trans('You can only move your shop to a shop group with all "share" options disabled -- or to a shop group with no customers/orders.', array(), 'Admin.Shopparameters.Notification');
}
$this->fields_form['input'][] = array(
'type' => 'select',
'label' => $this->trans('Shop group', array(), 'Admin.Shopparameters.Feature'),
'desc' => $group_desc,
'name' => 'id_shop_group',
'options' => array(
'query' => $options,
'id' => 'id_shop_group',
'name' => 'name',
),
);
} else {
$this->fields_form['input'][] = array(
'type' => 'hidden',
'name' => 'id_shop_group',
'default' => $group->name,
);
$this->fields_form['input'][] = array(
'type' => 'textShopGroup',
'label' => $this->trans('Shop group', array(), 'Admin.Shopparameters.Feature'),
'desc' => $this->trans('You can\'t edit the shop group because the current shop belongs to a group with the "share" option enabled.', array(), 'Admin.Shopparameters.Help'),
'name' => 'id_shop_group',
'value' => $group->name,
);
}
$categories = Category::getRootCategories($this->context->language->id);
$this->fields_form['input'][] = array(
'type' => 'select',
'label' => $this->trans('Category root', array(), 'Admin.Catalog.Feature'),
'desc' => $this->trans('This is the root category of the store that you\'ve created. To define a new root category for your store, [1]please click here[/1].', array(
'[1]' => '<a href="' . $this->context->link->getAdminLink('AdminCategories') . '&addcategoryroot" target="_blank">',
'[/1]' => '</a>',
), 'Admin.Shopparameters.Help'),
'name' => 'id_category',
'options' => array(
'query' => $categories,
'id' => 'id_category',
'name' => 'name',
),
);
if (Tools::isSubmit('id_shop')) {
$shop = new Shop((int) Tools::getValue('id_shop'));
$id_root = $shop->id_category;
} else {
$id_root = $categories[0]['id_category'];
}
$id_shop = (int) Tools::getValue('id_shop');
self::$currentIndex = self::$currentIndex . '&id_shop_group=' . (int) (Tools::getValue('id_shop_group') ?
Tools::getValue('id_shop_group') : (isset($obj->id_shop_group) ? $obj->id_shop_group : Shop::getContextShopGroupID()));
$shop = new Shop($id_shop);
$selected_cat = Shop::getCategories($id_shop);
if (empty($selected_cat)) {
// get first category root and preselect all these children
$root_categories = Category::getRootCategories();
$root_category = new Category($root_categories[0]['id_category']);
$children = $root_category->getAllChildren($this->context->language->id);
$selected_cat[] = $root_categories[0]['id_category'];
foreach ($children as $child) {
$selected_cat[] = $child->id;
}
}
if (Shop::getContext() == Shop::CONTEXT_SHOP && Tools::isSubmit('id_shop')) {
$root_category = new Category($shop->id_category);
} else {
$root_category = new Category($id_root);
}
$this->fields_form['input'][] = array(
'type' => 'categories',
'name' => 'categoryBox',
'label' => $this->trans('Associated categories', array(), 'Admin.Catalog.Feature'),
'tree' => array(
'id' => 'categories-tree',
'selected_categories' => $selected_cat,
'root_category' => $root_category->id,
'use_search' => true,
'use_checkbox' => true,
),
'desc' => $this->trans('By selecting associated categories, you are choosing to share the categories between shops. Once associated between shops, any alteration of this category will impact every shop.', array(), 'Admin.Shopparameters.Help'),
);
/*$this->fields_form['input'][] = array(
'type' => 'switch',
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
'name' => 'active',
'required' => true,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1
),
array(
'id' => 'active_off',
'value' => 0
)
),
'desc' => $this->trans('Enable or disable your store?', array(), 'Admin.Shopparameters.Help')
);*/
$themes = (new ThemeManagerBuilder($this->context, Db::getInstance()))
->buildRepository()
->getList();
$this->fields_form['input'][] = array(
'type' => 'theme',
'label' => $this->trans('Theme', array(), 'Admin.Design.Feature'),
'name' => 'theme',
'values' => $themes,
);
$this->fields_form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
if (Shop::getTotalShops() > 1 && $obj->id) {
$disabled = array('active' => false);
} else {
$disabled = false;
}
$import_data = array(
'carrier' => $this->trans('Carriers', array(), 'Admin.Shipping.Feature'),
'cms' => $this->trans('Pages', array(), 'Admin.Design.Feature'),
'contact' => $this->trans('Contact information', array(), 'Admin.Advparameters.Feature'),
'country' => $this->trans('Countries', array(), 'Admin.Global'),
'currency' => $this->trans('Currencies', array(), 'Admin.Global'),
'discount' => $this->trans('Discount prices', array(), 'Admin.Advparameters.Feature'),
'employee' => $this->trans('Employees', array(), 'Admin.Advparameters.Feature'),
'image' => $this->trans('Images', array(), 'Admin.Global'),
'lang' => $this->trans('Languages', array(), 'Admin.Global'),
'manufacturer' => $this->trans('Brands', array(), 'Admin.Global'),
'module' => $this->trans('Modules', array(), 'Admin.Global'),
'hook_module' => $this->trans('Module hooks', array(), 'Admin.Advparameters.Feature'),
'meta_lang' => $this->trans('Meta information', array(), 'Admin.Advparameters.Feature'),
'product' => $this->trans('Products', array(), 'Admin.Global'),
'product_attribute' => $this->trans('Product combinations', array(), 'Admin.Advparameters.Feature'),
'stock_available' => $this->trans('Available quantities for sale', array(), 'Admin.Advparameters.Feature'),
'store' => $this->trans('Stores', array(), 'Admin.Global'),
'warehouse' => $this->trans('Warehouses', array(), 'Admin.Advparameters.Feature'),
'webservice_account' => $this->trans('Webservice accounts', array(), 'Admin.Advparameters.Feature'),
'attribute_group' => $this->trans('Attribute groups', array(), 'Admin.Advparameters.Feature'),
'feature' => $this->trans('Features', array(), 'Admin.Global'),
'group' => $this->trans('Customer groups', array(), 'Admin.Advparameters.Feature'),
'tax_rules_group' => $this->trans('Tax rules groups', array(), 'Admin.Advparameters.Feature'),
'supplier' => $this->trans('Suppliers', array(), 'Admin.Global'),
'referrer' => $this->trans('Referrers/affiliates', array(), 'Admin.Advparameters.Feature'),
'zone' => $this->trans('Zones', array(), 'Admin.International.Feature'),
'cart_rule' => $this->trans('Cart rules', array(), 'Admin.Advparameters.Feature'),
);
// Hook for duplication of shop data
$modules_list = Hook::getHookModuleExecList('actionShopDataDuplication');
if (is_array($modules_list) && count($modules_list) > 0) {
foreach ($modules_list as $m) {
$import_data['Module' . ucfirst($m['module'])] = Module::getModuleName($m['module']);
}
}
asort($import_data);
if (!$this->object->id) {
$this->fields_import_form = array(
'radio' => array(
'type' => 'radio',
'label' => $this->trans('Import data', array(), 'Admin.Advparameters.Feature'),
'name' => 'useImportData',
'value' => 1,
),
'select' => array(
'type' => 'select',
'name' => 'importFromShop',
'label' => $this->trans('Choose the source shop', array(), 'Admin.Advparameters.Feature'),
'options' => array(
'query' => Shop::getShops(false),
'name' => 'name',
),
),
'allcheckbox' => array(
'type' => 'checkbox',
'label' => $this->trans('Choose data to import', array(), 'Admin.Advparameters.Feature'),
'values' => $import_data,
),
'desc' => $this->trans('Use this option to associate data (products, modules, etc.) the same way for each selected shop.', array(), 'Admin.Advparameters.Help'),
);
}
if (!$obj->theme_name) {
$themes = (new ThemeManagerBuilder($this->context, Db::getInstance()))
->buildRepository()
->getList();
$theme = array_pop($themes);
$theme_name = $theme->getName();
} else {
$theme_name = $obj->theme_name;
}
$this->fields_value = array(
'id_shop_group' => (Tools::getValue('id_shop_group') ? Tools::getValue('id_shop_group') :
(isset($obj->id_shop_group)) ? $obj->id_shop_group : Shop::getContextShopGroupID()),
'id_category' => (Tools::getValue('id_category') ? Tools::getValue('id_category') :
(isset($obj->id_category)) ? $obj->id_category : (int) Configuration::get('PS_HOME_CATEGORY')),
'theme_name' => $theme_name,
);
$ids_category = array();
$shops = Shop::getShops(false);
foreach ($shops as $shop) {
$ids_category[$shop['id_shop']] = $shop['id_category'];
}
$this->tpl_form_vars = array(
'disabled' => $disabled,
'checked' => (Tools::getValue('addshop') !== false) ? true : false,
'defaultShop' => (int) Configuration::get('PS_SHOP_DEFAULT'),
'ids_category' => $ids_category,
);
if (isset($this->fields_import_form)) {
$this->tpl_form_vars = array_merge($this->tpl_form_vars, array('form_import' => $this->fields_import_form));
}
return parent::renderForm();
}
/**
* Object creation.
*/
public function processAdd()
{
if (!Tools::getValue('categoryBox') || !in_array(Tools::getValue('id_category'), Tools::getValue('categoryBox'))) {
$this->errors[] = $this->trans('You need to select at least the root category.', array(), 'Admin.Advparameters.Notification');
}
if (Tools::isSubmit('id_category_default')) {
$_POST['id_category'] = (int) Tools::getValue('id_category_default');
}
/* Checking fields validity */
$this->validateRules();
if (!count($this->errors)) {
/** @var Shop $object */
$object = new $this->className();
$this->copyFromPost($object, $this->table);
$this->beforeAdd($object);
if (!$object->add()) {
$this->errors[] = $this->trans('An error occurred while creating an object.', array(), 'Admin.Notifications.Error') .
' <b>' . $this->table . ' (' . Db::getInstance()->getMsgError() . ')</b>';
} elseif (($_POST[$this->identifier] = $object->id) && $this->postImage($object->id) && !count($this->errors) && $this->_redirect) {
// voluntary do affectation here
$parent_id = (int) Tools::getValue('id_parent', 1);
$this->afterAdd($object);
$this->updateAssoShop($object->id);
// Save and stay on same form
if (Tools::isSubmit('submitAdd' . $this->table . 'AndStay')) {
$this->redirect_after = self::$currentIndex . '&shop_id=' . (int) $object->id . '&conf=3&update' . $this->table . '&token=' . $this->token;
}
// Save and back to parent
if (Tools::isSubmit('submitAdd' . $this->table . 'AndBackToParent')) {
$this->redirect_after = self::$currentIndex . '&shop_id=' . (int) $parent_id . '&conf=3&token=' . $this->token;
}
// Default behavior (save and back)
if (empty($this->redirect_after)) {
$this->redirect_after = self::$currentIndex . ($parent_id ? '&shop_id=' . $object->id : '') . '&conf=3&token=' . $this->token;
}
}
}
$this->errors = array_unique($this->errors);
if (count($this->errors) > 0) {
$this->display = 'add';
return;
}
$object->associateSuperAdmins();
$categories = Tools::getValue('categoryBox');
array_unshift($categories, Configuration::get('PS_ROOT_CATEGORY'));
Category::updateFromShop($categories, $object->id);
if (Tools::getValue('useImportData') && ($import_data = Tools::getValue('importData')) && is_array($import_data) && isset($import_data['product'])) {
ini_set('max_execution_time', 7200); // like searchcron.php
Search::indexation(true);
}
return $object;
}
public function displayEditLink($token, $id, $name = null)
{
if ($this->access('edit')) {
$tpl = $this->createTemplate('helpers/list/list_action_edit.tpl');
if (!array_key_exists('Edit', self::$cache_lang)) {
self::$cache_lang['Edit'] = $this->trans('Edit', array(), 'Admin.Actions');
}
$tpl->assign(array(
'href' => $this->context->link->getAdminLink('AdminShop') . '&shop_id=' . (int) $id . '&update' . $this->table,
'action' => self::$cache_lang['Edit'],
'id' => $id,
));
return $tpl->fetch();
} else {
return;
}
}
public function initCategoriesAssociation($id_root = null)
{
if (null === $id_root) {
$id_root = Configuration::get('PS_ROOT_CATEGORY');
}
$id_shop = (int) Tools::getValue('id_shop');
$shop = new Shop($id_shop);
$selected_cat = Shop::getCategories($id_shop);
if (empty($selected_cat)) {
// get first category root and preselect all these children
$root_categories = Category::getRootCategories();
$root_category = new Category($root_categories[0]['id_category']);
$children = $root_category->getAllChildren($this->context->language->id);
$selected_cat[] = $root_categories[0]['id_category'];
foreach ($children as $child) {
$selected_cat[] = $child->id;
}
}
if (Shop::getContext() == Shop::CONTEXT_SHOP && Tools::isSubmit('id_shop')) {
$root_category = new Category($shop->id_category);
} else {
$root_category = new Category($id_root);
}
$root_category = array('id_category' => $root_category->id, 'name' => $root_category->name[$this->context->language->id]);
$helper = new Helper();
return $helper->renderCategoryTree($root_category, $selected_cat, 'categoryBox', false, true);
}
public function ajaxProcessTree()
{
$tree = array();
$sql = 'SELECT g.id_shop_group, g.name as group_name, s.id_shop, s.name as shop_name, u.id_shop_url, u.domain, u.physical_uri, u.virtual_uri
FROM ' . _DB_PREFIX_ . 'shop_group g
LEFT JOIN ' . _DB_PREFIX_ . 'shop s ON g.id_shop_group = s.id_shop_group
LEFT JOIN ' . _DB_PREFIX_ . 'shop_url u ON u.id_shop = s.id_shop
ORDER BY g.name, s.name, u.domain';
$results = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
foreach ($results as $row) {
$id_shop_group = $row['id_shop_group'];
$id_shop = $row['id_shop'];
$id_shop_url = $row['id_shop_url'];
// Group list
if (!isset($tree[$id_shop_group])) {
$tree[$id_shop_group] = array(
'data' => array(
'title' => '<b>' . $this->trans('Group', array(), 'Admin.Global') . '</b> ' . $row['group_name'],
'icon' => 'themes/' . $this->context->employee->bo_theme . '/img/tree-multishop-groups.png',
'attr' => array(
'href' => $this->context->link->getAdminLink('AdminShop') . '&id_shop_group=' . $id_shop_group,
'title' => $this->trans('Click here to display the shops in the %name% shop group', array('%name%' => $row['group_name']), 'Admin.Advparameters.Help'),
),
),
'attr' => array(
'id' => 'tree-group-' . $id_shop_group,
),
'children' => array(),
);
}
// Shop list
if (!$id_shop) {
continue;
}
if (!isset($tree[$id_shop_group]['children'][$id_shop])) {
$tree[$id_shop_group]['children'][$id_shop] = array(
'data' => array(
'title' => $row['shop_name'],
'icon' => 'themes/' . $this->context->employee->bo_theme . '/img/tree-multishop-shop.png',
'attr' => array(
'href' => $this->context->link->getAdminLink('AdminShopUrl') . '&shop_id=' . (int) $id_shop,
'title' => $this->trans('Click here to display the URLs of the %name% shop', array('%name%' => $row['shop_name']), 'Admin.Advparameters.Help'),
),
),
'attr' => array(
'id' => 'tree-shop-' . $id_shop,
),
'children' => array(),
);
}
// Url list
if (!$id_shop_url) {
continue;
}
if (!isset($tree[$id_shop_group]['children'][$id_shop]['children'][$id_shop_url])) {
$url = $row['domain'] . $row['physical_uri'] . $row['virtual_uri'];
if (strlen($url) > 23) {
$url = substr($url, 0, 23) . '...';
}
$tree[$id_shop_group]['children'][$id_shop]['children'][$id_shop_url] = array(
'data' => array(
'title' => $url,
'icon' => 'themes/' . $this->context->employee->bo_theme . '/img/tree-multishop-url.png',
'attr' => array(
'href' => $this->context->link->getAdminLink('AdminShopUrl') . '&updateshop_url&id_shop_url=' . $id_shop_url,
'title' => $row['domain'] . $row['physical_uri'] . $row['virtual_uri'],
),
),
'attr' => array(
'id' => 'tree-url-' . $id_shop_url,
),
);
}
}
// jstree need to have children as array and not object, so we use sort to get clean keys
// DO NOT REMOVE this code, even if it seems really strange ;)
sort($tree);
foreach ($tree as &$groups) {
sort($groups['children']);
foreach ($groups['children'] as &$shops) {
sort($shops['children']);
}
}
$tree = array(array(
'data' => array(
'title' => '<b>' . $this->trans('Shop groups list', array(), 'Admin.Advparameters.Feature') . '</b>',
'icon' => 'themes/' . $this->context->employee->bo_theme . '/img/tree-multishop-root.png',
'attr' => array(
'href' => $this->context->link->getAdminLink('AdminShopGroup'),
'title' => $this->trans('Click here to display the list of shop groups', array(), 'Admin.Advparameters.Help'),
),
),
'attr' => array(
'id' => 'tree-root',
),
'state' => 'open',
'children' => $tree,
));
die(json_encode($tree));
}
}

View File

@@ -0,0 +1,364 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property ShopGroup $object
*/
class AdminShopGroupControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'shop_group';
$this->className = 'ShopGroup';
$this->lang = false;
$this->multishop_context = Shop::CONTEXT_ALL;
$this->addRowAction('edit');
$this->addRowAction('delete');
parent::__construct();
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
$this->show_toolbar = false;
$this->fields_list = array(
'id_shop_group' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Shop group', array(), 'Admin.Advparameters.Feature'),
'width' => 'auto',
'filter_key' => 'a!name',
),
);
$this->fields_options = array(
'general' => array(
'title' => $this->trans('Multistore options', array(), 'Admin.Advparameters.Feature'),
'fields' => array(
'PS_SHOP_DEFAULT' => array(
'title' => $this->trans('Default shop', array(), 'Admin.Advparameters.Feature'),
'cast' => 'intval',
'type' => 'select',
'identifier' => 'id_shop',
'list' => Shop::getShops(),
'visibility' => Shop::CONTEXT_ALL,
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
}
public function viewAccess($disable = false)
{
return Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE');
}
public function initContent()
{
parent::initContent();
$this->addJqueryPlugin('cooki-plugin');
$data = Shop::getTree();
foreach ($data as $key_group => &$group) {
foreach ($group['shops'] as $key_shop => &$shop) {
$current_shop = new Shop($shop['id_shop']);
$urls = $current_shop->getUrls();
foreach ($urls as $key_url => &$url) {
$title = $url['domain'] . $url['physical_uri'] . $url['virtual_uri'];
if (strlen($title) > 23) {
$title = substr($title, 0, 23) . '...';
}
$url['name'] = $title;
$shop['urls'][$url['id_shop_url']] = $url;
}
}
}
$shops_tree = new HelperTreeShops('shops-tree', $this->trans('Multistore tree', array(), 'Admin.Advparameters.Feature'));
$shops_tree->setNodeFolderTemplate('shop_tree_node_folder.tpl')->setNodeItemTemplate('shop_tree_node_item.tpl')
->setHeaderTemplate('shop_tree_header.tpl')->setActions(array(
new TreeToolbarLink(
'Collapse All',
'#',
'$(\'#' . $shops_tree->getId() . '\').tree(\'collapseAll\'); return false;',
'icon-collapse-alt'
),
new TreeToolbarLink(
'Expand All',
'#',
'$(\'#' . $shops_tree->getId() . '\').tree(\'expandAll\'); return false;',
'icon-expand-alt'
),
))
->setAttribute('url_shop_group', $this->context->link->getAdminLink('AdminShopGroup'))
->setAttribute('url_shop', $this->context->link->getAdminLink('AdminShop'))
->setAttribute('url_shop_url', $this->context->link->getAdminLink('AdminShopUrl'))
->setData($data);
$shops_tree = $shops_tree->render(null, false, false);
if ($this->display == 'edit') {
$this->toolbar_title[] = $this->object->name;
}
$this->context->smarty->assign(array(
'toolbar_scroll' => 1,
'toolbar_btn' => $this->toolbar_btn,
'title' => $this->toolbar_title,
'shops_tree' => $shops_tree,
));
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
if ($this->display != 'add' && $this->display != 'edit') {
$this->page_header_toolbar_btn['new'] = array(
'desc' => $this->trans('Add a new shop group', array(), 'Admin.Advparameters.Feature'),
'href' => self::$currentIndex . '&add' . $this->table . '&token=' . $this->token,
);
$this->page_header_toolbar_btn['new_2'] = array(
'desc' => $this->trans('Add a new shop', array(), 'Admin.Advparameters.Feature'),
'href' => $this->context->link->getAdminLink('AdminShop') . '&addshop',
'imgclass' => 'new_2',
'icon' => 'process-icon-new',
);
}
}
public function initToolbar()
{
parent::initToolbar();
if ($this->display != 'add' && $this->display != 'edit') {
$this->toolbar_btn['new'] = array(
'desc' => $this->trans('Add a new shop group', array(), 'Admin.Advparameters.Feature'),
'href' => self::$currentIndex . '&add' . $this->table . '&token=' . $this->token,
);
}
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Shop group', array(), 'Admin.Advparameters.Feature'),
'icon' => 'icon-shopping-cart',
),
'description' => $this->trans('Warning: Enabling the "share customers" and "share orders" options is not recommended. Once activated and orders are created, you will not be able to disable these options. If you need these options, we recommend using several categories rather than several shops.', array(), 'Admin.Advparameters.Help'),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Shop group name', array(), 'Admin.Advparameters.Feature'),
'name' => 'name',
'required' => true,
),
array(
'type' => 'switch',
'label' => $this->trans('Share customers', array(), 'Admin.Advparameters.Feature'),
'name' => 'share_customer',
'required' => true,
'class' => 't',
'is_bool' => true,
'disabled' => ($this->id_object && $this->display == 'edit' && ShopGroup::hasDependency($this->id_object, 'customer')) ? true : false,
'values' => array(
array(
'id' => 'share_customer_on',
'value' => 1,
),
array(
'id' => 'share_customer_off',
'value' => 0,
),
),
'desc' => $this->trans('Once this option is enabled, the shops in this group will share customers. If a customer registers in any one of these shops, the account will automatically be available in the others shops of this group.', array(), 'Admin.Advparameters.Help') . '<br/>' . $this->trans('Warning: you will not be able to disable this option once you have registered customers.', array(), 'Admin.Advparameters.Help'),
),
array(
'type' => 'switch',
'label' => $this->trans('Share available quantities to sell', array(), 'Admin.Advparameters.Feature'),
'name' => 'share_stock',
'required' => true,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'share_stock_on',
'value' => 1,
),
array(
'id' => 'share_stock_off',
'value' => 0,
),
),
'desc' => $this->trans('Share available quantities between shops of this group. When changing this option, all available products quantities will be reset to 0.', array(), 'Admin.Advparameters.Feature'),
),
array(
'type' => 'switch',
'label' => $this->trans('Share orders', array(), 'Admin.Advparameters.Feature'),
'name' => 'share_order',
'required' => true,
'class' => 't',
'is_bool' => true,
'disabled' => ($this->id_object && $this->display == 'edit' && ShopGroup::hasDependency($this->id_object, 'order')) ? true : false,
'values' => array(
array(
'id' => 'share_order_on',
'value' => 1,
),
array(
'id' => 'share_order_off',
'value' => 0,
),
),
'desc' => $this->trans('Once this option is enabled (which is only possible if customers and available quantities are shared among shops), the customer\'s cart will be shared by all shops in this group. This way, any purchase started in one shop will be able to be completed in another shop from the same group.', array(), 'Admin.Advparameters.Help') . '<br/>' . $this->trans('Warning: You will not be able to disable this option once you\'ve started to accept orders.', array(), 'Admin.Advparameters.Help'),
),
array(
'type' => 'switch',
'label' => $this->trans('Status', array(), 'Admin.Global'),
'name' => 'active',
'required' => true,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
),
array(
'id' => 'active_off',
'value' => 0,
),
),
'desc' => $this->trans('Enable or disable this shop group?', array(), 'Admin.Advparameters.Help'),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
if (!($obj = $this->loadObject(true))) {
return;
}
if (Shop::getTotalShops() > 1 && $obj->id) {
$disabled = array(
'share_customer' => true,
'share_stock' => true,
'share_order' => true,
'active' => false,
);
} else {
$disabled = false;
}
$default_shop = new Shop(Configuration::get('PS_SHOP_DEFAULT'));
$this->tpl_form_vars = array(
'disabled' => $disabled,
'checked' => (Tools::getValue('addshop_group') !== false) ? true : false,
'defaultGroup' => $default_shop->id_shop_group,
);
$this->fields_value = array(
'active' => true,
);
return parent::renderForm();
}
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
$shop_group_delete_list = array();
// test store authorized to remove
foreach ($this->_list as $shop_group) {
$shops = Shop::getShops(true, $shop_group['id_shop_group']);
if (!empty($shops)) {
$shop_group_delete_list[] = $shop_group['id_shop_group'];
}
}
$this->addRowActionSkipList('delete', $shop_group_delete_list);
}
public function postProcess()
{
if (Tools::isSubmit('delete' . $this->table) || Tools::isSubmit('status') || Tools::isSubmit('status' . $this->table)) {
/** @var ShopGroup $object */
$object = $this->loadObject();
if (ShopGroup::getTotalShopGroup() == 1) {
$this->errors[] = $this->trans('You cannot delete or disable the last shop group.', array(), 'Admin.Notifications.Error');
} elseif ($object->haveShops()) {
$this->errors[] = $this->trans('You cannot delete or disable a shop group in use.', array(), 'Admin.Notifications.Error');
}
if (count($this->errors)) {
return false;
}
}
return parent::postProcess();
}
protected function afterAdd($new_shop_group)
{
//Reset available quantitites
StockAvailable::resetProductFromStockAvailableByShopGroup($new_shop_group);
}
protected function afterUpdate($new_shop_group)
{
//Reset available quantitites
StockAvailable::resetProductFromStockAvailableByShopGroup($new_shop_group);
}
public function renderOptions()
{
if ($this->fields_options && is_array($this->fields_options)) {
$this->display = 'options';
$this->show_toolbar = false;
$helper = new HelperOptions($this);
$this->setHelperDisplay($helper);
$helper->id = $this->id;
$helper->tpl_vars = $this->tpl_option_vars;
$options = $helper->generateOptions($this->fields_options);
return $options;
}
}
}

View File

@@ -0,0 +1,574 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property ShopUrl $object
*/
class AdminShopUrlControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'shop_url';
$this->className = 'ShopUrl';
$this->lang = false;
$this->requiredDatabase = true;
$this->multishop_context = Shop::CONTEXT_ALL;
$this->bulk_actions = array();
parent::__construct();
/* if $_GET['id_shop'] is transmitted, virtual url can be loaded in config.php, so we wether transmit shop_id in herfs */
if ($this->id_shop = (int) Tools::getValue('shop_id')) {
$_GET['id_shop'] = $this->id_shop;
} else {
$this->id_shop = (int) Tools::getValue('id_shop');
}
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
$this->fields_list = array(
'id_shop_url' => array(
'title' => $this->trans('Shop URL ID', array(), 'Admin.Advparameters.Feature'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'shop_name' => array(
'title' => $this->trans('Shop name', array(), 'Admin.Advparameters.Feature'),
'filter_key' => 's!name',
),
'url' => array(
'title' => $this->trans('URL', array(), 'Admin.Global'),
'filter_key' => 'url',
'havingFilter' => true,
'remove_onclick' => true,
),
'main' => array(
'title' => $this->trans('Is it the main URL?', array(), 'Admin.Advparameters.Feature'),
'align' => 'center',
'activeVisu' => 'main',
'active' => 'main',
'type' => 'bool',
'orderby' => false,
'filter_key' => 'main',
'class' => 'fixed-width-md',
),
'active' => array(
'title' => $this->trans('Enabled', array(), 'Admin.Global'),
'align' => 'center',
'active' => 'status',
'type' => 'bool',
'orderby' => false,
'filter_key' => 'active',
'class' => 'fixed-width-md',
),
);
}
public function viewAccess($disable = false)
{
return Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE');
}
public function renderList()
{
$this->addRowActionSkipList('delete', array(1));
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_select = 's.name AS shop_name, CONCAT(\'http://\', a.domain, a.physical_uri, a.virtual_uri) AS url';
$this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'shop` s ON (s.id_shop = a.id_shop)';
if ($id_shop = (int) Tools::getValue('id_shop')) {
$this->_where = 'AND a.id_shop = ' . $id_shop;
}
$this->_use_found_rows = false;
return parent::renderList();
}
public function renderForm()
{
$update_htaccess = Tools::modRewriteActive() && ((file_exists('.htaccess') && is_writable('.htaccess')) || is_writable(dirname('.htaccess')));
$this->multiple_fieldsets = true;
if (!$update_htaccess) {
$desc_virtual_uri = array(
'<span class="warning_mod_rewrite">' . $this->trans('If you want to add a virtual URL, you need to activate URL rewriting on your web server and enable Friendly URL option.', array(), 'Admin.Advparameters.Help') . '</span>',
);
} else {
$desc_virtual_uri = array(
$this->trans('You can use this option if you want to create a store with a URL that doesn\'t exist on your server (e.g. if you want your store to be available with the URL www.example.com/my-store/shoes/, you have to set shoes/ in this field, assuming that my-store/ is your Physical URL).', array(), 'Admin.Advparameters.Help'),
'<strong>' . $this->trans('URL rewriting must be activated on your server to use this feature.', array(), 'Admin.Advparameters.Help') . '</strong>',
);
}
$this->fields_form = array(
array(
'form' => array(
'legend' => array(
'title' => $this->trans('URL options', array(), 'Admin.Advparameters.Feature'),
'icon' => 'icon-cogs',
),
'input' => array(
array(
'type' => 'select',
'label' => $this->trans('Shop', array(), 'Admin.Global'),
'name' => 'id_shop',
'onchange' => 'checkMainUrlInfo(this.value);',
'options' => array(
'optiongroup' => array(
'query' => Shop::getTree(),
'label' => 'name',
),
'options' => array(
'query' => 'shops',
'id' => 'id_shop',
'name' => 'name',
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Is it the main URL for this shop?', array(), 'Admin.Advparameters.Feature'),
'name' => 'main',
'is_bool' => true,
'class' => 't',
'values' => array(
array(
'id' => 'main_on',
'value' => 1,
),
array(
'id' => 'main_off',
'value' => 0,
),
),
'desc' => array(
$this->trans('If you set this URL as the Main URL for the selected shop, all URLs set to this shop will be redirected to this URL (you can only have one Main URL per shop).', array(), 'Admin.Advparameters.Help'),
array(
'text' => $this->trans('Since the selected shop has no main URL, you have to set this URL as the Main URL.', array(), 'Admin.Advparameters.Help'),
'id' => 'mainUrlInfo',
),
array(
'text' => $this->trans('The selected shop already has a Main URL. Therefore, if you set this one as the Main URL, the older Main URL will be set as a regular URL.', array(), 'Admin.Advparameters.Help'),
'id' => 'mainUrlInfoExplain',
),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'class' => 't',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
),
array(
'id' => 'active_off',
'value' => 0,
),
),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
),
),
array(
'form' => array(
'legend' => array(
'title' => $this->trans('Shop URL', array(), 'Admin.Advparameters.Feature'),
'icon' => 'icon-shopping-cart',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Domain', array(), 'Admin.Advparameters.Feature'),
'name' => 'domain',
'size' => 50,
),
array(
'type' => 'text',
'label' => $this->trans('SSL Domain', array(), 'Admin.Advparameters.Feature'),
'name' => 'domain_ssl',
'size' => 50,
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
),
),
);
if (!defined('_PS_HOST_MODE_')) {
$this->fields_form[1]['form']['input'] = array_merge(
$this->fields_form[1]['form']['input'],
array(
array(
'type' => 'text',
'label' => $this->trans('Physical URL', array(), 'Admin.Advparameters.Feature'),
'name' => 'physical_uri',
'desc' => $this->trans('This is the physical folder for your store on the web server. Leave this field empty if your store is installed on the root path. For instance, if your store is available at www.example.com/my-store/, you must input my-store/ in this field.', array(), 'Admin.Advparameters.Help'),
'size' => 50,
),
)
);
}
$this->fields_form[1]['form']['input'] = array_merge(
$this->fields_form[1]['form']['input'],
array(
array(
'type' => 'text',
'label' => $this->trans('Virtual URL', array(), 'Admin.Advparameters.Feature'),
'name' => 'virtual_uri',
'desc' => $desc_virtual_uri,
'size' => 50,
'hint' => (!$update_htaccess) ? $this->trans('Warning: URL rewriting (e.g. mod_rewrite for Apache) seems to be disabled. If your Virtual URL doesn\'t work, please check with your hosting provider on how to activate URL rewriting.', array(), 'Admin.Advparameters.Help') : null,
),
array(
'type' => 'text',
'label' => $this->trans('Final URL', array(), 'Admin.Advparameters.Feature'),
'name' => 'final_url',
'size' => 76,
'readonly' => true,
),
)
);
if (!($obj = $this->loadObject(true))) {
return;
}
self::$currentIndex = self::$currentIndex . ($obj->id ? '&shop_id=' . (int) $obj->id_shop : '');
$current_shop = Shop::initialize();
$list_shop_with_url = array();
foreach (Shop::getShops(false, null, true) as $id) {
$list_shop_with_url[$id] = (bool) count(ShopUrl::getShopUrls($id));
}
$this->tpl_form_vars = array(
'js_shop_url' => json_encode($list_shop_with_url),
);
$this->fields_value = array(
'domain' => trim(Validate::isLoadedObject($obj) ? $this->getFieldValue($obj, 'domain') : $current_shop->domain),
'domain_ssl' => trim(Validate::isLoadedObject($obj) ? $this->getFieldValue($obj, 'domain_ssl') : $current_shop->domain_ssl),
'physical_uri' => trim(Validate::isLoadedObject($obj) ? $this->getFieldValue($obj, 'physical_uri') : $current_shop->physical_uri),
'active' => trim(Validate::isLoadedObject($obj) ? $this->getFieldValue($obj, 'active') : true),
);
return parent::renderForm();
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
if ($this->display != 'add' && $this->display != 'edit') {
if ($this->id_object) {
$this->loadObject();
}
if (!$this->id_shop && $this->object && $this->object->id_shop) {
$this->id_shop = $this->object->id_shop;
}
$this->page_header_toolbar_btn['edit'] = array(
'desc' => $this->trans('Edit this shop', array(), 'Admin.Advparameters.Feature'),
'href' => $this->context->link->getAdminLink('AdminShop') . '&updateshop&shop_id=' . (int) $this->id_shop,
);
$this->page_header_toolbar_btn['new'] = array(
'desc' => $this->trans('Add a new URL', array(), 'Admin.Advparameters.Feature'),
'href' => $this->context->link->getAdminLink('AdminShopUrl') . '&add' . $this->table . '&shop_id=' . (int) $this->id_shop,
);
}
}
public function initToolbar()
{
parent::initToolbar();
if ($this->display != 'add' && $this->display != 'edit') {
if ($this->id_object) {
$this->loadObject();
}
if (!$this->id_shop && $this->object && $this->object->id_shop) {
$this->id_shop = $this->object->id_shop;
}
$this->toolbar_btn['new'] = array(
'desc' => $this->trans('Add a new URL', array(), 'Admin.Advparameters.Feature'),
'href' => $this->context->link->getAdminLink('AdminShopUrl') . '&add' . $this->table . '&shop_id=' . (int) $this->id_shop,
);
}
}
public function initContent()
{
parent::initContent();
$this->addJqueryPlugin('cooki-plugin');
$data = Shop::getTree();
foreach ($data as &$group) {
foreach ($group['shops'] as &$shop) {
$current_shop = new Shop($shop['id_shop']);
$urls = $current_shop->getUrls();
foreach ($urls as &$url) {
$title = $url['domain'] . $url['physical_uri'] . $url['virtual_uri'];
if (strlen($title) > 23) {
$title = substr($title, 0, 23) . '...';
}
$url['name'] = $title;
$shop['urls'][$url['id_shop_url']] = $url;
}
}
}
$shops_tree = new HelperTreeShops('shops-tree', $this->trans('Multistore tree', array(), 'Admin.Advparameters.Feature'));
$shops_tree->setNodeFolderTemplate('shop_tree_node_folder.tpl')->setNodeItemTemplate('shop_tree_node_item.tpl')
->setHeaderTemplate('shop_tree_header.tpl')->setActions(array(
new TreeToolbarLink(
'Collapse All',
'#',
'$(\'#' . $shops_tree->getId() . '\').tree(\'collapseAll\'); return false;',
'icon-collapse-alt'
),
new TreeToolbarLink(
'Expand All',
'#',
'$(\'#' . $shops_tree->getId() . '\').tree(\'expandAll\'); return false;',
'icon-expand-alt'
),
))
->setAttribute('url_shop_group', $this->context->link->getAdminLink('AdminShopGroup'))
->setAttribute('url_shop', $this->context->link->getAdminLink('AdminShop'))
->setAttribute('url_shop_url', $this->context->link->getAdminLink('AdminShopUrl'))
->setData($data);
$shops_tree = $shops_tree->render(null, false, false);
if (!$this->display && $this->id_shop) {
$shop = new Shop($this->id_shop);
$this->toolbar_title[] = $shop->name;
}
$this->context->smarty->assign(array(
'toolbar_scroll' => 1,
'toolbar_btn' => $this->toolbar_btn,
'title' => $this->toolbar_title,
'shops_tree' => $shops_tree,
));
}
public function postProcess()
{
$token = Tools::getValue('token') ? Tools::getValue('token') : $this->token;
$result = true;
if ((Tools::isSubmit('status' . $this->table) || Tools::isSubmit('status')) && Tools::getValue($this->identifier)) {
if ($this->access('edit')) {
if (Validate::isLoadedObject($object = $this->loadObject())) {
/** @var ShopUrl $object */
if ($object->main) {
$this->errors[] = $this->trans('You cannot disable the Main URL.', array(), 'Admin.Notifications.Error');
} elseif ($object->toggleStatus()) {
Tools::redirectAdmin(self::$currentIndex . '&conf=5&token=' . $token);
} else {
$this->errors[] = $this->trans('An error occurred while updating the status.', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error') . ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('main' . $this->table) && Tools::getValue($this->identifier)) {
if ($this->access('edit')) {
if (Validate::isLoadedObject($object = $this->loadObject())) {
/** @var ShopUrl $object */
if (!$object->main) {
$result = $object->setMain();
Tools::redirectAdmin(self::$currentIndex . '&conf=4&token=' . $token);
} else {
$this->errors[] = $this->trans('You cannot change a main URL to a non-main URL. You have to set another URL as your Main URL for the selected shop.', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error') . ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
} else {
$result = parent::postProcess();
}
if ($this->redirect_after) {
$this->redirect_after .= '&shop_id=' . (int) $this->id_shop;
}
return $result;
}
public function processSave()
{
/** @var ShopUrl $object */
$object = $this->loadObject(true);
if ($object->canAddThisUrl(Tools::getValue('domain'), Tools::getValue('domain_ssl'), Tools::getValue('physical_uri'), Tools::getValue('virtual_uri'))) {
$this->errors[] = $this->trans('A shop URL that uses this domain already exists.', array(), 'Admin.Notifications.Error');
}
$unallowed = str_replace('/', '', Tools::getValue('virtual_uri'));
if ($unallowed == 'c' || $unallowed == 'img' || is_numeric($unallowed)) {
$this->errors[] = $this->trans(
'A shop virtual URL cannot be "%URL%"',
array(
'%URL%' => $unallowed,
),
'Admin.Notifications.Error'
);
}
$return = parent::processSave();
if (!$this->errors) {
Tools::generateHtaccess();
Tools::generateRobotsFile();
Tools::clearSmartyCache();
Media::clearCache();
}
return $return;
}
public function processAdd()
{
/** @var ShopUrl $object */
$object = $this->loadObject(true);
if ($object->canAddThisUrl(Tools::getValue('domain'), Tools::getValue('domain_ssl'), Tools::getValue('physical_uri'), Tools::getValue('virtual_uri'))) {
$this->errors[] = $this->trans('A shop URL that uses this domain already exists.', array(), 'Admin.Notifications.Error');
}
if (Tools::getValue('main') && !Tools::getValue('active')) {
$this->errors[] = $this->trans('You cannot disable the Main URL.', array(), 'Admin.Notifications.Error');
}
return parent::processAdd();
}
public function processUpdate()
{
$this->redirect_shop_url = false;
$current_url = parse_url($_SERVER['REQUEST_URI']);
if (trim(dirname(dirname($current_url['path'])), '/') == trim($this->object->getBaseURI(), '/')) {
$this->redirect_shop_url = true;
}
/** @var ShopUrl $object */
$object = $this->loadObject(true);
if ($object->main && !Tools::getValue('main')) {
$this->errors[] = $this->trans('You cannot change a main URL to a non-main URL. You have to set another URL as your Main URL for the selected shop.', array(), 'Admin.Notifications.Error');
}
if (($object->main || Tools::getValue('main')) && !Tools::getValue('active')) {
$this->errors[] = $this->trans('You cannot disable the Main URL.', array(), 'Admin.Notifications.Error');
}
return parent::processUpdate();
}
/**
* @param ShopUrl $object
*/
protected function afterUpdate($object)
{
if ($object->id && Tools::getValue('main')) {
$object->setMain();
}
if ($this->redirect_shop_url) {
$this->redirect_after = $this->context->link->getAdminLink('AdminShopUrl');
}
}
/**
* @param string $token
* @param int $id
* @param string $name
*
* @return mixed
*/
public function displayDeleteLink($token, $id, $name = null)
{
$tpl = $this->createTemplate('helpers/list/list_action_delete.tpl');
if (!array_key_exists('Delete', self::$cache_lang)) {
self::$cache_lang['Delete'] = $this->trans('Delete', array(), 'Admin.Actions');
}
if (!array_key_exists('DeleteItem', self::$cache_lang)) {
self::$cache_lang['DeleteItem'] = $this->trans('Delete selected item?', array(), 'Admin.Notifications.Warning');
}
if (!array_key_exists('Name', self::$cache_lang)) {
self::$cache_lang['Name'] = $this->trans('Name:', array(), 'Admin.Global');
}
if (null !== $name) {
$name = '\n\n' . self::$cache_lang['Name'] . ' ' . $name;
}
$data = array(
$this->identifier => $id,
'href' => self::$currentIndex . '&' . $this->identifier . '=' . $id . '&delete' . $this->table . '&shop_id=' . (int) $this->id_shop . '&token=' . ($token != null ? $token : $this->token),
'action' => self::$cache_lang['Delete'],
);
if ($this->specificConfirmDelete !== false) {
$data['confirm'] = null !== $this->specificConfirmDelete ? '\r' . $this->specificConfirmDelete : self::$cache_lang['DeleteItem'] . $name;
}
$tpl->assign(array_merge($this->tpl_delete_link_vars, $data));
return $tpl->fetch();
}
}

View File

@@ -0,0 +1,202 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property OrderSlip $object
*/
class AdminSlipControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'order_slip';
$this->className = 'OrderSlip';
$this->_select = ' o.`id_shop`';
$this->_join .= ' LEFT JOIN ' . _DB_PREFIX_ . 'orders o ON (o.`id_order` = a.`id_order`)';
$this->_group = ' GROUP BY a.`id_order_slip`';
parent::__construct();
$this->fields_list = array(
'id_order_slip' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'id_order' => array(
'title' => $this->trans('Order ID', array(), 'Admin.Orderscustomers.Feature'),
'align' => 'left',
'class' => 'fixed-width-md',
'filter_key' => 'a!id_order',
),
'date_add' => array(
'title' => $this->trans('Date issued', array(), 'Admin.Orderscustomers.Feature'),
'type' => 'date',
'align' => 'right',
'filter_key' => 'a!date_add',
'havingFilter' => true,
),
'id_pdf' => array(
'title' => $this->trans('PDF', array(), 'Admin.Global'),
'align' => 'center',
'callback' => 'printPDFIcons',
'orderby' => false,
'search' => false,
'remove_onclick' => true, ),
);
$this->_select = 'a.id_order_slip AS id_pdf';
$this->optionTitle = $this->trans('Slip', array(), 'Admin.Orderscustomers.Feature');
$this->fields_options = array(
'general' => array(
'title' => $this->trans('Credit slip options', array(), 'Admin.Orderscustomers.Feature'),
'fields' => array(
'PS_CREDIT_SLIP_PREFIX' => array(
'title' => $this->trans('Credit slip prefix', array(), 'Admin.Orderscustomers.Feature'),
'desc' => $this->trans('Prefix used for credit slips.', array(), 'Admin.Orderscustomers.Help'),
'size' => 6,
'type' => 'textLang',
),
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
),
);
$this->_where = Shop::addSqlRestriction(false, 'o');
}
public function initPageHeaderToolbar()
{
$this->page_header_toolbar_btn['generate_pdf'] = array(
'href' => self::$currentIndex . '&token=' . $this->token,
'desc' => $this->trans('Generate PDF', array(), 'Admin.Orderscustomers.Feature'),
'icon' => 'process-icon-save-date',
);
parent::initPageHeaderToolbar();
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Print a PDF', array(), 'Admin.Orderscustomers.Feature'),
'icon' => 'icon-print',
),
'input' => array(
array(
'type' => 'date',
'label' => $this->trans('From', array(), 'Admin.Global'),
'name' => 'date_from',
'maxlength' => 10,
'required' => true,
'hint' => $this->trans('Format: 2011-12-31 (inclusive).', array(), 'Admin.Orderscustomers.Help'),
),
array(
'type' => 'date',
'label' => $this->trans('To', array(), 'Admin.Global'),
'name' => 'date_to',
'maxlength' => 10,
'required' => true,
'hint' => $this->trans('Format: 2012-12-31 (inclusive).', array(), 'Admin.Orderscustomers.Help'),
),
),
'submit' => array(
'title' => $this->trans('Generate PDF', array(), 'Admin.Orderscustomers.Feature'),
'id' => 'submitPrint',
'icon' => 'process-icon-download-alt',
),
);
$this->fields_value = array(
'date_from' => date('Y-m-d'),
'date_to' => date('Y-m-d'),
);
$this->show_toolbar = false;
return parent::renderForm();
}
public function postProcess()
{
if (Tools::getValue('submitAddorder_slip')) {
if (!Validate::isDate(Tools::getValue('date_from'))) {
$this->errors[] = $this->trans('Invalid "From" date', array(), 'Admin.Orderscustomers.Notification');
}
if (!Validate::isDate(Tools::getValue('date_to'))) {
$this->errors[] = $this->trans('Invalid "To" date', array(), 'Admin.Orderscustomers.Notification');
}
if (!count($this->errors)) {
$order_slips = OrderSlip::getSlipsIdByDate(Tools::getValue('date_from'), Tools::getValue('date_to'));
if (count($order_slips)) {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminPdf') . '&submitAction=generateOrderSlipsPDF&date_from=' . urlencode(Tools::getValue('date_from')) . '&date_to=' . urlencode(Tools::getValue('date_to')));
}
$this->errors[] = $this->trans('No order slips were found for this period.', array(), 'Admin.Orderscustomers.Notification');
}
} else {
return parent::postProcess();
}
}
public function initContent()
{
$this->content .= $this->renderList();
$this->content .= $this->renderForm();
$this->content .= $this->renderOptions();
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
public function initToolbar()
{
parent::initToolbar();
$this->toolbar_btn['save-date'] = array(
'href' => '#',
'desc' => $this->trans('Generate PDF', array(), 'Admin.Orderscustomers.Feature'),
);
}
public function printPDFIcons($id_order_slip, $tr)
{
$order_slip = new OrderSlip((int) $id_order_slip);
if (!Validate::isLoadedObject($order_slip)) {
return '';
}
$this->context->smarty->assign(array(
'order_slip' => $order_slip,
'tr' => $tr,
));
return $this->createTemplate('_print_pdf_icon.tpl')->fetch();
}
}

View File

@@ -0,0 +1,380 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property SpecificPriceRule $object
*/
class AdminSpecificPriceRuleControllerCore extends AdminController
{
public $list_reduction_type;
public function __construct()
{
$this->bootstrap = true;
$this->table = 'specific_price_rule';
$this->className = 'SpecificPriceRule';
$this->lang = false;
$this->multishop_context = Shop::CONTEXT_ALL;
parent::__construct();
/* if $_GET['id_shop'] is transmitted, virtual url can be loaded in config.php, so we wether transmit shop_id in herfs */
if ($this->id_shop = (int) Tools::getValue('shop_id')) {
$_GET['id_shop'] = $this->id_shop;
$_POST['id_shop'] = $this->id_shop;
}
$this->list_reduction_type = array(
'percentage' => $this->trans('Percentage', array(), 'Admin.Global'),
'amount' => $this->trans('Amount', array(), 'Admin.Global'),
);
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_select = 's.name shop_name, cu.iso_code as currency_iso_code, cl.name country_name, gl.name group_name';
$this->_join = 'LEFT JOIN ' . _DB_PREFIX_ . 'shop s ON (s.id_shop = a.id_shop)
LEFT JOIN ' . _DB_PREFIX_ . 'currency cu ON (cu.id_currency = a.id_currency)
LEFT JOIN ' . _DB_PREFIX_ . 'country_lang cl ON (cl.id_country = a.id_country AND cl.id_lang=' . (int) $this->context->language->id . ')
LEFT JOIN ' . _DB_PREFIX_ . 'group_lang gl ON (gl.id_group = a.id_group AND gl.id_lang=' . (int) $this->context->language->id . ')';
$this->_use_found_rows = false;
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'id_specific_price_rule' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'filter_key' => 'a!name',
'width' => 'auto',
),
'shop_name' => array(
'title' => $this->trans('Shop', array(), 'Admin.Global'),
'filter_key' => 's!name',
),
'currency_name' => array(
'title' => $this->trans('Currency', array(), 'Admin.Global'),
'align' => 'center',
'filter_key' => 'cu!name',
),
'country_name' => array(
'title' => $this->trans('Country', array(), 'Admin.Global'),
'align' => 'center',
'filter_key' => 'cl!name',
),
'group_name' => array(
'title' => $this->trans('Group', array(), 'Admin.Global'),
'align' => 'center',
'filter_key' => 'gl!name',
),
'from_quantity' => array(
'title' => $this->trans('From quantity', array(), 'Admin.Catalog.Feature'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'reduction_type' => array(
'title' => $this->trans('Reduction type', array(), 'Admin.Catalog.Feature'),
'align' => 'center',
'type' => 'select',
'filter_key' => 'a!reduction_type',
'list' => $this->list_reduction_type,
),
'reduction' => array(
'title' => $this->trans('Reduction', array(), 'Admin.Catalog.Feature'),
'align' => 'center',
'type' => 'decimal',
'class' => 'fixed-width-xs',
),
'from' => array(
'title' => $this->trans('Beginning', array(), 'Admin.Catalog.Feature'),
'align' => 'right',
'type' => 'datetime',
'filter_key' => 'a!from',
'order_key' => 'a!from',
),
'to' => array(
'title' => $this->trans('End', array(), 'Admin.Catalog.Feature'),
'align' => 'right',
'type' => 'datetime',
'filter_key' => 'a!to',
'order_key' => 'a!to',
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_specific_price_rule'] = array(
'href' => self::$currentIndex . '&addspecific_price_rule&token=' . $this->token,
'desc' => $this->trans('Add new catalog price rule', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
foreach ($this->_list as $k => $list) {
if (null !== $this->_list[$k]['currency_iso_code']) {
$currency = new Currency(Currency::getIdByIsoCode($this->_list[$k]['currency_iso_code']));
$this->_list[$k]['currency_name'] = $currency->name;
}
if ($list['reduction_type'] == 'amount') {
$this->_list[$k]['reduction_type'] = $this->list_reduction_type['amount'];
} elseif ($list['reduction_type'] == 'percentage') {
$this->_list[$k]['reduction_type'] = $this->list_reduction_type['percentage'];
}
}
}
public function renderForm()
{
if (!$this->object->id) {
$this->object->price = -1;
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Catalog price rules', array(), 'Admin.Catalog.Feature'),
'icon' => 'icon-dollar',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'maxlength' => 255,
'required' => true,
),
array(
'type' => 'select',
'label' => $this->trans('Shop', array(), 'Admin.Global'),
'name' => 'shop_id',
'options' => array(
'query' => Shop::getShops(),
'id' => 'id_shop',
'name' => 'name',
),
'condition' => Shop::isFeatureActive(),
'default_value' => Shop::getContextShopID(),
),
array(
'type' => 'select',
'label' => $this->trans('Currency', array(), 'Admin.Global'),
'name' => 'id_currency',
'options' => array(
'query' => array_merge(array(0 => array('id_currency' => 0, 'name' => $this->trans('All currencies', array(), 'Admin.Global'))), Currency::getCurrencies(false, true, true)),
'id' => 'id_currency',
'name' => 'name',
),
),
array(
'type' => 'select',
'label' => $this->trans('Country', array(), 'Admin.Global'),
'name' => 'id_country',
'options' => array(
'query' => array_merge(array(0 => array('id_country' => 0, 'name' => $this->trans('All countries', array(), 'Admin.Global'))), Country::getCountries((int) $this->context->language->id)),
'id' => 'id_country',
'name' => 'name',
),
),
array(
'type' => 'select',
'label' => $this->trans('Group', array(), 'Admin.Global'),
'name' => 'id_group',
'options' => array(
'query' => array_merge(array(0 => array('id_group' => 0, 'name' => $this->trans('All groups', array(), 'Admin.Global'))), Group::getGroups((int) $this->context->language->id)),
'id' => 'id_group',
'name' => 'name',
),
),
array(
'type' => 'text',
'label' => $this->trans('From quantity', array(), 'Admin.Catalog.Feature'),
'name' => 'from_quantity',
'maxlength' => 10,
'required' => true,
),
array(
'type' => 'text',
'label' => $this->trans('Price (tax excl.)', array(), 'Admin.Catalog.Feature'),
'name' => 'price',
'disabled' => ($this->object->price == -1 ? 1 : 0),
'maxlength' => 10,
'suffix' => $this->context->currency->getSign('right'),
),
array(
'type' => 'checkbox',
'name' => 'leave_bprice',
'values' => array(
'query' => array(
array(
'id' => 'on',
'name' => $this->trans('Leave initial price', array(), 'Admin.Catalog.Feature'),
'val' => '1',
'checked' => '1',
),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'datetime',
'label' => $this->trans('From', array(), 'Admin.Global'),
'name' => 'from',
),
array(
'type' => 'datetime',
'label' => $this->trans('To', array(), 'Admin.Global'),
'name' => 'to',
),
array(
'type' => 'select',
'label' => $this->trans('Reduction type', array(), 'Admin.Catalog.Feature'),
'name' => 'reduction_type',
'options' => array(
'query' => array(array('reduction_type' => 'amount', 'name' => $this->trans('Amount', array(), 'Admin.Global')), array('reduction_type' => 'percentage', 'name' => $this->trans('Percentage', array(), 'Admin.Global'))),
'id' => 'reduction_type',
'name' => 'name',
),
),
array(
'type' => 'select',
'label' => $this->trans('Reduction with or without taxes', array(), 'Admin.Catalog.Feature'),
'name' => 'reduction_tax',
'align' => 'center',
'options' => array(
'query' => array(
array('lab' => $this->trans('Tax included', array(), 'Admin.Global'), 'val' => 1),
array('lab' => $this->trans('Tax excluded', array(), 'Admin.Global'), 'val' => 0),
),
'id' => 'val',
'name' => 'lab',
),
),
array(
'type' => 'text',
'label' => $this->trans('Reduction', array(), 'Admin.Catalog.Feature'),
'name' => 'reduction',
'required' => true,
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
if (($value = $this->getFieldValue($this->object, 'price')) != -1) {
$price = number_format($value, 6);
} else {
$price = '';
}
$this->fields_value = array(
'price' => $price,
'from_quantity' => (($value = $this->getFieldValue($this->object, 'from_quantity')) ? $value : 1),
'reduction' => number_format((($value = $this->getFieldValue($this->object, 'reduction')) ? $value : 0), 6),
'leave_bprice_on' => $price ? 0 : 1,
'shop_id' => (($value = $this->getFieldValue($this->object, 'id_shop')) ? $value : 1),
);
$attribute_groups = array();
$attributes = Attribute::getAttributes((int) $this->context->language->id);
foreach ($attributes as $attribute) {
if (!isset($attribute_groups[$attribute['id_attribute_group']])) {
$attribute_groups[$attribute['id_attribute_group']] = array(
'id_attribute_group' => $attribute['id_attribute_group'],
'name' => $attribute['attribute_group'],
);
}
$attribute_groups[$attribute['id_attribute_group']]['attributes'][] = array(
'id_attribute' => $attribute['id_attribute'],
'name' => $attribute['name'],
);
}
$features = Feature::getFeatures((int) $this->context->language->id);
foreach ($features as &$feature) {
$feature['values'] = FeatureValue::getFeatureValuesWithLang((int) $this->context->language->id, $feature['id_feature'], true);
}
$this->tpl_form_vars = array(
'manufacturers' => Manufacturer::getManufacturers(false, (int) $this->context->language->id, true, false, false, false, true),
'suppliers' => Supplier::getSuppliers(),
'attributes_group' => $attribute_groups,
'features' => $features,
'categories' => Category::getSimpleCategories((int) $this->context->language->id),
'conditions' => $this->object->getConditions(),
'is_multishop' => Shop::isFeatureActive(),
);
return parent::renderForm();
}
public function processSave()
{
$_POST['price'] = Tools::getValue('leave_bprice_on') ? '-1' : Tools::getValue('price');
if (Validate::isLoadedObject(($object = parent::processSave()))) {
/* @var SpecificPriceRule $object */
$object->deleteConditions();
foreach ($_POST as $key => $values) {
if (preg_match('/^condition_group_([0-9]+)$/Ui', $key, $condition_group)) {
$conditions = array();
foreach ($values as $value) {
$condition = explode('_', $value);
$conditions[] = array('type' => $condition[0], 'value' => $condition[1]);
}
$object->addConditions($conditions);
}
}
$object->apply();
return $object;
}
}
public function postProcess()
{
Tools::clearSmartyCache();
return parent::postProcess();
}
}

View File

@@ -0,0 +1,299 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property State $object
*/
class AdminStatesControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'state';
$this->className = 'State';
$this->lang = false;
$this->requiredDatabase = true;
parent::__construct();
$this->addRowAction('edit');
$this->addRowAction('delete');
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
$this->bulk_actions = array(
'delete' => array('text' => $this->trans('Delete selected', array(), 'Admin.Actions'), 'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning')),
'AffectZone' => array('text' => $this->trans('Assign to a new zone', array(), 'Admin.International.Feature')),
);
$this->_select = 'z.`name` AS zone, cl.`name` AS country';
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'zone` z ON (z.`id_zone` = a.`id_zone`)
LEFT JOIN `' . _DB_PREFIX_ . 'country_lang` cl ON (cl.`id_country` = a.`id_country` AND cl.id_lang = ' . (int) $this->context->language->id . ')';
$this->_use_found_rows = false;
$countries_array = $zones_array = array();
$this->zones = Zone::getZones();
$this->countries = Country::getCountries($this->context->language->id, false, true, false);
foreach ($this->zones as $zone) {
$zones_array[$zone['id_zone']] = $zone['name'];
}
foreach ($this->countries as $country) {
$countries_array[$country['id_country']] = $country['name'];
}
$this->fields_list = array(
'id_state' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'filter_key' => 'a!name',
),
'iso_code' => array(
'title' => $this->trans('ISO code', array(), 'Admin.International.Feature'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'zone' => array(
'title' => $this->trans('Zone', array(), 'Admin.Global'),
'type' => 'select',
'list' => $zones_array,
'filter_key' => 'z!id_zone',
'filter_type' => 'int',
'order_key' => 'zone',
),
'country' => array(
'title' => $this->trans('Country', array(), 'Admin.Global'),
'type' => 'select',
'list' => $countries_array,
'filter_key' => 'cl!id_country',
'filter_type' => 'int',
'order_key' => 'country',
),
'active' => array(
'title' => $this->trans('Enabled', array(), 'Admin.Global'),
'active' => 'status',
'filter_key' => 'a!active',
'align' => 'center',
'type' => 'bool',
'orderby' => false,
'class' => 'fixed-width-sm',
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_state'] = array(
'href' => self::$currentIndex . '&addstate&token=' . $this->token,
'desc' => $this->trans('Add new state', array(), 'Admin.International.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderList()
{
$this->tpl_list_vars['zones'] = Zone::getZones();
$this->tpl_list_vars['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
$this->tpl_list_vars['POST'] = $_POST;
return parent::renderList();
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('States', array(), 'Admin.International.Feature'),
'icon' => 'icon-globe',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'maxlength' => 32,
'required' => true,
'hint' => $this->trans('Provide the state name to be displayed in addresses and on invoices.', array(), 'Admin.International.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('ISO code', array(), 'Admin.International.Feature'),
'name' => 'iso_code',
'maxlength' => 7,
'required' => true,
'class' => 'uppercase',
'hint' => $this->trans('1 to 4 letter ISO code.', array(), 'Admin.International.Help') . ' ' . $this->trans('You can prefix it with the country ISO code if needed.', array(), 'Admin.International.Help'),
),
array(
'type' => 'select',
'label' => $this->trans('Country', array(), 'Admin.Global'),
'name' => 'id_country',
'required' => true,
'default_value' => (int) $this->context->country->id,
'options' => array(
'query' => Country::getCountries($this->context->language->id, false, true),
'id' => 'id_country',
'name' => 'name',
),
'hint' => $this->trans('Country where the state is located.', array(), 'Admin.International.Help') . ' ' . $this->trans('Only the countries with the option "contains states" enabled are displayed.', array(), 'Admin.International.Help'),
),
array(
'type' => 'select',
'label' => $this->trans('Zone', array(), 'Admin.Global'),
'name' => 'id_zone',
'required' => true,
'options' => array(
'query' => Zone::getZones(),
'id' => 'id_zone',
'name' => 'name',
),
'hint' => array(
$this->trans('Geographical region where this state is located.', array(), 'Admin.International.Help'),
$this->trans('Used for shipping', array(), 'Admin.International.Help'),
),
),
array(
'type' => 'switch',
'label' => $this->trans('Status', array(), 'Admin.Global'),
'name' => 'active',
'required' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => '<img src="../img/admin/enabled.gif" alt="' . $this->trans('Enabled', array(), 'Admin.Global') . '" title="' . $this->trans('Enabled', array(), 'Admin.Global') . '" />',
),
array(
'id' => 'active_off',
'value' => 0,
'label' => '<img src="../img/admin/disabled.gif" alt="' . $this->trans('Disabled', array(), 'Admin.Global') . '" title="' . $this->trans('Disabled', array(), 'Admin.Global') . '" />',
),
),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
return parent::renderForm();
}
public function postProcess()
{
if (Tools::isSubmit($this->table . 'Orderby') || Tools::isSubmit($this->table . 'Orderway')) {
$this->filter = true;
}
// Idiot-proof controls
if (!Tools::getValue('id_' . $this->table)) {
if (Validate::isStateIsoCode(Tools::getValue('iso_code')) && State::getIdByIso(Tools::getValue('iso_code'), Tools::getValue('id_country'))) {
$this->errors[] = $this->trans('This ISO code already exists. You cannot create two states with the same ISO code.', array(), 'Admin.International.Notification');
}
} elseif (Validate::isStateIsoCode(Tools::getValue('iso_code'))) {
$id_state = State::getIdByIso(Tools::getValue('iso_code'), Tools::getValue('id_country'));
if ($id_state && $id_state != Tools::getValue('id_' . $this->table)) {
$this->errors[] = $this->trans('This ISO code already exists. You cannot create two states with the same ISO code.', array(), 'Admin.International.Notification');
}
}
/* Delete state */
if (Tools::isSubmit('delete' . $this->table)) {
if ($this->access('delete')) {
if (Validate::isLoadedObject($object = $this->loadObject())) {
/** @var State $object */
if (!$object->isUsed()) {
if ($object->delete()) {
Tools::redirectAdmin(self::$currentIndex . '&conf=1&token=' . (Tools::getValue('token') ? Tools::getValue('token') : $this->token));
}
$this->errors[] = $this->trans('An error occurred during deletion.', array(), 'Admin.Notifications.Error');
} else {
$this->errors[] = $this->trans('This state was used in at least one address. It cannot be removed.', array(), 'Admin.International.Notification');
}
} else {
$this->errors[] = $this->trans('An error occurred while deleting the object.', array(), 'Admin.Notifications.Error') . ' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
}
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
}
if (!count($this->errors)) {
parent::postProcess();
}
}
protected function displayAjaxStates()
{
$states = Db::getInstance()->executeS('
SELECT s.id_state, s.name
FROM ' . _DB_PREFIX_ . 'state s
LEFT JOIN ' . _DB_PREFIX_ . 'country c ON (s.`id_country` = c.`id_country`)
WHERE s.id_country = ' . (int) (Tools::getValue('id_country')) . ' AND s.active = 1 AND c.`contains_states` = 1
ORDER BY s.`name` ASC');
if (is_array($states) && !empty($states)) {
$list = '';
if ((bool) Tools::getValue('no_empty') != true) {
$empty_value = (Tools::isSubmit('empty_value')) ? Tools::getValue('empty_value') : '-';
$list = '<option value="0">' . Tools::htmlentitiesUTF8($empty_value) . '</option>' . "\n";
}
foreach ($states as $state) {
$list .= '<option value="' . (int) ($state['id_state']) . '"' . ((isset($_GET['id_state']) && $_GET['id_state'] == $state['id_state']) ? ' selected="selected"' : '') . '>' . $state['name'] . '</option>' . "\n";
}
} else {
$list = 'false';
}
die($list);
}
/**
* Allow the assignation of zone only if the form is displayed.
*/
protected function processBulkAffectZone()
{
$zone_to_affect = Tools::getValue('zone_to_affect');
if ($zone_to_affect && $zone_to_affect !== 0) {
parent::processBulkAffectZone();
}
if (Tools::getIsset('submitBulkAffectZonestate')) {
$this->tpl_list_vars['assign_zone'] = true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,313 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
abstract class AdminStatsTabControllerCore extends AdminPreferencesControllerCore
{
public function init()
{
parent::init();
$this->action = 'view';
$this->display = 'view';
}
public function initContent()
{
if ($this->ajax) {
return;
}
$this->addToolBarModulesListButton();
$this->toolbar_title = $this->trans('Stats', array(), 'Admin.Stats.Feature');
if ($this->display == 'view') {
// Some controllers use the view action without an object
if ($this->className) {
$this->loadObject(true);
}
$this->content .= $this->renderView();
}
$this->content .= $this->displayMenu();
$this->content .= $this->displayCalendar();
$this->content .= $this->displayStats();
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
unset($this->page_header_toolbar_btn['back']);
}
public function displayCalendar()
{
return AdminStatsTabController::displayCalendarForm(array(
'Calendar' => $this->trans('Calendar', array(), 'Admin.Global'),
'Day' => $this->trans('Day', array(), 'Admin.Global'),
'Month' => $this->trans('Month', array(), 'Admin.Global'),
'Year' => $this->trans('Year', array(), 'Admin.Global'),
'From' => $this->trans('From:', array(), 'Admin.Global'),
'To' => $this->trans('To:', array(), 'Admin.Global'),
'Save' => $this->trans('Save', array(), 'Admin.Global'),
), $this->token);
}
public static function displayCalendarForm($translations, $token, $action = null, $table = null, $identifier = null, $id = null)
{
$context = Context::getContext();
$tpl = $context->controller->createTemplate('calendar.tpl');
$context->controller->addJqueryUI('ui.datepicker');
if ($identifier === null && Tools::getValue('module')) {
$identifier = 'module';
$id = Tools::getValue('module');
}
$action = Context::getContext()->link->getAdminLink('AdminStats');
$action .= ($action && $table ? '&' . Tools::safeOutput($action) : '');
$action .= ($identifier && $id ? '&' . Tools::safeOutput($identifier) . '=' . (int) $id : '');
$module = Tools::getValue('module');
$action .= ($module ? '&module=' . Tools::safeOutput($module) : '');
$action .= (($id_product = Tools::getValue('id_product')) ? '&id_product=' . Tools::safeOutput($id_product) : '');
$tpl->assign(array(
'current' => self::$currentIndex,
'token' => $token,
'action' => $action,
'table' => $table,
'identifier' => $identifier,
'id' => $id,
'translations' => $translations,
'datepickerFrom' => Tools::getValue('datepickerFrom', $context->employee->stats_date_from),
'datepickerTo' => Tools::getValue('datepickerTo', $context->employee->stats_date_to),
));
return $tpl->fetch();
}
/* Not used anymore, but still work */
protected function displayEngines()
{
$tpl = $this->createTemplate('engines.tpl');
$autoclean_period = array(
'never' => $this->trans('Never', array(), 'Admin.Global'),
'week' => $this->trans('Week', array(), 'Admin.Global'),
'month' => $this->trans('Month', array(), 'Admin.Global'),
'year' => $this->trans('Year', array(), 'Admin.Global'),
);
$tpl->assign(array(
'current' => self::$currentIndex,
'token' => $this->token,
'graph_engine' => Configuration::get('PS_STATS_RENDER'),
'grid_engine' => Configuration::get('PS_STATS_GRID_RENDER'),
'auto_clean' => Configuration::get('PS_STATS_OLD_CONNECT_AUTO_CLEAN'),
'array_graph_engines' => ModuleGraphEngine::getGraphEngines(),
'array_grid_engines' => ModuleGridEngine::getGridEngines(),
'array_auto_clean' => $autoclean_period,
));
return $tpl->fetch();
}
public function displayMenu()
{
$tpl = $this->createTemplate('menu.tpl');
$modules = $this->getModules();
$module_instance = array();
foreach ($modules as $m => $module) {
if ($module_instance[$module['name']] = Module::getInstanceByName($module['name'])) {
$modules[$m]['displayName'] = $module_instance[$module['name']]->displayName;
} else {
unset(
$module_instance[$module['name']],
$modules[$m]
);
}
}
uasort($modules, array($this, 'checkModulesNames'));
$tpl->assign(array(
'current' => self::$currentIndex,
'current_module_name' => Tools::getValue('module', 'statsforecast'),
'token' => $this->token,
'modules' => $modules,
'module_instance' => $module_instance,
));
return $tpl->fetch();
}
public function checkModulesNames($a, $b)
{
return (bool) ($a['displayName'] > $b['displayName']);
}
protected function getModules()
{
$sql = 'SELECT h.`name` AS hook, m.`name`
FROM `' . _DB_PREFIX_ . 'module` m
LEFT JOIN `' . _DB_PREFIX_ . 'hook_module` hm ON hm.`id_module` = m.`id_module`
LEFT JOIN `' . _DB_PREFIX_ . 'hook` h ON hm.`id_hook` = h.`id_hook`
WHERE h.`name` = \'displayAdminStatsModules\'
AND m.`active` = 1
GROUP BY hm.id_module
ORDER BY hm.`position`';
return Db::getInstance()->executeS($sql);
}
public function displayStats()
{
$tpl = $this->createTemplate('stats.tpl');
if ((!($module_name = Tools::getValue('module')) || !Validate::isModuleName($module_name)) && ($module_instance = Module::getInstanceByName('statsforecast')) && $module_instance->active) {
$module_name = 'statsforecast';
}
if ($module_name) {
$_GET['module'] = $module_name;
if (!isset($module_instance)) {
$module_instance = Module::getInstanceByName($module_name);
}
if ($module_instance && $module_instance->active) {
$hook = Hook::exec('displayAdminStatsModules', null, $module_instance->id);
}
}
$tpl->assign(array(
'module_name' => $module_name,
'module_instance' => isset($module_instance) ? $module_instance : null,
'hook' => isset($hook) ? $hook : null,
));
return $tpl->fetch();
}
public function postProcess()
{
$this->context = Context::getContext();
$this->processDateRange();
if (Tools::getValue('submitSettings')) {
if ($this->access('edit')) {
self::$currentIndex .= '&module=' . Tools::getValue('module');
Configuration::updateValue('PS_STATS_RENDER', Tools::getValue('PS_STATS_RENDER', Configuration::get('PS_STATS_RENDER')));
Configuration::updateValue('PS_STATS_GRID_RENDER', Tools::getValue('PS_STATS_GRID_RENDER', Configuration::get('PS_STATS_GRID_RENDER')));
Configuration::updateValue('PS_STATS_OLD_CONNECT_AUTO_CLEAN', Tools::getValue('PS_STATS_OLD_CONNECT_AUTO_CLEAN', Configuration::get('PS_STATS_OLD_CONNECT_AUTO_CLEAN')));
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
}
}
public function processDateRange()
{
if (Tools::isSubmit('submitDatePicker')) {
if ((!Validate::isDate($from = Tools::getValue('datepickerFrom')) || !Validate::isDate($to = Tools::getValue('datepickerTo'))) || (strtotime($from) > strtotime($to))) {
$this->errors[] = $this->trans('The specified date is invalid.', array(), 'Admin.Stats.Notification');
}
}
if (Tools::isSubmit('submitDateDay')) {
$from = date('Y-m-d');
$to = date('Y-m-d');
}
if (Tools::isSubmit('submitDateDayPrev')) {
$yesterday = time() - 60 * 60 * 24;
$from = date('Y-m-d', $yesterday);
$to = date('Y-m-d', $yesterday);
}
if (Tools::isSubmit('submitDateMonth')) {
$from = date('Y-m-01');
$to = date('Y-m-t');
}
if (Tools::isSubmit('submitDateMonthPrev')) {
$m = (date('m') == 1 ? 12 : date('m') - 1);
$y = ($m == 12 ? date('Y') - 1 : date('Y'));
$from = $y . '-' . $m . '-01';
$to = $y . '-' . $m . date('-t', mktime(12, 0, 0, $m, 15, $y));
}
if (Tools::isSubmit('submitDateYear')) {
$from = date('Y-01-01');
$to = date('Y-12-31');
}
if (Tools::isSubmit('submitDateYearPrev')) {
$from = (date('Y') - 1) . date('-01-01');
$to = (date('Y') - 1) . date('-12-31');
}
if (isset($from, $to) && !count($this->errors)) {
$this->context->employee->stats_date_from = $from;
$this->context->employee->stats_date_to = $to;
$this->context->employee->update();
if (!$this->isXmlHttpRequest()) {
Tools::redirectAdmin($_SERVER['REQUEST_URI']);
}
}
}
public function ajaxProcessSetDashboardDateRange()
{
$this->processDateRange();
if ($this->isXmlHttpRequest()) {
if (is_array($this->errors) && count($this->errors)) {
die(json_encode(
array(
'has_errors' => true,
'errors' => array($this->errors),
'date_from' => $this->context->employee->stats_date_from,
'date_to' => $this->context->employee->stats_date_to, )
));
} else {
die(json_encode(
array(
'has_errors' => false,
'date_from' => $this->context->employee->stats_date_from,
'date_to' => $this->context->employee->stats_date_to, )
));
}
}
}
protected function getDate()
{
$year = isset($this->context->cookie->stats_year) ? $this->context->cookie->stats_year : date('Y');
$month = isset($this->context->cookie->stats_month) ? sprintf('%02d', $this->context->cookie->stats_month) : '%';
$day = isset($this->context->cookie->stats_day) ? sprintf('%02d', $this->context->cookie->stats_day) : '%';
return $year . '-' . $month . '-' . $day;
}
}

View File

@@ -0,0 +1,717 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property OrderState $object
*/
class AdminStatusesControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'order_state';
$this->className = 'OrderState';
$this->lang = true;
$this->deleted = false;
$this->colorOnBackground = false;
$this->multishop_context = Shop::CONTEXT_ALL;
$this->imageType = 'gif';
$this->fieldImageSettings = array(
'name' => 'icon',
'dir' => 'os',
);
parent::__construct();
$this->bulk_actions = array('delete' => array('text' => $this->trans('Delete selected', array(), 'Admin.Actions'), 'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning')));
}
public function init()
{
if (Tools::isSubmit('addorder_return_state')) {
$this->display = 'add';
}
if (Tools::isSubmit('updateorder_return_state')) {
$this->display = 'edit';
}
return parent::init();
}
/**
* init all variables to render the order status list.
*/
protected function initOrderStatutsList()
{
$this->fields_list = array(
'id_order_state' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'text-center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'width' => 'auto',
'color' => 'color',
),
'logo' => array(
'title' => $this->trans('Icon', array(), 'Admin.Shopparameters.Feature'),
'align' => 'text-center',
'image' => 'os',
'orderby' => false,
'search' => false,
'class' => 'fixed-width-xs',
),
'send_email' => array(
'title' => $this->trans('Send email to customer', array(), 'Admin.Shopparameters.Feature'),
'align' => 'text-center',
'active' => 'sendEmail',
'type' => 'bool',
'ajax' => true,
'orderby' => false,
'class' => 'fixed-width-sm',
),
'delivery' => array(
'title' => $this->trans('Delivery', array(), 'Admin.Global'),
'align' => 'text-center',
'active' => 'delivery',
'type' => 'bool',
'ajax' => true,
'orderby' => false,
'class' => 'fixed-width-sm',
),
'invoice' => array(
'title' => $this->trans('Invoice', array(), 'Admin.Global'),
'align' => 'text-center',
'active' => 'invoice',
'type' => 'bool',
'ajax' => true,
'orderby' => false,
'class' => 'fixed-width-sm',
),
'template' => array(
'title' => $this->trans('Email template', array(), 'Admin.Shopparameters.Feature'),
),
);
}
/**
* init all variables to render the order return list.
*/
protected function initOrdersReturnsList()
{
$this->table = 'order_return_state';
$this->className = 'OrderReturnState';
$this->_defaultOrderBy = $this->identifier = 'id_order_return_state';
$this->list_id = 'order_return_state';
$this->deleted = false;
$this->_orderBy = null;
$this->fields_list = array(
'id_order_return_state' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'align' => 'left',
'width' => 'auto',
'color' => 'color',
),
);
}
protected function initOrderReturnsForm()
{
$id_order_return_state = (int) Tools::getValue('id_order_return_state');
// Create Object OrderReturnState
$order_return_state = new OrderReturnState($id_order_return_state);
//init field form variable for order return form
$this->fields_form = array();
//$this->initToolbar();
$this->getlanguages();
$helper = new HelperForm();
$helper->currentIndex = self::$currentIndex;
$helper->token = $this->token;
$helper->table = 'order_return_state';
$helper->identifier = 'id_order_return_state';
$helper->id = $order_return_state->id;
$helper->toolbar_scroll = false;
$helper->languages = $this->_languages;
$helper->default_form_language = $this->default_form_language;
$helper->allow_employee_form_lang = $this->allow_employee_form_lang;
if ($order_return_state->id) {
$helper->fields_value = array(
'name' => $this->getFieldValue($order_return_state, 'name'),
'color' => $this->getFieldValue($order_return_state, 'color'),
);
} else {
$helper->fields_value = array(
'name' => $this->getFieldValue($order_return_state, 'name'),
'color' => '#ffffff',
);
}
$helper->toolbar_btn = $this->toolbar_btn;
$helper->title = $this->trans('Edit return status', array(), 'Admin.Shopparameters.Feature');
return $helper;
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_order_state'] = array(
'href' => self::$currentIndex . '&addorder_state&token=' . $this->token,
'desc' => $this->trans('Add new order status', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
$this->page_header_toolbar_btn['new_order_return_state'] = array(
'href' => self::$currentIndex . '&addorder_return_state&token=' . $this->token,
'desc' => $this->trans('Add new order return status', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
/**
* Function used to render the list to display for this controller.
*/
public function renderList()
{
//init and render the first list
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->addRowActionSkipList('delete', $this->getUnremovableStatuses());
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->initOrderStatutsList();
$lists = parent::renderList();
//init and render the second list
$this->list_skip_actions = array();
$this->_filter = false;
$this->addRowActionSkipList('delete', array(1, 2, 3, 4, 5));
$this->initOrdersReturnsList();
$this->checkFilterForOrdersReturnsList();
// call postProcess() to take care of actions and filters
$this->postProcess();
$this->toolbar_title = $this->trans('Return statuses', array(), 'Admin.Shopparameters.Feature');
parent::initToolbar();
$lists .= parent::renderList();
return $lists;
}
protected function getUnremovableStatuses()
{
return array_map(function ($row) {
return (int) $row['id_order_state'];
}, Db::getInstance()->executeS('SELECT id_order_state FROM ' . _DB_PREFIX_ . 'order_state WHERE unremovable = 1'));
}
protected function checkFilterForOrdersReturnsList()
{
// test if a filter is applied for this list
if (Tools::isSubmit('submitFilter' . $this->table) || $this->context->cookie->{'submitFilter' . $this->table} !== false) {
$this->filter = true;
}
// test if a filter reset request is required for this list
if (isset($_POST['submitReset' . $this->table])) {
$this->action = 'reset_filters';
} else {
$this->action = '';
}
}
public function renderForm()
{
$this->fields_form = array(
'tinymce' => true,
'legend' => array(
'title' => $this->trans('Order status', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-time',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Status name', array(), 'Admin.Shopparameters.Feature'),
'name' => 'name',
'lang' => true,
'required' => true,
'hint' => array(
$this->trans('Order status (e.g. \'Pending\').', array(), 'Admin.Shopparameters.Help'),
$this->trans('Invalid characters: numbers and', array(), 'Admin.Shopparameters.Help') . ' !<>,;?=+()@#"{}_$%:',
),
),
array(
'type' => 'file',
'label' => $this->trans('Icon', array(), 'Admin.Shopparameters.Feature'),
'name' => 'icon',
'hint' => $this->trans('Upload an icon from your computer (File type: .gif, suggested size: 16x16).', array(), 'Admin.Shopparameters.Help'),
),
array(
'type' => 'color',
'label' => $this->trans('Color', array(), 'Admin.Shopparameters.Feature'),
'name' => 'color',
'hint' => $this->trans('Status will be highlighted in this color. HTML colors only.', array(), 'Admin.Shopparameters.Help') . ' "lightblue", "#CC6600")',
),
array(
'type' => 'checkbox',
'name' => 'logable',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Consider the associated order as validated.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'checkbox',
'name' => 'invoice',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Allow a customer to download and view PDF versions of his/her invoices.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'checkbox',
'name' => 'hidden',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Hide this status in all customer orders.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'checkbox',
'name' => 'send_email',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Send an email to the customer when his/her order status has changed.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'checkbox',
'name' => 'pdf_invoice',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Attach invoice PDF to email.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'checkbox',
'name' => 'pdf_delivery',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Attach delivery slip PDF to email.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'checkbox',
'name' => 'shipped',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Set the order as shipped.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'checkbox',
'name' => 'paid',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Set the order as paid.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'checkbox',
'name' => 'delivery',
'values' => array(
'query' => array(
array('id' => 'on', 'name' => $this->trans('Show delivery PDF.', array(), 'Admin.Shopparameters.Feature'), 'val' => '1'),
),
'id' => 'id',
'name' => 'name',
),
),
array(
'type' => 'select_template',
'label' => $this->trans('Template', array(), 'Admin.Shopparameters.Feature'),
'name' => 'template',
'lang' => true,
'options' => array(
'query' => $this->getTemplates(),
'id' => 'id',
'name' => 'name',
'folder' => 'folder',
),
'hint' => array(
$this->trans('Only letters, numbers and underscores ("_") are allowed.', array(), 'Admin.Shopparameters.Help'),
$this->trans('Email template for both .html and .txt.', array(), 'Admin.Shopparameters.Help'),
),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
if (Tools::isSubmit('updateorder_state') || Tools::isSubmit('addorder_state')) {
return $this->renderOrderStatusForm();
} elseif (Tools::isSubmit('updateorder_return_state') || Tools::isSubmit('addorder_return_state')) {
return $this->renderOrderReturnsForm();
} else {
return parent::renderForm();
}
}
protected function renderOrderStatusForm()
{
if (!($obj = $this->loadObject(true))) {
return;
}
$this->fields_value = array(
'logable_on' => $this->getFieldValue($obj, 'logable'),
'invoice_on' => $this->getFieldValue($obj, 'invoice'),
'hidden_on' => $this->getFieldValue($obj, 'hidden'),
'send_email_on' => $this->getFieldValue($obj, 'send_email'),
'shipped_on' => $this->getFieldValue($obj, 'shipped'),
'paid_on' => $this->getFieldValue($obj, 'paid'),
'delivery_on' => $this->getFieldValue($obj, 'delivery'),
'pdf_delivery_on' => $this->getFieldValue($obj, 'pdf_delivery'),
'pdf_invoice_on' => $this->getFieldValue($obj, 'pdf_invoice'),
);
if ($this->getFieldValue($obj, 'color') !== false) {
$this->fields_value['color'] = $this->getFieldValue($obj, 'color');
} else {
$this->fields_value['color'] = '#ffffff';
}
return parent::renderForm();
}
protected function renderOrderReturnsForm()
{
$helper = $this->initOrderReturnsForm();
$helper->show_cancel_button = true;
$back = Tools::safeOutput(Tools::getValue('back', ''));
if (empty($back)) {
$back = self::$currentIndex . '&token=' . $this->token;
}
if (!Validate::isCleanHtml($back)) {
die(Tools::displayError());
}
$helper->back_url = $back;
$this->fields_form[0]['form'] = array(
'tinymce' => true,
'legend' => array(
'title' => $this->trans('Return status', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-time',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Status name', array(), 'Admin.Shopparameters.Feature'),
'name' => 'name',
'lang' => true,
'required' => true,
'hint' => array(
$this->trans('Order\'s return status name.', array(), 'Admin.Shopparameters.Help'),
$this->trans('Invalid characters: numbers and', array(), 'Admin.Shopparameters.Help') . ' !<>,;?=+()@#"<22>{}_$%:',
),
),
array(
'type' => 'color',
'label' => $this->trans('Color', array(), 'Admin.Shopparameters.Feature'),
'name' => 'color',
'hint' => $this->trans('Status will be highlighted in this color. HTML colors only.', array(), 'Admin.Shopparameters.Help') . ' "lightblue", "#CC6600")',
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
return $helper->generateForm($this->fields_form);
}
protected function getTemplates()
{
$default_path = '../mails/';
// Mail templates can also be found in the theme folder
$theme_path = '../themes/' . $this->context->shop->theme->getName() . '/mails/';
$array = array();
foreach (Language::getLanguages(false) as $language) {
$iso_code = $language['iso_code'];
// If there is no folder for the given iso_code in /mails or in /themes/[theme_name]/mails, we bypass this language
if (!@filemtime(_PS_ADMIN_DIR_ . '/' . $default_path . $iso_code) && !@filemtime(_PS_ADMIN_DIR_ . '/' . $theme_path . $iso_code)) {
continue;
}
$theme_templates_dir = _PS_ADMIN_DIR_ . '/' . $theme_path . $iso_code;
$theme_templates = is_dir($theme_templates_dir) ? scandir($theme_templates_dir, SCANDIR_SORT_NONE) : array();
// We merge all available emails in one array
$templates = array_unique(array_merge(scandir(_PS_ADMIN_DIR_ . '/' . $default_path . $iso_code, SCANDIR_SORT_NONE), $theme_templates));
foreach ($templates as $key => $template) {
if (!strncmp(strrev($template), 'lmth.', 5)) {
$search_result = array_search($template, $theme_templates);
$array[$iso_code][] = array(
'id' => substr($template, 0, -5),
'name' => substr($template, 0, -5),
'folder' => ((!empty($search_result) ? $theme_path : $default_path)),
);
}
}
}
return $array;
}
public function postProcess()
{
if (Tools::isSubmit($this->table . 'Orderby') || Tools::isSubmit($this->table . 'Orderway')) {
$this->filter = true;
}
if (Tools::isSubmit('submitAddorder_return_state')) {
if (!$this->access('add')) {
return;
}
$id_order_return_state = Tools::getValue('id_order_return_state');
// Create Object OrderReturnState
$order_return_state = new OrderReturnState((int) $id_order_return_state);
$order_return_state->color = Tools::getValue('color');
$order_return_state->name = array();
foreach (Language::getIDs(false) as $id_lang) {
$order_return_state->name[$id_lang] = Tools::getValue('name_' . $id_lang);
}
// Update object
if (!$order_return_state->save()) {
$this->errors[] = $this->trans('An error has occurred: Can\'t save the current order\'s return status.', array(), 'Admin.Orderscustomers.Notification');
} else {
Tools::redirectAdmin(self::$currentIndex . '&conf=4&token=' . $this->token);
}
}
if (Tools::isSubmit('submitBulkdeleteorder_return_state')) {
if (!$this->access('delete')) {
return;
}
$this->className = 'OrderReturnState';
$this->table = 'order_return_state';
$this->boxes = Tools::getValue('order_return_stateBox');
parent::processBulkDelete();
}
if (Tools::isSubmit('deleteorder_return_state')) {
if (!$this->access('delete')) {
return;
}
$id_order_return_state = Tools::getValue('id_order_return_state');
// Create Object OrderReturnState
$order_return_state = new OrderReturnState((int) $id_order_return_state);
if (!$order_return_state->delete()) {
$this->errors[] = $this->trans('An error has occurred: Can\'t delete the current order\'s return status.', array(), 'Admin.Orderscustomers.Notification');
} else {
Tools::redirectAdmin(self::$currentIndex . '&conf=1&token=' . $this->token);
}
}
if (Tools::isSubmit('submitAdd' . $this->table)) {
if (!$this->access('add')) {
return;
}
$this->deleted = false; // Disabling saving historisation
$_POST['invoice'] = (int) Tools::getValue('invoice_on');
$_POST['logable'] = (int) Tools::getValue('logable_on');
$_POST['send_email'] = (int) Tools::getValue('send_email_on');
$_POST['hidden'] = (int) Tools::getValue('hidden_on');
$_POST['shipped'] = (int) Tools::getValue('shipped_on');
$_POST['paid'] = (int) Tools::getValue('paid_on');
$_POST['delivery'] = (int) Tools::getValue('delivery_on');
$_POST['pdf_delivery'] = (int) Tools::getValue('pdf_delivery_on');
$_POST['pdf_invoice'] = (int) Tools::getValue('pdf_invoice_on');
if (!$_POST['send_email']) {
foreach (Language::getIDs(false) as $id_lang) {
$_POST['template_' . $id_lang] = '';
}
}
return parent::postProcess();
} elseif (Tools::isSubmit('delete' . $this->table)) {
if (!$this->access('delete')) {
return;
}
$order_state = new OrderState(Tools::getValue('id_order_state'), $this->context->language->id);
if (!$order_state->isRemovable()) {
$this->errors[] = $this->trans('For security reasons, you cannot delete default order statuses.', array(), 'Admin.Shopparameters.Notification');
} else {
return parent::postProcess();
}
} elseif (Tools::isSubmit('submitBulkdelete' . $this->table)) {
if (!$this->access('delete')) {
return;
}
foreach (Tools::getValue($this->table . 'Box') as $selection) {
$order_state = new OrderState((int) $selection, $this->context->language->id);
if (!$order_state->isRemovable()) {
$this->errors[] = $this->trans('For security reasons, you cannot delete default order statuses.', array(), 'Admin.Shopparameters.Notification');
break;
}
}
if (!count($this->errors)) {
return parent::postProcess();
}
} else {
return parent::postProcess();
}
}
protected function filterToField($key, $filter)
{
if ($this->table == 'order_state') {
$this->initOrderStatutsList();
} elseif ($this->table == 'order_return_state') {
$this->initOrdersReturnsList();
}
return parent::filterToField($key, $filter);
}
protected function afterImageUpload()
{
parent::afterImageUpload();
if (($id_order_state = (int) Tools::getValue('id_order_state')) &&
isset($_FILES) && count($_FILES) && file_exists(_PS_ORDER_STATE_IMG_DIR_ . $id_order_state . '.gif')) {
$current_file = _PS_TMP_IMG_DIR_ . 'order_state_mini_' . $id_order_state . '_' . $this->context->shop->id . '.gif';
if (file_exists($current_file)) {
unlink($current_file);
}
}
return true;
}
public function ajaxProcessSendEmailOrderState()
{
$id_order_state = (int) Tools::getValue('id_order_state');
$sql = 'UPDATE ' . _DB_PREFIX_ . 'order_state SET `send_email`= NOT `send_email` WHERE id_order_state=' . $id_order_state;
$result = Db::getInstance()->execute($sql);
if ($result) {
echo json_encode(array('success' => 1, 'text' => $this->trans('The status has been updated successfully.', array(), 'Admin.Notifications.Success')));
} else {
echo json_encode(array('success' => 0, 'text' => $this->trans('An error occurred while updating the status.', array(), 'Admin.Notifications.Error')));
}
}
public function ajaxProcessDeliveryOrderState()
{
$id_order_state = (int) Tools::getValue('id_order_state');
$sql = 'UPDATE ' . _DB_PREFIX_ . 'order_state SET `delivery`= NOT `delivery` WHERE id_order_state=' . $id_order_state;
$result = Db::getInstance()->execute($sql);
if ($result) {
echo json_encode(array('success' => 1, 'text' => $this->trans('The status has been updated successfully.', array(), 'Admin.Notifications.Success')));
} else {
echo json_encode(array('success' => 0, 'text' => $this->trans('An error occurred while updating the status.', array(), 'Admin.Notifications.Error')));
}
}
public function ajaxProcessInvoiceOrderState()
{
$id_order_state = (int) Tools::getValue('id_order_state');
$sql = 'UPDATE ' . _DB_PREFIX_ . 'order_state SET `invoice`= NOT `invoice` WHERE id_order_state=' . $id_order_state;
$result = Db::getInstance()->execute($sql);
if ($result) {
echo json_encode(array('success' => 1, 'text' => $this->trans('The status has been updated successfully.', array(), 'Admin.Notifications.Success')));
} else {
echo json_encode(array('success' => 0, 'text' => $this->trans('An error occurred while updating the status.', array(), 'Admin.Notifications.Error')));
}
}
}

View File

@@ -0,0 +1,604 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Store $object
*/
class AdminStoresControllerCore extends AdminController
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'store';
$this->className = 'Store';
$this->lang = false;
$this->toolbar_scroll = false;
parent::__construct();
if (!Tools::getValue('realedit')) {
$this->deleted = false;
}
$this->fieldImageSettings = array(
'name' => 'image',
'dir' => 'st',
);
$this->fields_list = array(
'id_store' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'align' => 'center', 'class' => 'fixed-width-xs'),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'filter_key' => 'sl!name'),
'address1' => array('title' => $this->trans('Address', array(), 'Admin.Global'), 'filter_key' => 'sl!address1'),
'city' => array('title' => $this->trans('City', array(), 'Admin.Global')),
'postcode' => array('title' => $this->trans('Zip/postal code', array(), 'Admin.Global')),
'state' => array('title' => $this->trans('State', array(), 'Admin.Global'), 'filter_key' => 'st!name'),
'country' => array('title' => $this->trans('Country', array(), 'Admin.Global'), 'filter_key' => 'cl!name'),
'phone' => array('title' => $this->trans('Phone', array(), 'Admin.Global')),
'fax' => array('title' => $this->trans('Fax', array(), 'Admin.Global')),
'active' => array('title' => $this->trans('Enabled', array(), 'Admin.Global'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->_buildOrderedFieldsShop($this->_getDefaultFieldsContent());
}
public function renderOptions()
{
// Set toolbar options
$this->display = 'options';
$this->show_toolbar = true;
$this->toolbar_scroll = true;
$this->initToolbar();
return parent::renderOptions();
}
public function initToolbar()
{
parent::initToolbar();
if ($this->display == 'options') {
unset($this->toolbar_btn['new']);
} elseif ($this->display != 'add' && $this->display != 'edit') {
unset($this->toolbar_btn['save']);
}
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_store'] = array(
'href' => self::$currentIndex . '&addstore&token=' . $this->token,
'desc' => $this->trans('Add new store', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderList()
{
// Set toolbar options
$this->display = null;
$this->initToolbar();
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_select = 'cl.`name` country, st.`name` state, sl.*';
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'country_lang` cl
ON (cl.`id_country` = a.`id_country`
AND cl.`id_lang` = ' . (int) $this->context->language->id . ')
LEFT JOIN `' . _DB_PREFIX_ . 'state` st
ON (st.`id_state` = a.`id_state`)
LEFT JOIN `' . _DB_PREFIX_ . 'store_lang` sl
ON (sl.`id_store` = a.`id_store`
AND sl.`id_lang` = ' . (int) $this->context->language->id . ') ';
return parent::renderList();
}
public function renderForm()
{
if (!($obj = $this->loadObject(true))) {
return;
}
$image = _PS_STORE_IMG_DIR_ . $obj->id . '.jpg';
$image_url = ImageManager::thumbnail(
$image,
$this->table . '_' . (int) $obj->id . '.' . $this->imageType,
350,
$this->imageType,
true,
true
);
$image_size = file_exists($image) ? filesize($image) / 1000 : false;
$tmp_addr = new Address();
$res = $tmp_addr->getFieldsRequiredDatabase();
$required_fields = array();
foreach ($res as $row) {
$required_fields[(int) $row['id_required_field']] = $row['field_name'];
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Stores', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-home',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'required' => false,
'hint' => array(
$this->trans('Store name (e.g. City Center Mall Store).', array(), 'Admin.Shopparameters.Feature'),
$this->trans('Allowed characters: letters, spaces and %s', array(), 'Admin.Shopparameters.Feature'),
),
),
array(
'type' => 'text',
'label' => $this->trans('Address', array(), 'Admin.Global'),
'name' => 'address1',
'lang' => true,
'required' => true,
),
array(
'type' => 'text',
'label' => $this->trans('Address (2)', array(), 'Admin.Global'),
'name' => 'address2',
'lang' => true,
),
array(
'type' => 'text',
'label' => $this->trans('Zip/postal code', array(), 'Admin.Global'),
'name' => 'postcode',
'required' => in_array('postcode', $required_fields),
),
array(
'type' => 'text',
'label' => $this->trans('City', array(), 'Admin.Global'),
'name' => 'city',
'required' => true,
),
array(
'type' => 'select',
'label' => $this->trans('Country', array(), 'Admin.Global'),
'name' => 'id_country',
'required' => true,
'default_value' => (int) $this->context->country->id,
'options' => array(
'query' => Country::getCountries($this->context->language->id),
'id' => 'id_country',
'name' => 'name',
),
),
array(
'type' => 'select',
'label' => $this->trans('State', array(), 'Admin.Global'),
'name' => 'id_state',
'required' => true,
'options' => array(
'id' => 'id_state',
'name' => 'name',
'query' => null,
),
),
array(
'type' => 'latitude',
'label' => $this->trans('Latitude / Longitude', array(), 'Admin.Shopparameters.Feature'),
'name' => 'latitude',
'required' => true,
'maxlength' => 12,
'hint' => $this->trans('Store coordinates (e.g. 45.265469/-47.226478).', array(), 'Admin.Shopparameters.Feature'),
),
array(
'type' => 'text',
'label' => $this->trans('Phone', array(), 'Admin.Global'),
'name' => 'phone',
),
array(
'type' => 'text',
'label' => $this->trans('Fax', array(), 'Admin.Global'),
'name' => 'fax',
),
array(
'type' => 'text',
'label' => $this->trans('Email address', array(), 'Admin.Global'),
'name' => 'email',
),
array(
'type' => 'textarea',
'label' => $this->trans('Note', array(), 'Admin.Global'),
'name' => 'note',
'lang' => true,
'cols' => 42,
'rows' => 4,
),
array(
'type' => 'switch',
'label' => $this->trans('Active', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
'hint' => $this->trans('Whether or not to display this store.', array(), 'Admin.Shopparameters.Help'),
),
array(
'type' => 'file',
'label' => $this->trans('Picture', array(), 'Admin.Shopparameters.Feature'),
'name' => 'image',
'display_image' => true,
'image' => $image_url ? $image_url : false,
'size' => $image_size,
'hint' => $this->trans('Storefront picture.', array(), 'Admin.Shopparameters.Help'),
),
),
'hours' => array(
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$days = array();
$days[1] = $this->trans('Monday', array(), 'Admin.Shopparameters.Feature');
$days[2] = $this->trans('Tuesday', array(), 'Admin.Shopparameters.Feature');
$days[3] = $this->trans('Wednesday', array(), 'Admin.Shopparameters.Feature');
$days[4] = $this->trans('Thursday', array(), 'Admin.Shopparameters.Feature');
$days[5] = $this->trans('Friday', array(), 'Admin.Shopparameters.Feature');
$days[6] = $this->trans('Saturday', array(), 'Admin.Shopparameters.Feature');
$days[7] = $this->trans('Sunday', array(), 'Admin.Shopparameters.Feature');
$hours = array();
$hours_temp = ($this->getFieldValue($obj, 'hours'));
if (is_array($hours_temp) && !empty($hours_temp)) {
$langs = Language::getLanguages(false);
$hours_temp = array_map('json_decode', $hours_temp);
$hours = array_map(
array($this, 'adaptHoursFormat'),
$hours_temp
);
$hours = (count($langs) > 1) ? $hours : $hours[reset($langs)['id_lang']];
}
$this->fields_value = array(
'latitude' => $this->getFieldValue($obj, 'latitude') ? $this->getFieldValue($obj, 'latitude') : '',
'longitude' => $this->getFieldValue($obj, 'longitude') ? $this->getFieldValue($obj, 'longitude') : '',
'days' => $days,
'hours' => $hours,
);
return parent::renderForm();
}
public function postProcess()
{
if (isset($_POST['submitAdd' . $this->table])) {
$langs = Language::getLanguages(false);
/* Cleaning fields */
foreach ($_POST as $kp => $vp) {
if (!in_array($kp, array('checkBoxShopGroupAsso_store', 'checkBoxShopAsso_store', 'hours'))) {
$_POST[$kp] = trim($vp);
}
if ('hours' === $kp) {
foreach ($vp as $day => $value) {
$_POST['hours'][$day] = is_array($value) ? array_map('trim', $_POST['hours'][$day]) : trim($value);
}
}
}
/* Rewrite latitude and longitude to 8 digits */
$_POST['latitude'] = number_format((float) $_POST['latitude'], 8);
$_POST['longitude'] = number_format((float) $_POST['longitude'], 8);
/* If the selected country does not contain states */
$id_state = (int) Tools::getValue('id_state');
$id_country = (int) Tools::getValue('id_country');
$country = new Country((int) $id_country);
if ($id_country && $country && !(int) $country->contains_states && $id_state) {
$this->errors[] = $this->trans('You\'ve selected a state for a country that does not contain states.', array(), 'Admin.Advparameters.Notification');
}
/* If the selected country contains states, then a state have to be selected */
if ((int) $country->contains_states && !$id_state) {
$this->errors[] = $this->trans('An address located in a country containing states must have a state selected.', array(), 'Admin.Shopparameters.Notification');
}
$latitude = (float) Tools::getValue('latitude');
$longitude = (float) Tools::getValue('longitude');
if (empty($latitude) || empty($longitude)) {
$this->errors[] = $this->trans('Latitude and longitude are required.', array(), 'Admin.Shopparameters.Notification');
}
$postcode = Tools::getValue('postcode');
/* Check zip code format */
if ($country->zip_code_format && !$country->checkZipCode($postcode)) {
$this->errors[] = $this->trans('Your Zip/postal code is incorrect.', array(), 'Admin.Notifications.Error') . '<br />' . $this->trans('It must be entered as follows:', array(), 'Admin.Notifications.Error') . ' ' . str_replace('C', $country->iso_code, str_replace('N', '0', str_replace('L', 'A', $country->zip_code_format)));
} elseif (empty($postcode) && $country->need_zip_code) {
$this->errors[] = $this->trans('A Zip/postal code is required.', array(), 'Admin.Notifications.Error');
} elseif ($postcode && !Validate::isPostCode($postcode)) {
$this->errors[] = $this->trans('The Zip/postal code is invalid.', array(), 'Admin.Notifications.Error');
}
/* Store hours */
foreach ($langs as $lang) {
$hours = array();
for ($i = 1; $i < 8; ++$i) {
if (1 < count($langs)) {
$hours[] = explode(' | ', $_POST['hours'][$i][$lang['id_lang']]);
unset($_POST['hours'][$i][$lang['id_lang']]);
} else {
$hours[] = explode(' | ', $_POST['hours'][$i]);
unset($_POST['hours'][$i]);
}
}
$encodedHours[$lang['id_lang']] = json_encode($hours);
}
$_POST['hours'] = (1 < count($langs)) ? $encodedHours : json_encode($hours);
}
if (!count($this->errors)) {
parent::postProcess();
} else {
$this->display = 'add';
}
}
protected function postImage($id)
{
$ret = parent::postImage($id);
$generate_hight_dpi_images = (bool) Configuration::get('PS_HIGHT_DPI');
if (($id_store = (int) Tools::getValue('id_store')) && isset($_FILES) && count($_FILES) && file_exists(_PS_STORE_IMG_DIR_ . $id_store . '.jpg')) {
$images_types = ImageType::getImagesTypes('stores');
foreach ($images_types as $image_type) {
ImageManager::resize(
_PS_STORE_IMG_DIR_ . $id_store . '.jpg',
_PS_STORE_IMG_DIR_ . $id_store . '-' . stripslashes($image_type['name']) . '.jpg',
(int) $image_type['width'],
(int) $image_type['height']
);
if ($generate_hight_dpi_images) {
ImageManager::resize(
_PS_STORE_IMG_DIR_ . $id_store . '.jpg',
_PS_STORE_IMG_DIR_ . $id_store . '-' . stripslashes($image_type['name']) . '2x.jpg',
(int) $image_type['width'] * 2,
(int) $image_type['height'] * 2
);
}
}
}
return $ret;
}
protected function _getDefaultFieldsContent()
{
$this->context = Context::getContext();
$countryList = array();
$countryList[] = array('id' => '0', 'name' => $this->trans('Choose your country', array(), 'Admin.Shopparameters.Feature'));
foreach (Country::getCountries($this->context->language->id) as $country) {
$countryList[] = array('id' => $country['id_country'], 'name' => $country['name']);
}
$stateList = array();
$stateList[] = array('id' => '0', 'name' => $this->trans('Choose your state (if applicable)', array(), 'Admin.Shopparameters.Feature'));
foreach (State::getStates($this->context->language->id) as $state) {
$stateList[] = array('id' => $state['id_state'], 'name' => $state['name']);
}
$formFields = array(
'PS_SHOP_NAME' => array(
'title' => $this->trans('Shop name', array(), 'Admin.Shopparameters.Feature'),
'hint' => $this->trans('Displayed in emails and page titles.', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isGenericName',
'required' => true,
'type' => 'text',
'no_escape' => true,
),
'PS_SHOP_EMAIL' => array('title' => $this->trans('Shop email', array(), 'Admin.Shopparameters.Feature'),
'hint' => $this->trans('Displayed in emails sent to customers.', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isEmail',
'required' => true,
'type' => 'text',
),
'PS_SHOP_DETAILS' => array(
'title' => $this->trans('Registration number', array(), 'Admin.Shopparameters.Feature'),
'hint' => $this->trans('Shop registration information (e.g. SIRET or RCS).', array(), 'Admin.Shopparameters.Help'),
'validation' => 'isGenericName',
'type' => 'textarea',
'cols' => 30,
'rows' => 5,
),
'PS_SHOP_ADDR1' => array(
'title' => $this->trans('Shop address line 1', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isAddress',
'type' => 'text',
),
'PS_SHOP_ADDR2' => array(
'title' => $this->trans('Shop address line 2', array(), 'Admin.Shopparameters.Feature'),
'validation' => 'isAddress',
'type' => 'text',
),
'PS_SHOP_CODE' => array(
'title' => $this->trans('Zip/postal code', array(), 'Admin.Global'),
'validation' => 'isGenericName',
'type' => 'text',
),
'PS_SHOP_CITY' => array(
'title' => $this->trans('City', array(), 'Admin.Global'),
'validation' => 'isGenericName',
'type' => 'text',
),
'PS_SHOP_COUNTRY_ID' => array(
'title' => $this->trans('Country', array(), 'Admin.Global'),
'validation' => 'isInt',
'type' => 'select',
'list' => $countryList,
'identifier' => 'id',
'cast' => 'intval',
'defaultValue' => (int) $this->context->country->id,
),
'PS_SHOP_STATE_ID' => array(
'title' => $this->trans('State', array(), 'Admin.Global'),
'validation' => 'isInt',
'type' => 'select',
'list' => $stateList,
'identifier' => 'id',
'cast' => 'intval',
),
'PS_SHOP_PHONE' => array(
'title' => $this->trans('Phone', array(), 'Admin.Global'),
'validation' => 'isGenericName',
'type' => 'text',
),
'PS_SHOP_FAX' => array(
'title' => $this->trans('Fax', array(), 'Admin.Global'),
'validation' => 'isGenericName',
'type' => 'text',
),
);
return $formFields;
}
protected function _buildOrderedFieldsShop($formFields)
{
// You cannot do that, because the fields must be sorted for the country you've selected.
// Simple example: the current country is France, where we don't display the state. You choose "US" as a country in the form. The state is not dsplayed at the right place...
// $associatedOrderKey = array(
// 'PS_SHOP_NAME' => 'company',
// 'PS_SHOP_ADDR1' => 'address1',
// 'PS_SHOP_ADDR2' => 'address2',
// 'PS_SHOP_CITY' => 'city',
// 'PS_SHOP_STATE_ID' => 'State:name',
// 'PS_SHOP_CODE' => 'postcode',
// 'PS_SHOP_COUNTRY_ID' => 'Country:name',
// 'PS_SHOP_PHONE' => 'phone');
// $fields = array();
// $orderedFields = AddressFormat::getOrderedAddressFields(Configuration::get('PS_SHOP_COUNTRY_ID'), false, true);
// foreach ($orderedFields as $lineFields)
// if (($patterns = explode(' ', $lineFields)))
// foreach ($patterns as $pattern)
// if (($key = array_search($pattern, $associatedOrderKey)))
// $fields[$key] = $formFields[$key];
// foreach ($formFields as $key => $value)
// if (!isset($fields[$key]))
// $fields[$key] = $formFields[$key];
$fields = $formFields;
$this->fields_options['contact'] = array(
'title' => $this->trans('Contact details', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-user',
'fields' => $fields,
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
);
}
public function beforeUpdateOptions()
{
if (isset($_POST['PS_SHOP_STATE_ID']) && $_POST['PS_SHOP_STATE_ID'] != '0') {
$sql = 'SELECT `active` FROM `' . _DB_PREFIX_ . 'state`
WHERE `id_country` = ' . (int) Tools::getValue('PS_SHOP_COUNTRY_ID') . '
AND `id_state` = ' . (int) Tools::getValue('PS_SHOP_STATE_ID');
$isStateOk = Db::getInstance()->getValue($sql);
if ($isStateOk != 1) {
$this->errors[] = $this->trans('The specified state is not located in this country.', array(), 'Admin.Shopparameters.Notification');
}
}
}
public function updateOptionPsShopCountryId($value)
{
if (!$this->errors && $value) {
$country = new Country($value, $this->context->language->id);
if ($country->id) {
Configuration::updateValue('PS_SHOP_COUNTRY_ID', $value);
Configuration::updateValue('PS_SHOP_COUNTRY', pSQL($country->name));
}
}
}
public function updateOptionPsShopStateId($value)
{
if (!$this->errors && $value) {
$state = new State($value);
if ($state->id) {
Configuration::updateValue('PS_SHOP_STATE_ID', $value);
Configuration::updateValue('PS_SHOP_STATE', pSQL($state->name));
}
}
}
/**
* Adapt the format of hours.
*
* @param array $value
*
* @return array
*/
protected function adaptHoursFormat($value)
{
$separator = array_fill(0, count($value), ' | ');
return array_map('implode', $value, $separator);
}
}

View File

@@ -0,0 +1,593 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Supplier $object
*/
class AdminSuppliersControllerCore extends AdminController
{
public $bootstrap = true;
public function __construct()
{
$this->table = 'supplier';
$this->className = 'Supplier';
parent::__construct();
$this->addRowAction('view');
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->allow_export = true;
$this->_defaultOrderBy = 'name';
$this->_defaultOrderWay = 'ASC';
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'icon' => 'icon-trash',
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
),
);
$this->_select = 'COUNT(DISTINCT ps.`id_product`) AS products';
$this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'product_supplier` ps ON (a.`id_supplier` = ps.`id_supplier`)';
$this->_group = 'GROUP BY a.`id_supplier`';
$this->fieldImageSettings = array('name' => 'logo', 'dir' => 'su');
$this->fields_list = array(
'id_supplier' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'align' => 'center', 'class' => 'fixed-width-xs'),
'logo' => array('title' => $this->trans('Logo', array(), 'Admin.Global'), 'align' => 'center', 'image' => 'su', 'orderby' => false, 'search' => false),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global')),
'products' => array('title' => $this->trans('Number of products', array(), 'Admin.Catalog.Feature'), 'align' => 'right', 'filter_type' => 'int', 'tmpTableFilter' => true),
'active' => array('title' => $this->trans('Enabled', array(), 'Admin.Global'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false, 'class' => 'fixed-width-xs'),
);
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJqueryUi('ui.widget');
$this->addJqueryPlugin('tagify');
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_supplier'] = array(
'href' => self::$currentIndex . '&addsupplier&token=' . $this->token,
'desc' => $this->trans('Add new supplier', array(), 'Admin.Catalog.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderForm()
{
// loads current warehouse
if (!($obj = $this->loadObject(true))) {
return;
}
$image = _PS_SUPP_IMG_DIR_ . $obj->id . '.jpg';
$image_url = ImageManager::thumbnail(
$image,
$this->table . '_' . (int) $obj->id . '.' . $this->imageType,
350,
$this->imageType,
true,
true
);
$image_size = file_exists($image) ? filesize($image) / 1000 : false;
$tmp_addr = new Address();
$res = $tmp_addr->getFieldsRequiredDatabase();
$required_fields = array();
foreach ($res as $row) {
$required_fields[(int) $row['id_required_field']] = $row['field_name'];
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Suppliers', array(), 'Admin.Global'),
'icon' => 'icon-truck',
),
'input' => array(
array(
'type' => 'hidden',
'name' => 'id_address',
),
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'required' => true,
'col' => 4,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
(
in_array('company', $required_fields) ?
array(
'type' => 'text',
'label' => $this->trans('Company', array(), 'Admin.Global'),
'name' => 'company',
'display' => in_array('company', $required_fields),
'required' => in_array('company', $required_fields),
'maxlength' => 16,
'col' => 4,
'hint' => $this->trans('Company name for this supplier', array(), 'Admin.Catalog.Help'),
)
: null
),
array(
'type' => 'textarea',
'label' => $this->trans('Description', array(), 'Admin.Global'),
'name' => 'description',
'lang' => true,
'hint' => array(
$this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
$this->trans('Will appear in the list of suppliers.', array(), 'Admin.Catalog.Help'),
),
'autoload_rte' => 'rte', //Enable TinyMCE editor for short description
),
array(
'type' => 'text',
'label' => $this->trans('Phone', array(), 'Admin.Global'),
'name' => 'phone',
'required' => in_array('phone', $required_fields),
'maxlength' => 16,
'col' => 4,
'hint' => $this->trans('Phone number for this supplier', array(), 'Admin.Catalog.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Mobile phone', array(), 'Admin.Global'),
'name' => 'phone_mobile',
'required' => in_array('phone_mobile', $required_fields),
'maxlength' => 16,
'col' => 4,
'hint' => $this->trans('Mobile phone number for this supplier.', array(), 'Admin.Catalog.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Address', array(), 'Admin.Global'),
'name' => 'address',
'maxlength' => 128,
'col' => 6,
'required' => true,
),
array(
'type' => 'text',
'label' => $this->trans('Address (2)', array(), 'Admin.Global'),
'name' => 'address2',
'required' => in_array('address2', $required_fields),
'col' => 6,
'maxlength' => 128,
),
array(
'type' => 'text',
'label' => $this->trans('Zip/postal code', array(), 'Admin.Global'),
'name' => 'postcode',
'required' => in_array('postcode', $required_fields),
'maxlength' => 12,
'col' => 2,
),
array(
'type' => 'text',
'label' => $this->trans('City', array(), 'Admin.Global'),
'name' => 'city',
'maxlength' => 32,
'col' => 4,
'required' => true,
),
array(
'type' => 'select',
'label' => $this->trans('Country', array(), 'Admin.Global'),
'name' => 'id_country',
'required' => true,
'col' => 4,
'default_value' => (int) $this->context->country->id,
'options' => array(
'query' => Country::getCountries($this->context->language->id, false),
'id' => 'id_country',
'name' => 'name',
),
),
array(
'type' => 'select',
'label' => $this->trans('State', array(), 'Admin.Global'),
'name' => 'id_state',
'col' => 4,
'options' => array(
'id' => 'id_state',
'query' => array(),
'name' => 'name',
),
),
array(
'type' => 'text',
'label' => $this->trans('DNI', array(), 'Admin.Global'),
'name' => 'dni',
'maxlength' => 16,
'col' => 4,
'required' => true, // Only required in case of specifics countries
),
array(
'type' => 'file',
'label' => $this->trans('Logo', array(), 'Admin.Global'),
'name' => 'logo',
'display_image' => true,
'image' => $image_url ? $image_url : false,
'size' => $image_size,
'hint' => $this->trans('Upload a supplier logo from your computer.', array(), 'Admin.Catalog.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Meta title', array(), 'Admin.Global'),
'name' => 'meta_title',
'lang' => true,
'col' => 4,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Meta description', array(), 'Admin.Global'),
'name' => 'meta_description',
'lang' => true,
'col' => 6,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'tags',
'label' => $this->trans('Meta keywords', array(), 'Admin.Global'),
'name' => 'meta_keywords',
'lang' => true,
'col' => 6,
'hint' => array(
$this->trans('To add tags, click in the field, write something, and then press the "Enter" key.', array(), 'Admin.Shopparameters.Help'),
$this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' &lt;&gt;;=#{}',
),
),
array(
'type' => 'switch',
'label' => $this->trans('Enable', array(), 'Admin.Actions'),
'name' => 'active',
'required' => false,
'class' => 't',
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
// loads current address for this supplier - if possible
$address = null;
if (isset($obj->id)) {
$id_address = Address::getAddressIdBySupplierId($obj->id);
if ($id_address > 0) {
$address = new Address((int) $id_address);
}
}
// force specific fields values (address)
if ($address != null) {
$this->fields_value = array(
'id_address' => $address->id,
'phone' => $address->phone,
'phone_mobile' => $address->phone_mobile,
'address' => $address->address1,
'address2' => $address->address2,
'postcode' => $address->postcode,
'city' => $address->city,
'id_country' => $address->id_country,
'id_state' => $address->id_state,
'dni' => $address->dni,
);
} else {
$this->fields_value = array(
'id_address' => 0,
'id_country' => Configuration::get('PS_COUNTRY_DEFAULT'),
);
}
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
return parent::renderForm();
}
/**
* AdminController::initToolbar() override.
*
* @see AdminController::initToolbar()
*/
public function initToolbar()
{
parent::initToolbar();
$this->addPageHeaderToolBarModulesListButton();
if (empty($this->display) && $this->can_import) {
$this->toolbar_btn['import'] = array(
'href' => $this->context->link->getAdminLink('AdminImport', true) . '&import_type=suppliers',
'desc' => $this->trans('Import', array(), 'Admin.Actions'),
);
}
}
public function renderView()
{
$this->initTabModuleList();
$this->toolbar_title = $this->object->name;
$products = $this->object->getProductsLite($this->context->language->id);
$total_product = count($products);
for ($i = 0; $i < $total_product; ++$i) {
$products[$i] = new Product($products[$i]['id_product'], false, $this->context->language->id);
$products[$i]->loadStockData();
// Build attributes combinations
$combinations = $products[$i]->getAttributeCombinations($this->context->language->id);
foreach ($combinations as $combination) {
$comb_infos = Supplier::getProductInformationsBySupplier(
$this->object->id,
$products[$i]->id,
$combination['id_product_attribute']
);
$comb_array[$combination['id_product_attribute']]['product_supplier_reference'] = $comb_infos['product_supplier_reference'];
$comb_array[$combination['id_product_attribute']]['product_supplier_price_te'] = Tools::displayPrice($comb_infos['product_supplier_price_te'], new Currency($comb_infos['id_currency']));
$comb_array[$combination['id_product_attribute']]['reference'] = $combination['reference'];
$comb_array[$combination['id_product_attribute']]['ean13'] = $combination['ean13'];
$comb_array[$combination['id_product_attribute']]['upc'] = $combination['upc'];
$comb_array[$combination['id_product_attribute']]['quantity'] = $combination['quantity'];
$comb_array[$combination['id_product_attribute']]['attributes'][] = array(
$combination['group_name'],
$combination['attribute_name'],
$combination['id_attribute'],
);
}
if (isset($comb_array)) {
foreach ($comb_array as $key => $product_attribute) {
$list = '';
foreach ($product_attribute['attributes'] as $attribute) {
$list .= $attribute[0] . ' - ' . $attribute[1] . ', ';
}
$comb_array[$key]['attributes'] = rtrim($list, ', ');
}
isset($comb_array) ? $products[$i]->combination = $comb_array : '';
unset($comb_array);
} else {
$product_infos = Supplier::getProductInformationsBySupplier(
$this->object->id,
$products[$i]->id,
0
);
$products[$i]->product_supplier_reference = $product_infos['product_supplier_reference'];
$currencyId = $product_infos['id_currency'] ?: Currency::getDefaultCurrency()->id;
$products[$i]->product_supplier_price_te = Tools::displayPrice($product_infos['product_supplier_price_te'], new Currency($currencyId));
}
}
$this->tpl_view_vars = array(
'supplier' => $this->object,
'products' => $products,
'stock_management' => Configuration::get('PS_STOCK_MANAGEMENT'),
'shopContext' => Shop::getContext(),
);
return parent::renderView();
}
protected function afterImageUpload()
{
$return = true;
$generate_hight_dpi_images = (bool) Configuration::get('PS_HIGHT_DPI');
/* Generate image with differents size */
if (($id_supplier = (int) Tools::getValue('id_supplier')) &&
isset($_FILES) && count($_FILES) && file_exists(_PS_SUPP_IMG_DIR_ . $id_supplier . '.jpg')) {
$images_types = ImageType::getImagesTypes('suppliers');
foreach ($images_types as $image_type) {
$file = _PS_SUPP_IMG_DIR_ . $id_supplier . '.jpg';
if (!ImageManager::resize($file, _PS_SUPP_IMG_DIR_ . $id_supplier . '-' . 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_SUPP_IMG_DIR_ . $id_supplier . '-' . stripslashes($image_type['name']) . '2x.jpg', (int) $image_type['width'] * 2, (int) $image_type['height'] * 2)) {
$return = false;
}
}
}
$current_logo_file = _PS_TMP_IMG_DIR_ . 'supplier_mini_' . $id_supplier . '_' . $this->context->shop->id . '.jpg';
if (file_exists($current_logo_file)) {
unlink($current_logo_file);
}
}
return $return;
}
/**
* AdminController::postProcess() override.
*
* @see AdminController::postProcess()
*/
public function postProcess()
{
// checks access
if (Tools::isSubmit('submitAdd' . $this->table) && !($this->access('add'))) {
$this->errors[] = $this->trans('You do not have permission to add suppliers.', array(), 'Admin.Catalog.Notification');
return parent::postProcess();
}
if (Tools::isSubmit('submitAdd' . $this->table)) {
if (Tools::isSubmit('id_supplier') && !($obj = $this->loadObject(true))) {
return;
}
// updates/creates address if it does not exist
if (Tools::isSubmit('id_address') && (int) Tools::getValue('id_address') > 0) {
$address = new Address((int) Tools::getValue('id_address'));
} // updates address
else {
$address = new Address();
} // creates address
$address->alias = Tools::getValue('name', null);
$address->lastname = 'supplier'; // skip problem with numeric characters in supplier name
$address->firstname = 'supplier'; // skip problem with numeric characters in supplier name
$address->address1 = Tools::getValue('address', null);
$address->address2 = Tools::getValue('address2', null);
$address->postcode = Tools::getValue('postcode', null);
$address->phone = Tools::getValue('phone', null);
$address->phone_mobile = Tools::getValue('phone_mobile', null);
$address->id_country = Tools::getValue('id_country', null);
$address->id_state = Tools::getValue('id_state', null);
$address->city = Tools::getValue('city', null);
$address->dni = Tools::getValue('dni', null);
$validation = $address->validateController();
/*
* Make sure dni is checked without raising an exception.
* This field is mandatory for some countries.
*/
if ($address->validateField('dni', $address->dni) !== true) {
$validation['dni'] = $this->trans(
'%s is invalid.',
array(
'<b>dni</b>',
),
'Admin.Notifications.Error'
);
}
// checks address validity
if (count($validation) > 0) {
foreach ($validation as $item) {
$this->errors[] = $item;
}
$this->errors[] = $this->trans('The address is not correct. Please make sure all of the required fields are completed.', array(), 'Admin.Catalog.Notification');
} else {
if (Tools::isSubmit('id_address') && Tools::getValue('id_address') > 0) {
$address->update();
} else {
$address->save();
$_POST['id_address'] = $address->id;
}
}
return parent::postProcess();
} elseif (Tools::isSubmit('delete' . $this->table)) {
if (!($obj = $this->loadObject(true))) {
return;
} elseif (SupplyOrder::supplierHasPendingOrders($obj->id)) {
$this->errors[] = $this->trans('It is not possible to delete a supplier if there are pending supplier orders.', array(), 'Admin.Catalog.Notification');
} else {
//delete all product_supplier linked to this supplier
Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'product_supplier` WHERE `id_supplier`=' . (int) $obj->id);
$id_address = Address::getAddressIdBySupplierId($obj->id);
$address = new Address($id_address);
if (Validate::isLoadedObject($address)) {
$address->deleted = 1;
$address->save();
}
return parent::postProcess();
}
} else {
return parent::postProcess();
}
}
/**
* @see AdminController::afterAdd()
*
* @param Supplier $object
*
* @return bool
*/
protected function afterAdd($object)
{
$id_address = (int) $_POST['id_address'];
$address = new Address($id_address);
if (Validate::isLoadedObject($address)) {
$address->id_supplier = $object->id;
$address->save();
}
return true;
}
/**
* @see AdminController::afterUpdate()
*
* @param Supplier $object
*
* @return bool
*/
protected function afterUpdate($object)
{
$id_address = (int) $_POST['id_address'];
$address = new Address($id_address);
if (Validate::isLoadedObject($address)) {
if ($address->id_supplier != $object->id) {
$address->id_supplier = $object->id;
$address->save();
}
}
return true;
}
}

View File

@@ -0,0 +1,384 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Tab $object
*/
class AdminTabsControllerCore extends AdminController
{
protected $position_identifier = 'id_tab';
public function __construct()
{
$this->bootstrap = true;
$this->multishop_context = Shop::CONTEXT_ALL;
$this->table = 'tab';
$this->list_id = 'tab';
$this->className = 'Tab';
$this->lang = true;
parent::__construct();
$this->fieldImageSettings = array(
'name' => 'icon',
'dir' => 't',
);
$this->imageType = 'gif';
$this->bulk_actions = array(
'delete' => array(
'text' => $this->l('Delete selected'),
'confirm' => $this->l('Delete selected items?'),
'icon' => 'icon-trash',
),
);
$this->fields_list = array(
'id_tab' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
),
'class_name' => array(
'title' => $this->l('Class'),
),
'module' => array(
'title' => $this->l('Module'),
),
'active' => array(
'title' => $this->trans('Enabled', array(), 'Admin.Global'),
'align' => 'center',
'active' => 'status',
'type' => 'bool',
'orderby' => false,
),
'position' => array(
'title' => $this->l('Position'),
'filter_key' => 'a!position',
'position' => 'position',
'align' => 'center',
'class' => 'fixed-width-md',
),
);
}
public function initPageHeaderToolbar()
{
$this->page_header_toolbar_title = $this->l('Menus');
if ($this->display == 'details') {
$this->page_header_toolbar_btn['back_to_list'] = array(
'href' => Context::getContext()->link->getAdminLink('AdminTabs'),
'desc' => $this->l('Back to list', null, null, false),
'icon' => 'process-icon-back',
);
} elseif (empty($this->display)) {
$this->page_header_toolbar_btn['new_menu'] = array(
'href' => self::$currentIndex . '&addtab&token=' . $this->token,
'desc' => $this->l('Add new menu', null, null, false),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
/**
* AdminController::renderForm() override.
*
* @see AdminController::renderForm()
*/
public function renderForm()
{
$tabs = Tab::getTabs($this->context->language->id, 0);
// If editing, we clean itself
if (Tools::isSubmit('id_tab')) {
foreach ($tabs as $key => $tab) {
if ($tab['id_tab'] == Tools::getValue('id_tab')) {
unset($tabs[$key]);
}
}
}
// added category "Home" in var $tabs
$tab_zero = array(
'id_tab' => 0,
'name' => $this->l('Home'),
);
array_unshift($tabs, $tab_zero);
$this->fields_form = array(
'legend' => array(
'title' => $this->l('Menus'),
'icon' => 'icon-list-ul',
),
'input' => array(
array(
'type' => 'hidden',
'name' => 'position',
'required' => false,
),
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'required' => true,
'hint' => $this->l('Invalid characters:') . ' &lt;&gt;;=#{}',
),
array(
'type' => 'text',
'label' => $this->l('Class'),
'name' => 'class_name',
'required' => true,
),
array(
'type' => 'text',
'label' => $this->l('Module'),
'name' => 'module',
),
array(
'type' => 'switch',
'label' => $this->l('Status'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
'hint' => $this->l('Show or hide menu.'),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
$display_parent = true;
if (Validate::isLoadedObject($this->object) && !class_exists($this->object->class_name . 'Controller')) {
$display_parent = false;
}
if ($display_parent) {
$this->fields_form['input'][] = array(
'type' => 'select',
'label' => $this->l('Parent'),
'name' => 'id_parent',
'options' => array(
'query' => $tabs,
'id' => 'id_tab',
'name' => 'name',
),
);
}
return parent::renderForm();
}
/**
* AdminController::renderList() override.
*
* @see AdminController::renderList()
*/
public function renderList()
{
$this->addRowAction('edit');
$this->addRowAction('details');
$this->addRowAction('delete');
$this->_where = 'AND a.`id_parent` = 0';
$this->_orderBy = 'position';
return parent::renderList();
}
public function initProcess()
{
if (Tools::getIsset('details' . $this->table)) {
$this->list_id = 'details';
if (isset($_POST['submitReset' . $this->list_id])) {
$this->processResetFilters();
}
} else {
$this->list_id = 'tab';
}
return parent::initProcess();
}
public function renderDetails()
{
if (($id = Tools::getValue('id_tab'))) {
$this->lang = false;
$this->list_id = 'details';
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->toolbar_btn = array();
/** @var Tab $tab */
$tab = $this->loadObject($id);
$this->toolbar_title = $tab->name[$this->context->employee->id_lang];
$this->_select = 'b.*';
$this->_join = 'LEFT JOIN `' . _DB_PREFIX_ . 'tab_lang` b ON (b.`id_tab` = a.`id_tab` AND b.`id_lang` = ' .
(int) $this->context->language->id . ')';
$this->_where = 'AND a.`id_parent` = ' . (int) $id;
$this->_orderBy = 'position';
$this->_use_found_rows = false;
self::$currentIndex = self::$currentIndex . '&details' . $this->table;
$this->processFilter();
return parent::renderList();
}
}
public function postProcess()
{
/* PrestaShop demo mode */
if (_PS_MODE_DEMO_) {
$this->errors[] = $this->trans('This functionality has been disabled.', array(), 'Admin.Notifications.Error');
return;
}
/* PrestaShop demo mode*/
if (($id_tab = (int) Tools::getValue('id_tab')) && ($direction = Tools::getValue('move')) && Validate::isLoadedObject($tab = new Tab($id_tab))) {
if ($tab->move($direction)) {
Tools::redirectAdmin(self::$currentIndex . '&token=' . $this->token);
}
} elseif (Tools::getValue('position') && !Tools::isSubmit('submitAdd' . $this->table)) {
if ($this->access('edit') !== '1') {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
} elseif (!Validate::isLoadedObject($object = new Tab((int) Tools::getValue($this->identifier)))) {
$this->errors[] = $this->trans('An error occurred while updating the status for an object.', array(), 'Admin.Notifications.Error') .
' <b>' . $this->table . '</b> ' . $this->trans('(cannot load object)', array(), 'Admin.Notifications.Error');
}
if (!$object->updatePosition((int) Tools::getValue('way'), (int) Tools::getValue('position'))) {
$this->errors[] = $this->trans('Failed to update the position.', array(), 'Admin.Notifications.Error');
} else {
Tools::redirectAdmin(self::$currentIndex . '&conf=5&token=' . Tools::getAdminTokenLite('AdminTabs'));
}
} elseif (Tools::isSubmit('submitAdd' . $this->table) && Tools::getValue('id_tab') === Tools::getValue('id_parent')) {
$this->errors[] = $this->trans('You can\'t put this menu inside itself. ', array(), 'Admin.Advparameters.Notification');
} elseif (Tools::isSubmit('submitAdd' . $this->table) && $id_parent = (int) Tools::getValue('id_parent')) {
$this->redirect_after = self::$currentIndex . '&id_' . $this->table . '=' . $id_parent . '&details' . $this->table . '&conf=4&token=' . $this->token;
} elseif (isset($_GET['details' . $this->table]) && is_array($this->bulk_actions)) {
$submit_bulk_actions = array_merge(array(
'enableSelection' => array(
'text' => $this->l('Enable selection'),
'icon' => 'icon-power-off text-success',
),
'disableSelection' => array(
'text' => $this->l('Disable selection'),
'icon' => 'icon-power-off text-danger',
),
), $this->bulk_actions);
foreach ($submit_bulk_actions as $bulk_action => $params) {
if (Tools::isSubmit('submitBulk' . $bulk_action . $this->table) || Tools::isSubmit('submitBulk' . $bulk_action)) {
if ($this->access('edit')) {
$this->action = 'bulk' . $bulk_action;
$this->boxes = Tools::getValue($this->list_id . 'Box');
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
break;
} elseif (Tools::isSubmit('submitBulk')) {
if ($this->access('edit')) {
$this->action = 'bulk' . Tools::getValue('select_submitBulk');
$this->boxes = Tools::getValue($this->list_id . 'Box');
} else {
$this->errors[] = $this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error');
}
break;
}
}
} else {
// Temporary add the position depend of the selection of the parent category
if (!Tools::isSubmit('id_tab')) { // @todo Review
$_POST['position'] = Tab::getNbTabs(Tools::getValue('id_parent'));
}
}
if (!count($this->errors)) {
parent::postProcess();
}
}
protected function afterImageUpload()
{
/** @var Tab $obj */
if (!($obj = $this->loadObject(true))) {
return;
}
@rename(_PS_IMG_DIR_ . 't/' . $obj->id . '.gif', _PS_IMG_DIR_ . 't/' . $obj->class_name . '.gif');
}
public function ajaxProcessUpdatePositions()
{
$way = (int) (Tools::getValue('way'));
$id_tab = (int) (Tools::getValue('id'));
$positions = Tools::getValue('tab');
// when changing positions in a tab sub-list, the first array value is empty and needs to be removed
if (!$positions[0]) {
unset($positions[0]);
// reset indexation from 0
$positions = array_merge($positions);
}
foreach ($positions as $position => $value) {
$pos = explode('_', $value);
if (isset($pos[2]) && (int) $pos[2] === $id_tab) {
if ($tab = new Tab((int) $pos[2])) {
if (isset($position) && $tab->updatePosition($way, $position)) {
echo 'ok position ' . (int) $position . ' for tab ' . (int) $pos[1] . '\r\n';
} else {
echo '{"hasError" : true, "errors" : "Can not update tab ' . (int) $id_tab . ' to position ' . (int) $position . ' "}';
}
} else {
echo '{"hasError" : true, "errors" : "This tab (' . (int) $id_tab . ') can t be loaded"}';
}
break;
}
}
}
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Tag $object
*/
class AdminTagsControllerCore extends AdminController
{
public $bootstrap = true;
public function __construct()
{
$this->table = 'tag';
$this->className = 'Tag';
parent::__construct();
$this->fields_list = array(
'id_tag' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'lang' => array(
'title' => $this->trans('Language', array(), 'Admin.Global'),
'filter_key' => 'l!name',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
'filter_key' => 'a!name',
),
'products' => array(
'title' => $this->trans('Products', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
'havingFilter' => true,
),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'icon' => 'icon-trash',
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_tag'] = array(
'href' => self::$currentIndex . '&addtag&token=' . $this->token,
'desc' => $this->trans('Add new tag', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderList()
{
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_select = 'l.name as lang, COUNT(pt.id_product) as products';
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'product_tag` pt
ON (a.`id_tag` = pt.`id_tag`)
LEFT JOIN `' . _DB_PREFIX_ . 'lang` l
ON (l.`id_lang` = a.`id_lang`)';
$this->_group = 'GROUP BY a.name, a.id_lang';
return parent::renderList();
}
public function postProcess()
{
if ($this->access('edit') && Tools::getValue('submitAdd' . $this->table)) {
if (($id = (int) Tools::getValue($this->identifier)) && ($obj = new $this->className($id)) && Validate::isLoadedObject($obj)) {
/** @var Tag $obj */
$previous_products = $obj->getProducts();
$removed_products = array();
foreach ($previous_products as $product) {
if (!in_array($product['id_product'], $_POST['products'])) {
$removed_products[] = $product['id_product'];
}
}
if (Configuration::get('PS_SEARCH_INDEXATION')) {
Search::removeProductsSearchIndex($removed_products);
}
$obj->setProducts($_POST['products']);
}
}
return parent::postProcess();
}
public function renderForm()
{
/** @var Tag $obj */
if (!($obj = $this->loadObject(true))) {
return;
}
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Tag', array(), 'Admin.Shopparameters.Feature'),
'icon' => 'icon-tag',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'required' => true,
),
array(
'type' => 'select',
'label' => $this->trans('Language', array(), 'Admin.Global'),
'name' => 'id_lang',
'required' => true,
'options' => array(
'query' => Language::getLanguages(false),
'id' => 'id_lang',
'name' => 'name',
),
),
),
'selects' => array(
'products' => $obj->getProducts(true),
'products_unselected' => $obj->getProducts(false),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
return parent::renderForm();
}
}

View File

@@ -0,0 +1,578 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property TaxRulesGroup $object
*/
class AdminTaxRulesGroupControllerCore extends AdminController
{
public $tax_rule;
public $selected_countries = array();
public $selected_states = array();
public $errors_tax_rule;
public function __construct()
{
$this->bootstrap = true;
$this->table = 'tax_rules_group';
$this->className = 'TaxRulesGroup';
$this->lang = false;
parent::__construct();
$this->fields_list = array(
'id_tax_rules_group' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global'),
),
'active' => array(
'title' => $this->trans('Enabled', array(), 'Admin.Global'),
'active' => 'status',
'type' => 'bool',
'orderby' => false,
'align' => 'center',
'class' => 'fixed-width-sm',
),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
$this->_where .= ' AND a.deleted = 0';
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_tax_rules_group'] = array(
'href' => self::$currentIndex . '&addtax_rules_group&token=' . $this->token,
'desc' => $this->trans('Add new tax rules group', array(), 'Admin.International.Feature'),
'icon' => 'process-icon-new',
);
}
if ($this->display === 'edit') {
$this->page_header_toolbar_btn['new'] = array(
'href' => '#',
'desc' => $this->trans('Add a new tax rule', array(), 'Admin.International.Feature'),
);
}
parent::initPageHeaderToolbar();
}
public function renderList()
{
$this->addRowAction('edit');
$this->addRowAction('delete');
return parent::renderList();
}
public function initRulesList($id_group)
{
$this->table = 'tax_rule';
$this->list_id = 'tax_rule';
$this->identifier = 'id_tax_rule';
$this->className = 'TaxRule';
$this->lang = false;
$this->list_simple_header = false;
$this->toolbar_btn = null;
$this->list_no_link = true;
$this->bulk_actions = array(
'delete' => array('text' => $this->trans('Delete selected', array(), 'Admin.Actions'), 'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'), 'icon' => 'icon-trash'),
);
$this->fields_list = array(
'country_name' => array(
'title' => $this->trans('Country', array(), 'Admin.Global'),
),
'state_name' => array(
'title' => $this->trans('State', array(), 'Admin.Global'),
),
'zipcode' => array(
'title' => $this->trans('Zip/Postal code', array(), 'Admin.Global'),
'class' => 'fixed-width-md',
),
'behavior' => array(
'title' => $this->trans('Behavior', array(), 'Admin.International.Feature'),
),
'rate' => array(
'title' => $this->trans('Tax', array(), 'Admin.Global'),
'class' => 'fixed-width-sm',
),
'description' => array(
'title' => $this->trans('Description', array(), 'Admin.Global'),
),
);
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->_select = '
c.`name` AS country_name,
s.`name` AS state_name,
CONCAT_WS(" - ", a.`zipcode_from`, a.`zipcode_to`) AS zipcode,
t.rate';
$this->_join = '
LEFT JOIN `' . _DB_PREFIX_ . 'country_lang` c
ON (a.`id_country` = c.`id_country` AND id_lang = ' . (int) $this->context->language->id . ')
LEFT JOIN `' . _DB_PREFIX_ . 'state` s
ON (a.`id_state` = s.`id_state`)
LEFT JOIN `' . _DB_PREFIX_ . 'tax` t
ON (a.`id_tax` = t.`id_tax`)';
$this->_where = 'AND `id_tax_rules_group` = ' . (int) $id_group;
$this->_use_found_rows = false;
$this->show_toolbar = false;
$this->tpl_list_vars = array('id_tax_rules_group' => (int) $id_group);
$this->_filter = false;
return parent::renderList();
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Tax Rules', array(), 'Admin.International.Feature'),
'icon' => 'icon-money',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'required' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info') . ' <>;=#{}',
),
array(
'type' => 'switch',
'label' => $this->trans('Enable', array(), 'Admin.Actions'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
),
),
'submit' => array(
'title' => $this->trans('Save and stay', array(), 'Admin.Actions'),
'stay' => true,
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
if (!($obj = $this->loadObject(true))) {
return;
}
if (!isset($obj->id)) {
$this->no_back = false;
$content = parent::renderForm();
} else {
$this->no_back = true;
$this->page_header_toolbar_btn['new'] = array(
'href' => '#',
'desc' => $this->trans('Add a new tax rule', array(), 'Admin.International.Feature'),
);
$content = parent::renderForm();
$this->tpl_folder = 'tax_rules/';
$content .= $this->initRuleForm();
// We change the variable $ tpl_folder to avoid the overhead calling the file in list_action_edit.tpl in intList ();
$content .= $this->initRulesList((int) $obj->id);
}
return $content;
}
public function initRuleForm()
{
$this->fields_form[0]['form'] = array(
'legend' => array(
'title' => $this->trans('New tax rule', array(), 'Admin.International.Feature'),
'icon' => 'icon-money',
),
'input' => array(
array(
'type' => 'select',
'label' => $this->trans('Country', array(), 'Admin.Global'),
'name' => 'country',
'id' => 'country',
'options' => array(
'query' => Country::getCountries($this->context->language->id),
'id' => 'id_country',
'name' => 'name',
'default' => array(
'value' => 0,
'label' => $this->trans('All', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'select',
'label' => $this->trans('State', array(), 'Admin.Global'),
'name' => 'states[]',
'id' => 'states',
'multiple' => true,
'options' => array(
'query' => array(),
'id' => 'id_state',
'name' => 'name',
'default' => array(
'value' => 0,
'label' => $this->trans('All', array(), 'Admin.Global'),
),
),
),
array(
'type' => 'hidden',
'name' => 'action',
),
array(
'type' => 'text',
'label' => $this->trans('Zip/postal code range', array(), 'Admin.International.Feature'),
'name' => 'zipcode',
'required' => false,
'hint' => $this->trans('You can define a range of Zip/postal codes (e.g., 75000-75015) or simply use one Zip/postal code.', array(), 'Admin.International.Help'),
),
array(
'type' => 'select',
'label' => $this->trans('Behavior', array(), 'Admin.International.Feature'),
'name' => 'behavior',
'required' => false,
'options' => array(
'query' => array(
array(
'id' => 0,
'name' => $this->trans('This tax only', array(), 'Admin.International.Feature'),
),
array(
'id' => 1,
'name' => $this->trans('Combine', array(), 'Admin.International.Feature'),
),
array(
'id' => 2,
'name' => $this->trans('One after another', array(), 'Admin.International.Feature'),
),
),
'id' => 'id',
'name' => 'name',
),
'hint' => array(
$this->trans('You must define the behavior if an address matches multiple rules:', array(), 'Admin.International.Help') . '<br>',
$this->trans('- This tax only: Will apply only this tax', array(), 'Admin.International.Help') . '<br>',
$this->trans('- Combine: Combine taxes (e.g.: 10% + 5% = 15%)', array(), 'Admin.International.Help') . '<br>',
$this->trans('- One after another: Apply taxes one after another (e.g.: 100 + 10% => 110 + 5% = 115.5)', array(), 'Admin.International.Help'),
),
),
array(
'type' => 'select',
'label' => $this->trans('Tax', array(), 'Admin.Global'),
'name' => 'id_tax',
'required' => false,
'options' => array(
'query' => Tax::getTaxes((int) $this->context->language->id),
'id' => 'id_tax',
'name' => 'name',
'default' => array(
'value' => 0,
'label' => $this->trans('No Tax', array(), 'Admin.International.Help'),
),
),
'hint' => $this->trans('(Total tax: 9%)', array(), 'Admin.International.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Description', array(), 'Admin.Global'),
'name' => 'description',
),
),
'submit' => array(
'title' => $this->trans('Save and stay', array(), 'Admin.Actions'),
'stay' => true,
),
);
if (!($obj = $this->loadObject(true))) {
return;
}
$this->fields_value = array(
'action' => 'create_rule',
'id_tax_rules_group' => $obj->id,
'id_tax_rule' => '',
);
$this->getlanguages();
$helper = new HelperForm();
$helper->override_folder = $this->tpl_folder;
$helper->currentIndex = self::$currentIndex;
$helper->token = $this->token;
$helper->table = 'tax_rule';
$helper->identifier = 'id_tax_rule';
$helper->id = $obj->id;
$helper->toolbar_scroll = true;
$helper->show_toolbar = true;
$helper->languages = $this->_languages;
$helper->default_form_language = $this->default_form_language;
$helper->allow_employee_form_lang = $this->allow_employee_form_lang;
$helper->fields_value = $this->getFieldsValue($this->object);
$helper->toolbar_btn['save_new_rule'] = array(
'href' => self::$currentIndex . '&amp;id_tax_rules_group=' . $obj->id . '&amp;action=create_rule&amp;token=' . $this->token,
'desc' => 'Save tax rule',
'class' => 'process-icon-save',
);
$helper->submit_action = 'create_rule';
return $helper->generateForm($this->fields_form);
}
public function initProcess()
{
if (Tools::isSubmit('deletetax_rule')) {
if ($this->access('delete')) {
$this->action = 'delete_tax_rule';
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::isSubmit('submitBulkdeletetax_rule')) {
if ($this->access('delete')) {
$this->action = 'bulk_delete_tax_rules';
} else {
$this->errors[] = $this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error');
}
} elseif (Tools::getValue('action') == 'create_rule') {
if ($this->access('add')) {
$this->action = 'create_rule';
} else {
$this->errors[] = $this->trans('You do not have permission to add this.', array(), 'Admin.Notifications.Error');
}
} else {
parent::initProcess();
}
}
protected function processCreateRule()
{
$zip_code = Tools::getValue('zipcode');
$zip_code = ('' === $zip_code) ? 0 : $zip_code;
$id_rule = (int) Tools::getValue('id_tax_rule');
$id_tax = (int) Tools::getValue('id_tax');
$id_tax_rules_group = (int) Tools::getValue('id_tax_rules_group');
$behavior = (int) Tools::getValue('behavior');
$description = pSQL(Tools::getValue('description'));
if ((int) ($id_country = Tools::getValue('country')) == 0) {
$countries = Country::getCountries($this->context->language->id);
$this->selected_countries = array();
foreach ($countries as $country) {
$this->selected_countries[] = (int) $country['id_country'];
}
} else {
$this->selected_countries = array($id_country);
}
$this->selected_states = Tools::getValue('states');
if (empty($this->selected_states) || count($this->selected_states) == 0) {
$this->selected_states = array(0);
}
$tax_rules_group = new TaxRulesGroup((int) $id_tax_rules_group);
foreach ($this->selected_countries as $id_country) {
$first = true;
foreach ($this->selected_states as $id_state) {
if ($tax_rules_group->hasUniqueTaxRuleForCountry($id_country, $id_state, $id_rule)) {
$this->errors[] = $this->trans('A tax rule already exists for this country/state with tax only behavior.', array(), 'Admin.International.Notification');
continue;
}
$tr = new TaxRule();
// update or creation?
if (isset($id_rule) && $first) {
$tr->id = $id_rule;
$first = false;
}
$tr->id_tax = $id_tax;
$tax_rules_group = new TaxRulesGroup((int) $id_tax_rules_group);
$tr->id_tax_rules_group = (int) $tax_rules_group->id;
$tr->id_country = (int) $id_country;
$tr->id_state = (int) $id_state;
list($tr->zipcode_from, $tr->zipcode_to) = $tr->breakDownZipCode($zip_code);
// Construct Object Country
$country = new Country((int) $id_country, (int) $this->context->language->id);
if ($zip_code && $country->need_zip_code) {
if ($country->zip_code_format) {
foreach (array($tr->zipcode_from, $tr->zipcode_to) as $zip_code) {
if ($zip_code) {
if (!$country->checkZipCode($zip_code)) {
$this->errors[] = $this->trans(
'The Zip/postal code is invalid. It must be typed as follows: %format% for %country%.',
array(
'%format%' => str_replace('C', $country->iso_code, str_replace('N', '0', str_replace('L', 'A', $country->zip_code_format))),
'%country%' => $country->name,
),
'Admin.International.Notification'
);
}
}
}
}
}
$tr->behavior = (int) $behavior;
$tr->description = $description;
$this->tax_rule = $tr;
$_POST['id_state'] = $tr->id_state;
$this->errors = array_merge($this->errors, $this->validateTaxRule($tr));
if (count($this->errors) == 0) {
$tax_rules_group = $this->updateTaxRulesGroup($tax_rules_group);
$tr->id = (int) $tax_rules_group->getIdTaxRuleGroupFromHistorizedId((int) $tr->id);
$tr->id_tax_rules_group = (int) $tax_rules_group->id;
if (!$tr->save()) {
$this->errors[] = $this->trans('An error has occurred: Cannot save the current tax rule.', array(), 'Admin.International.Notification');
}
}
}
}
if (count($this->errors) == 0) {
Tools::redirectAdmin(
self::$currentIndex . '&' . $this->identifier . '=' . (int) $tax_rules_group->id . '&conf=4&update' . $this->table . '&token=' . $this->token
);
} else {
$this->display = 'edit';
}
}
protected function processBulkDeleteTaxRules()
{
$this->deleteTaxRule(Tools::getValue('tax_ruleBox'));
}
protected function processDeleteTaxRule()
{
$this->deleteTaxRule(array(Tools::getValue('id_tax_rule')));
}
protected function deleteTaxRule(array $id_tax_rule_list)
{
$result = true;
foreach ($id_tax_rule_list as $id_tax_rule) {
$tax_rule = new TaxRule((int) $id_tax_rule);
if (Validate::isLoadedObject($tax_rule)) {
$tax_rules_group = new TaxRulesGroup((int) $tax_rule->id_tax_rules_group);
$tax_rules_group = $this->updateTaxRulesGroup($tax_rules_group);
$tax_rule = new TaxRule($tax_rules_group->getIdTaxRuleGroupFromHistorizedId((int) $id_tax_rule));
if (Validate::isLoadedObject($tax_rule)) {
$result &= $tax_rule->delete();
}
}
}
Tools::redirectAdmin(
self::$currentIndex . '&' . $this->identifier . '=' . (int) $tax_rules_group->id . '&conf=4&update' . $this->table . '&token=' . $this->token
);
}
/**
* Check if the tax rule could be added in the database.
*
* @param TaxRule $tr
*
* @return array
*/
protected function validateTaxRule(TaxRule $tr)
{
// @TODO: check if the rule already exists
return $tr->validateController();
}
protected function displayAjaxUpdateTaxRule()
{
if ($this->access('view')) {
$id_tax_rule = Tools::getValue('id_tax_rule');
$tax_rules = new TaxRule((int) $id_tax_rule);
$output = array();
foreach ($tax_rules as $key => $result) {
$output[$key] = $result;
}
die(json_encode($output));
}
}
/**
* @param TaxRulesGroup $object
*
* @return TaxRulesGroup
*/
protected function updateTaxRulesGroup($object)
{
static $tax_rules_group = null;
if ($tax_rules_group === null) {
$object->update();
$tax_rules_group = $object;
}
return $tax_rules_group;
}
}

View File

@@ -0,0 +1,482 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
/**
* @property Product|Category $object
*/
class AdminTrackingControllerCore extends AdminController
{
public $bootstrap = true;
/** @var HelperList */
protected $_helper_list;
public function postprocess()
{
if (Tools::getValue('id_product') && Tools::isSubmit('statusproduct')) {
$this->table = 'product';
$this->identifier = 'id_product';
$this->action = 'status';
$this->className = 'Product';
} elseif (Tools::getValue('id_category') && Tools::isSubmit('statuscategory')) {
$this->table = 'category';
$this->identifier = 'id_category';
$this->action = 'status';
$this->className = 'Category';
}
$this->list_no_link = true;
parent::postprocess();
}
public function initContent()
{
if ($id_category = Tools::getValue('id_category') && Tools::getIsset('viewcategory')) {
Tools::redirectAdmin($this->context->link->getAdminLink('AdminProducts') . '&id_category=' . (int) $id_category . '&viewcategory');
}
$this->_helper_list = new HelperList();
if (!Configuration::get('PS_STOCK_MANAGEMENT')) {
$this->warnings[] = $this->trans('List of products without available quantities for sale are not displayed because stock management is disabled.', array(), 'Admin.Catalog.Notification');
}
$methods = get_class_methods($this);
$tpl_vars['arrayList'] = array();
foreach ($methods as $method_name) {
if (preg_match('#getCustomList(.+)#', $method_name, $matches)) {
$this->clearListOptions();
$this->content .= call_user_func(array($this, $matches[0]));
}
}
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
public function getCustomListCategoriesEmpty()
{
$this->table = 'category';
$this->list_id = 'empty_categories';
$this->lang = true;
$this->className = 'Category';
$this->identifier = 'id_category';
$this->_orderBy = 'id_category';
$this->_orderWay = 'DESC';
$this->_list_index = 'index.php?controller=AdminCategories';
$this->_list_token = Tools::getAdminTokenLite('AdminCategories');
$this->addRowAction('edit');
$this->addRowAction('view');
$this->addRowActionSkipList('edit', array((int) Configuration::get('PS_ROOT_CATEGORY')));
$this->fields_list = (array(
'id_category' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'class' => 'fixed-width-xs', 'align' => 'center'),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'filter_key' => 'b!name'),
'description' => array('title' => $this->trans('Description', array(), 'Admin.Global'), 'callback' => 'getDescriptionClean'),
'active' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'type' => 'bool', 'active' => 'status', 'align' => 'center', 'class' => 'fixed-width-xs'),
));
$this->clearFilters();
$this->_join = Shop::addSqlAssociation('category', 'a');
$this->_filter = ' AND NOT EXISTS (
SELECT 1
FROM `' . _DB_PREFIX_ . 'category_product` cp
WHERE a.`id_category` = cp.id_category
)
AND a.`id_category` != ' . (int) Configuration::get('PS_ROOT_CATEGORY');
$this->toolbar_title = $this->trans('List of empty categories:', array(), 'Admin.Catalog.Feature');
return $this->renderList();
}
public function getCustomListProductsAttributesNoStock()
{
if (!Configuration::get('PS_STOCK_MANAGEMENT')) {
return;
}
$this->table = 'product';
$this->list_id = 'no_stock_products_attributes';
$this->lang = true;
$this->identifier = 'id_product';
$this->_orderBy = 'id_product';
$this->_orderWay = 'DESC';
$this->className = 'Product';
$this->_list_index = 'index.php?controller=AdminProducts';
$this->_list_token = Tools::getAdminTokenLite('AdminProducts');
$this->show_toolbar = false;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->fields_list = array(
'id_product' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'class' => 'fixed-width-xs', 'align' => 'center'),
'reference' => array('title' => $this->trans('Reference', array(), 'Admin.Global')),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'filter_key' => 'b!name'),
'active' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'type' => 'bool', 'active' => 'status', 'align' => 'center', 'class' => 'fixed-width-xs', 'filter_key' => 'a!active'),
);
$this->clearFilters();
$this->_join = Shop::addSqlAssociation('product', 'a');
$this->_filter = 'AND EXISTS (
SELECT 1
FROM `' . _DB_PREFIX_ . 'product` p
' . Product::sqlStock('p') . '
WHERE a.id_product = p.id_product AND EXISTS (
SELECT 1
FROM `' . _DB_PREFIX_ . 'product_attribute` WHERE `' . _DB_PREFIX_ . 'product_attribute`.id_product = p.id_product
)
AND IFNULL(stock.quantity, 0) <= 0
)';
$this->toolbar_title = $this->trans('List of products with combinations but without available quantities for sale:', array(), 'Admin.Catalog.Feature');
return $this->renderList();
}
public function getCustomListProductsNoStock()
{
if (!Configuration::get('PS_STOCK_MANAGEMENT')) {
return;
}
$this->table = 'product';
$this->list_id = 'no_stock_products';
$this->className = 'Product';
$this->lang = true;
$this->identifier = 'id_product';
$this->_orderBy = 'id_product';
$this->_orderWay = 'DESC';
$this->show_toolbar = false;
$this->_list_index = 'index.php?controller=AdminProducts';
$this->_list_token = Tools::getAdminTokenLite('AdminProducts');
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->fields_list = array(
'id_product' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'class' => 'fixed-width-xs', 'align' => 'center'),
'reference' => array('title' => $this->trans('Reference', array(), 'Admin.Global')),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global')),
'active' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'type' => 'bool', 'active' => 'status', 'align' => 'center', 'class' => 'fixed-width-xs', 'filter_key' => 'a!active'),
);
$this->clearFilters();
$this->_join = Shop::addSqlAssociation('product', 'a');
$this->_filter = 'AND EXISTS (
SELECT 1
FROM `' . _DB_PREFIX_ . 'product` p
' . Product::sqlStock('p') . '
WHERE a.id_product = p.id_product AND NOT EXISTS (
SELECT 1
FROM `' . _DB_PREFIX_ . 'product_attribute` pa WHERE pa.id_product = p.id_product
)
AND IFNULL(stock.quantity, 0) <= 0
)';
$this->toolbar_title = $this->trans('List of products without combinations and without available quantities for sale:', array(), 'Admin.Catalog.Feature');
return $this->renderList();
}
public function getCustomListProductsDisabled()
{
$this->table = 'product';
$this->list_id = 'disabled_products';
$this->className = 'Product';
$this->lang = true;
$this->identifier = 'id_product';
$this->_orderBy = 'id_product';
$this->_orderWay = 'DESC';
$this->_filter = 'AND product_shop.`active` = 0';
$this->show_toolbar = false;
$this->_list_index = 'index.php?controller=AdminProducts';
$this->_list_token = Tools::getAdminTokenLite('AdminProducts');
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->fields_list = array(
'id_product' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'class' => 'fixed-width-xs', 'align' => 'center'),
'reference' => array('title' => $this->trans('Reference', array(), 'Admin.Global')),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'filter_key' => 'b!name'),
);
$this->clearFilters();
$this->_join = Shop::addSqlAssociation('product', 'a');
$this->toolbar_title = $this->trans('List of disabled products', array(), 'Admin.Catalog.Feature');
return $this->renderList();
}
public function getCustomListProductsWithoutPhoto()
{
$this->table = 'product';
$this->list_id = 'products_without_photo';
$this->lang = true;
$this->identifier = 'id_product';
$this->_orderBy = 'id_product';
$this->_orderWay = 'DESC';
$this->className = 'Product';
$this->_list_index = 'index.php?controller=AdminProducts';
$this->_list_token = Tools::getAdminTokenLite('AdminProducts');
$this->show_toolbar = false;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->fields_list = array(
'id_product' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'class' => 'fixed-width-xs', 'align' => 'center'),
'reference' => array('title' => $this->trans('Reference', array(), 'Admin.Global')),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'filter_key' => 'b!name'),
'active' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'type' => 'bool', 'active' => 'status', 'align' => 'center', 'class' => 'fixed-width-xs'),
);
$this->clearFilters();
$this->_join = Shop::addSqlAssociation('product', 'a');
$this->_filter = 'AND NOT EXISTS (
SELECT 1
FROM `' . _DB_PREFIX_ . 'image` img
WHERE a.id_product = img.id_product
)';
$this->toolbar_title = $this->trans('List of products without images', array(), 'Admin.Catalog.Feature');
return $this->renderList(true);
}
public function getCustomListProductsWithoutDescription()
{
$this->table = 'product';
$this->list_id = 'products_without_description';
$this->lang = true;
$this->identifier = 'id_product';
$this->_orderBy = 'id_product';
$this->_orderWay = 'DESC';
$this->className = 'Product';
$this->_list_index = 'index.php?controller=AdminProducts';
$this->_list_token = Tools::getAdminTokenLite('AdminProducts');
$this->show_toolbar = false;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->fields_list = array(
'id_product' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'class' => 'fixed-width-xs', 'align' => 'center'),
'reference' => array('title' => $this->trans('Reference', array(), 'Admin.Global')),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'filter_key' => 'b!name'),
'active' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'type' => 'bool', 'active' => 'status', 'align' => 'center', 'class' => 'fixed-width-xs'),
);
$this->clearFilters();
$defaultLanguage = new Language(Configuration::get('PS_LANG_DEFAULT'));
$this->_join = Shop::addSqlAssociation('product', 'a');
$this->_filter = 'AND EXISTS (
SELECT 1
FROM `' . _DB_PREFIX_ . 'product_lang` pl
WHERE
a.id_product = pl.id_product AND
pl.id_lang = ' . (int) $defaultLanguage->id . ' AND
pl.id_shop = ' . (int) $this->context->shop->id . ' AND
description = "" AND description_short = ""
)';
$this->toolbar_title = $this->trans('List of products without description', array(), 'Admin.Catalog.Feature');
return $this->renderList(true);
}
public function getCustomListProductsWithoutPrice()
{
$this->table = 'product';
$this->list_id = 'products_without_price';
$this->lang = true;
$this->identifier = 'id_product';
$this->_orderBy = 'id_product';
$this->_orderWay = 'DESC';
$this->className = 'Product';
$this->_list_index = 'index.php?controller=AdminProducts';
$this->_list_token = Tools::getAdminTokenLite('AdminProducts');
$this->show_toolbar = false;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->fields_list = array(
'id_product' => array('title' => $this->trans('ID', array(), 'Admin.Global'), 'class' => 'fixed-width-xs', 'align' => 'center'),
'reference' => array('title' => $this->trans('Reference', array(), 'Admin.Global')),
'name' => array('title' => $this->trans('Name', array(), 'Admin.Global'), 'filter_key' => 'b!name'),
'active' => array('title' => $this->trans('Status', array(), 'Admin.Global'), 'type' => 'bool', 'active' => 'status', 'align' => 'center', 'class' => 'fixed-width-xs', 'ajax' => true),
);
$this->clearFilters();
$this->_join = Shop::addSqlAssociation('product', 'a');
$this->_filter = ' AND a.price = "0.000000" AND a.wholesale_price = "0.000000" AND NOT EXISTS (
SELECT 1
FROM `' . _DB_PREFIX_ . 'specific_price` sp
WHERE a.id_product = sp.id_product
)';
$this->toolbar_title = $this->trans('List of products without price', array(), 'Admin.Catalog.Feature');
return $this->renderList();
}
public function renderList($withPagination = false)
{
$paginationLimit = 20;
$this->processFilter();
if (!($this->fields_list && is_array($this->fields_list))) {
return false;
}
$this->getList($this->context->language->id, null, null, 0, $withPagination ? $paginationLimit : null);
$helper = new HelperList();
// Empty list is ok
if (!is_array($this->_list)) {
$this->displayWarning($this->trans('Bad SQL query', array(), 'Admin.Notifications.Error') . '<br />' . htmlspecialchars($this->_list_error));
return false;
}
$this->setHelperDisplay($helper);
if ($withPagination) {
$helper->_default_pagination = $paginationLimit;
$helper->_pagination = $this->_pagination;
}
$helper->tpl_vars = $this->tpl_list_vars;
$helper->tpl_delete_link_vars = $this->tpl_delete_link_vars;
// For compatibility reasons, we have to check standard actions in class attributes
foreach ($this->actions_available as $action) {
if (!in_array($action, $this->actions) && isset($this->$action) && $this->$action) {
$this->actions[] = $action;
}
}
$helper->is_cms = $this->is_cms;
$list = $helper->generateList($this->_list, $this->fields_list);
return $list;
}
public function displayEnableLink($token, $id, $value, $active, $id_category = null, $id_product = null)
{
$this->_helper_list->currentIndex = $this->_list_index;
$this->_helper_list->identifier = $this->identifier;
$this->_helper_list->table = $this->table;
// Since Categories controller is migrated to Symfony
// it makes use of new endpoint instead of relaying on legacy controller
if ($this->list_id === 'empty_categories') {
$url = SymfonyContainer::getInstance()->get('router')->generate('admin_categories_toggle_status', [
'categoryId' => $id,
]);
$this->context->smarty->assign('migrated_url_enable', $url);
$html = $this->_helper_list->displayEnableLink(
$this->_list_token,
$id,
$value,
$active,
$id_category,
$id_product,
true
);
$this->context->smarty->clearAssign('migrated_url_enable');
return $html;
}
return $this->_helper_list->displayEnableLink($this->_list_token, $id, $value, $active, $id_category, $id_product);
}
public function displayDeleteLink($token, $id, $name = null)
{
$this->_helper_list->currentIndex = $this->_list_index;
$this->_helper_list->identifier = $this->identifier;
$this->_helper_list->table = $this->table;
return $this->_helper_list->displayDeleteLink($this->_list_token, $id, $name);
}
public function displayEditLink($token, $id, $name = null)
{
$this->_helper_list->currentIndex = $this->_list_index;
$this->_helper_list->identifier = $this->identifier;
$this->_helper_list->table = $this->table;
return $this->_helper_list->displayEditLink($this->_list_token, $id, $name);
}
protected function clearFilters()
{
if (Tools::isSubmit('submitResetempty_categories')) {
$this->processResetFilters('empty_categories');
}
if (Tools::isSubmit('submitResetno_stock_products_attributes')) {
$this->processResetFilters('no_stock_products_attributes');
}
if (Tools::isSubmit('submitResetno_stock_products')) {
$this->processResetFilters('no_stock_products');
}
if (Tools::isSubmit('submitResetdisabled_products')) {
$this->processResetFilters('disabled_products');
}
if (Tools::isSubmit('submitResetproducts_without_photo')) {
$this->processResetFilters('products_without_photo');
}
if (Tools::isSubmit('submitResetproducts_without_description')) {
$this->processResetFilters('products_without_description');
}
if (Tools::isSubmit('submitResetproducts_without_price')) {
$this->processResetFilters('products_without_price');
}
}
public function clearListOptions()
{
$this->table = '';
$this->actions = array();
$this->list_skip_actions = array();
$this->lang = false;
$this->identifier = '';
$this->_orderBy = '';
$this->_orderWay = '';
$this->_filter = '';
$this->_group = '';
$this->_where = '';
$this->list_title = $this->trans('Product disabled', array(), 'Admin.Catalog.Feature');
}
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
parent::getList($id_lang, $order_by, $order_way, $start, $limit, Context::getContext()->shop->id);
}
public static function getDescriptionClean($description)
{
return Tools::getDescriptionClean($description);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/**
* @property Zone $object
*/
class AdminZonesControllerCore extends AdminController
{
public $asso_type = 'shop';
public function __construct()
{
$this->bootstrap = true;
$this->table = 'zone';
$this->className = 'Zone';
$this->lang = false;
parent::__construct();
$this->fields_list = array(
'id_zone' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs',
),
'name' => array(
'title' => $this->trans('Zone', array(), 'Admin.Global'),
),
'active' => array(
'title' => $this->trans('Enabled', array(), 'Admin.Global'),
'align' => 'center',
'active' => 'status',
'type' => 'bool',
'orderby' => false,
'class' => 'fixed-width-sm',
),
);
$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning'),
'icon' => 'icon-trash',
),
);
}
public function initPageHeaderToolbar()
{
if (empty($this->display)) {
$this->page_header_toolbar_btn['new_zone'] = array(
'href' => self::$currentIndex . '&addzone&token=' . $this->token,
'desc' => $this->trans('Add new zone', array(), 'Admin.International.Feature'),
'icon' => 'process-icon-new',
);
}
parent::initPageHeaderToolbar();
}
public function renderList()
{
$this->addRowAction('edit');
$this->addRowAction('delete');
return parent::renderList();
}
public function renderForm()
{
$this->fields_form = array(
'legend' => array(
'title' => $this->trans('Zones', array(), 'Admin.International.Feature'),
'icon' => 'icon-globe',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'required' => true,
'hint' => $this->trans('Zone name (e.g. Africa, West Coast, Neighboring Countries).', array(), 'Admin.International.Help'),
),
array(
'type' => 'switch',
'label' => $this->trans('Active', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global'),
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global'),
),
),
'hint' => $this->trans('Allow or disallow shipping to this zone.', array(), 'Admin.International.Help'),
),
),
);
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}
$this->fields_form['submit'] = array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
);
return parent::renderForm();
}
/**
* Get all zones displayed in a select input.
*/
public function displayAjaxZones()
{
$this->context->smarty->assign(array(
'zones' => Zone::getZones(),
));
$array = array(
'hasError' => false,
'errors' => '',
'data' => $this->context->smarty->fetch('controllers/zones/select.tpl'),
);
$this->ajaxRender(json_encode($array));
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
class BoOrderCore extends PaymentModule
{
public $active = 1;
public $name = 'bo_order';
public function __construct()
{
$this->displayName = $this->trans('Back office order', array(), 'Admin.Orderscustomers.Feature');
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2019 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2019 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../../');
exit;