1<?php
2/**
3 * Copyright (C) 2017-2019 thirty bees
4 * Copyright (C) 2007-2016 PrestaShop SA
5 *
6 * thirty bees is an extension to the PrestaShop software by PrestaShop SA.
7 *
8 * NOTICE OF LICENSE
9 *
10 * This source file is subject to the Academic Free License (AFL 3.0)
11 * that is bundled with this package in the file LICENSE.md.
12 * It is also available through the world-wide-web at this URL:
13 * https://opensource.org/licenses/afl-3.0.php
14 * If you did not receive a copy of the license and are unable to
15 * obtain it through the world-wide-web, please send an email
16 * to license@thirtybees.com so we can send you a copy immediately.
17 *
18 * @author    thirty bees <modules@thirtybees.com>
19 * @author    PrestaShop SA <contact@prestashop.com>
20 * @copyright 2017-2019 thirty bees
21 * @copyright 2007-2016 PrestaShop SA
22 * @license   Academic Free License (AFL 3.0)
23 * PrestaShop is an internationally registered trademark of PrestaShop SA.
24 */
25
26require_once __DIR__.'/classes/autoload.php';
27
28use TbUpdaterModule\Tools;
29
30/**
31 * Display SQL date in friendly format
32 *
33 * @param string  $sqlDate  Date in SQL format (YYYY-MM-DD HH:mm:ss)
34 * @param boolean $withTime Display both date and time
35 *
36 * @todo Several formats (french : DD-MM-YYYY)
37 */
38function displayDate($sqlDate, $withTime = false)
39{
40    return strftime('%Y-%m-%d'.($withTime ? ' %H:%M:%S' : ''), strtotime($sqlDate));
41}
42
43/**
44 * Return path to a product category
45 *
46 * @param string  $urlBase     Start URL
47 * @param integer $idCategory Start category
48 * @param string  $path        Current path
49 * @param string  $highlight   String to highlight (in XHTML/CSS)
50 * @param string  $type        Category type (products/cms)
51 */
52function getPath($urlBase, $idCategory, $path = '', $highlight = '', $categoryType = 'catalog')
53{
54    global $cookie;
55
56    if ($categoryType == 'catalog') {
57        $category = Db::getInstance()->getRow(
58            '
59		SELECT id_category, level_depth, nleft, nright
60		FROM '._DB_PREFIX_.'category
61		WHERE id_category = '.(int) $idCategory
62        );
63
64        if (isset($category['id_category'])) {
65            $categories = Db::getInstance()->ExecuteS(
66                '
67			SELECT c.id_category, cl.name, cl.link_rewrite
68			FROM '._DB_PREFIX_.'category c
69			LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = c.id_category)
70			WHERE c.nleft <= '.(int) $category['nleft'].' AND c.nright >= '.(int) $category['nright'].' AND cl.id_lang = '.(int) ($cookie->id_lang).'
71			ORDER BY c.level_depth ASC
72			LIMIT '.(int) ($category['level_depth'] + 1)
73            );
74
75            $fullPath = '';
76            $n = 1;
77            $nCategories = (int) sizeof($categories);
78            foreach ($categories as $category) {
79                $edit = '<a href="'.$urlBase.'&id_category='.(int) $category['id_category'].'&'.($category['id_category'] == 1 ? 'viewcategory' : 'addcategory').'&token='.Tools::getAdminToken('AdminCatalog'.(int) (Tab::getIdFromClassName('AdminCatalog')).(int) ($cookie->id_employee)).'" title="'.($category['id_category'] == 1 ? 'Home' : 'Modify').'"><img src="../img/admin/'.($category['id_category'] == 1 ? 'home' : 'edit').'.gif" alt="" /></a> ';
80                $fullPath .= $edit.
81                    ($n < $nCategories ? '<a href="'.$urlBase.'&id_category='.(int) $category['id_category'].'&viewcategory&token='.Tools::getAdminToken('AdminCatalog'.(int) (Tab::getIdFromClassName('AdminCatalog')).(int) ($cookie->id_employee)).'" title="'.htmlentities($category['name'], ENT_NOQUOTES, 'UTF-8').'">' : '').
82                    (!empty($highlight) ? str_ireplace($highlight, '<span class="highlight">'.htmlentities($highlight, ENT_NOQUOTES, 'UTF-8').'</span>', $category['name']) : $category['name']).
83                    ($n < $nCategories ? '</a>' : '').
84                    (($n++ != $nCategories || !empty($path)) ? ' > ' : '');
85            }
86
87            return $fullPath.$path;
88        }
89    } elseif ($categoryType == 'cms') {
90        $category = new CMSCategory($idCategory, (int) ($cookie->id_lang));
91        if (!$category->id) {
92            return $path;
93        }
94
95        $name = ($highlight != null) ? str_ireplace($highlight, '<span class="highlight">'.$highlight.'</span>', CMSCategory::hideCMSCategoryPosition($category->name)) : CMSCategory::hideCMSCategoryPosition($category->name);
96        $edit = '<a href="'.$urlBase.'&id_cms_category='.$category->id.'&addcategory&token='.Tools::getAdminToken('AdminCMSContent'.(int) (Tab::getIdFromClassName('AdminCMSContent')).(int) ($cookie->id_employee)).'">
97				<img src="../img/admin/edit.gif" alt="Modify" /></a> ';
98        if ($category->id == 1) {
99            $edit = '<a href="'.$urlBase.'&id_cms_category='.$category->id.'&viewcategory&token='.Tools::getAdminToken('AdminCMSContent'.(int) (Tab::getIdFromClassName('AdminCMSContent')).(int) ($cookie->id_employee)).'">
100					<img src="../img/admin/home.gif" alt="Home" /></a> ';
101        }
102        $path = $edit.'<a href="'.$urlBase.'&id_cms_category='.$category->id.'&viewcategory&token='.Tools::getAdminToken('AdminCMSContent'.(int) (Tab::getIdFromClassName('AdminCMSContent')).(int) ($cookie->id_employee)).'">
103		'.$name.'</a> > '.$path;
104        if ($category->id == 1) {
105            return substr($path, 0, strlen($path) - 3);
106        }
107
108        return getPath($urlBase, $category->id_parent, $path, '', 'cms');
109    }
110}
111
112function getDirContent($path)
113{
114    $content = [];
115    if (is_dir($path)) {
116        $d = dir($path);
117        while (false !== ($entry = $d->read())) {
118            if ($entry{0} != '.') {
119                $content[] = $entry;
120            }
121        }
122        $d->close();
123    }
124
125    return $content;
126}
127
128function createDir($path, $rights)
129{
130    if (file_exists($path)) {
131        return true;
132    }
133
134    return @mkdir($path, $rights);
135}
136
137function recursiveTab($idTab)
138{
139    global $cookie, $tabs;
140
141    $adminTab = Tab::getTab((int) $cookie->id_lang, $idTab);
142    $tabs[] = $adminTab;
143    if ($adminTab['id_parent'] > 0) {
144        recursiveTab($adminTab['id_parent']);
145    }
146}
147
148function checkingTab($tab)
149{
150    global $ajaxUpgrader, $cookie;
151
152    $tab = trim($tab);
153    if (!Validate::isTabName($tab)) {
154        return false;
155    }
156
157    $row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql = 'SELECT id_tab, module FROM `'._DB_PREFIX_.'tab` WHERE class_name = \''.pSQL($tab).'\'');
158    if (!$row['id_tab']) {
159        if (isset(\AdminTab::$tabParenting[$tab])) {
160            Tools::redirectAdmin('?tab='.\AdminTab::$tabParenting[$tab].'&token='.Tools::getAdminTokenLite(\AdminTab::$tabParenting[$tab]));
161        }
162        echo Tools::displayError('Tab cannot be found.');
163
164        return false;
165    }
166    if ($row['module'] AND file_exists(_PS_MODULE_DIR_.'/'.$row['module'].'/'.$tab.'.php')) {
167        include_once(_PS_MODULE_DIR_.'/'.$row['module'].'/'.$tab.'.php');
168    } elseif (file_exists(PS_ADMIN_DIR.'/tabs/'.$tab.'.php')) {
169        include_once(PS_ADMIN_DIR.'/tabs/'.$tab.'.php');
170    }
171
172    if (!class_exists($tab, false) OR !$row['id_tab']) {
173        echo Tools::displayError('Tab file cannot be found.');
174
175        return false;
176    }
177    $ajaxUpgrader = new $tab;
178    if (!$ajaxUpgrader->viewAccess()) {
179        $ajaxUpgrader->_errors = [Tools::displayError('Access denied')];
180        echo $ajaxUpgrader->displayErrors();
181
182        return false;
183    }
184
185    return $row['id_tab'];
186}
187
188function checkTabRights($idTab)
189{
190    global $cookie;
191    static $tabAccesses = null;
192
193    if ($tabAccesses === null) {
194        $tabAccesses = Profile::getProfileAccesses($cookie->profile);
195    }
196
197    if (isset($tabAccesses[(int) ($idTab)]['view'])) {
198        return ($tabAccesses[(int) ($idTab)]['view'] === '1');
199    }
200
201    return false;
202}
203
204/**
205 * Converts a simpleXML element into an array. Preserves attributes and everything.
206 * You can choose to get your elements either flattened, or stored in a custom index that
207 * you define.
208 * For example, for a given element
209 * <field name="someName" type="someType"/>
210 * if you choose to flatten attributes, you would get:
211 * $array['field']['name'] = 'someName';
212 * $array['field']['type'] = 'someType';
213 * If you choose not to flatten, you get:
214 * $array['field']['@attributes']['name'] = 'someName';
215 * _____________________________________
216 * Repeating fields are stored in indexed arrays. so for a markup such as:
217 * <parent>
218 * <child>a</child>
219 * <child>b</child>
220 * <child>c</child>
221 * </parent>
222 * you array would be:
223 * $array['parent']['child'][0] = 'a';
224 * $array['parent']['child'][1] = 'b';
225 * ...And so on.
226 * _____________________________________
227 *
228 * @param simpleXMLElement $xml               the XML to convert
229 * @param boolean          $flattenValues     Choose wether to flatten values
230 *                                            or to set them under a particular index.
231 *                                            defaults to true;
232 * @param boolean          $flattenAttributes Choose wether to flatten attributes
233 *                                            or to set them under a particular index.
234 *                                            Defaults to true;
235 * @param boolean          $flattenChildren   Choose wether to flatten children
236 *                                            or to set them under a particular index.
237 *                                            Defaults to true;
238 * @param string           $valueKey          index for values, in case $flattenValues was set to
239 *                                            false. Defaults to "@value"
240 * @param string           $attributesKey     index for attributes, in case $flattenAttributes was set to
241 *                                            false. Defaults to "@attributes"
242 * @param string           $childrenKey       index for children, in case $flattenChildren was set to
243 *                                            false. Defaults to "@children"
244 *
245 * @return array the resulting array.
246 */
247function simpleXMLToArray($xml, $flattenValues = true, $flattenAttributes = true, $flattenChildren = true, $valueKey = '@value', $attributesKey = '@attributes', $childrenKey = '@children')
248{
249    $return = [];
250    if (!($xml instanceof SimpleXMLElement)) {
251        return $return;
252    }
253
254    $name = $xml->getName();
255    $trimmedValue = trim((string) $xml);
256    if (strlen($trimmedValue) == 0) {
257        $trimmedValue = null;
258    }
259
260    if ($trimmedValue !== null) {
261        if (!$flattenValues) {
262            $return[$valueKey] = $trimmedValue;
263        } else {
264            $return = $trimmedValue;
265        }
266    }
267
268    $children = [];
269    $first = true;
270    foreach ($xml->children() as $elementName => $child) {
271        $value = simpleXMLToArray($child, $flattenValues, $flattenAttributes, $flattenChildren, $valueKey, $attributesKey, $childrenKey);
272        if (isset($children[$elementName])) {
273            if ($first) {
274                $temp = $children[$elementName];
275                unset($children[$elementName]);
276                $children[$elementName][] = $temp;
277                $first = false;
278            }
279            $children[$elementName][] = $value;
280        } else {
281            $children[$elementName] = $value;
282        }
283    }
284
285    if (count($children) > 0) {
286        if (!$flattenChildren) {
287            $return[$childrenKey] = $children;
288        } else {
289            $return = array_merge($return, $children);
290        }
291    }
292
293    $attributes = [];
294    foreach ($xml->attributes() as $name => $value) {
295        $attributes[$name] = trim($value);
296    }
297
298    if (count($attributes) > 0) {
299        if (!$flattenAttributes) {
300            $return[$attributesKey] = $attributes;
301        } else {
302            $return = array_merge($return, $attributes);
303        }
304    }
305
306    return $return;
307}
308