/** * {@inheritdoc} * * @param string $key The identifier to write to. * @param array $data The data to dump. * @return bool True on success or false on failure. */ public function dump($key, array $data) { $data = Hash::flatten($data); array_walk($data, [$this, '_persist'], $key); array_filter($data); return (bool) $data; }
/** * Constructor * * @param \Cake\ORM\Entity $entity Entity * @param int $code code to report to client */ public function __construct(Entity $entity, $code = 422) { $this->_validationErrors = array_filter((array) $entity->errors()); $flat = Hash::flatten($this->_validationErrors); $errorCount = $this->_validationErrorCount = count($flat); $this->message = __dn('crud', 'A validation error occurred', '{0} validation errors occurred', $errorCount, [$errorCount]); parent::__construct($this->message, $code); }
/** * @inheritdoc */ public function postLink($title, $url = null, array $options = []) { $options += ['block' => null, 'confirm' => null]; $requestMethod = 'POST'; if (!empty($options['method'])) { $requestMethod = strtoupper($options['method']); unset($options['method']); } $confirmMessage = $options['confirm']; unset($options['confirm']); $formName = str_replace('.', '', uniqid('post_', true)); $formOptions = ['name' => $formName, 'class' => 'csp-hidden', 'method' => 'post']; if (isset($options['target'])) { $formOptions['target'] = $options['target']; unset($options['target']); } $templater = $this->templater(); $this->_lastAction($url); $action = $templater->formatAttributes(['action' => $this->Url->build($url), 'escape' => false]); $out = $templater->format('formStart', ['attrs' => $templater->formatAttributes($formOptions) . $action]); $out .= $this->hidden('_method', ['value' => $requestMethod]); $out .= $this->_csrfField(); $fields = []; if (isset($options['data']) && is_array($options['data'])) { foreach (Hash::flatten($options['data']) as $key => $value) { $fields[$key] = $value; $out .= $this->hidden($key, ['value' => $value]); } unset($options['data']); } $out .= $this->secure($fields); $out .= $templater->format('formEnd', []); if ($options['block']) { if ($options['block'] === true) { $options['block'] = __FUNCTION__; } $this->_View->append($options['block'], $out); $out = ''; } unset($options['block']); $url = '#'; if (!empty($options['class'])) { $options['class'] .= ' csp-' . __FUNCTION__; } else { $options['class'] = 'csp-' . __FUNCTION__; } $options['data-csp-form'] = $formName; if ($confirmMessage) { if (isset($options['escape']) && $options['escape'] === false) { $confirmMessage = h($confirmMessage); } $options['data-csp-confirm'] = $confirmMessage; } $out .= $this->Html->link($title, $url, $options); return $out; }
/** * Add the CSRF and Security Component tokens if necessary. * * @param string $url * @param array $data * @return array */ protected function _addTokens($url, $data) { if ($this->_securityToken === true) { $_data = $this->_unsetUnlockedData($data); $keys = array_map(function ($field) { return preg_replace('/(\\.\\d+)+$/', '', $field); }, array_keys(Hash::flatten($_data))); $tokenData = $this->_buildFieldToken($url, array_unique($keys)); $data['_Token'] = $tokenData; $data['_Token']['debug'] = 'SecurityComponent debug data would be added here'; } $data = $this->_setCsrfToken($data); return $data; }
/** * @param EntityInterface $entity * @return array */ public function getFlatArray(EntityInterface $entity) { $array = $this->getArray($entity, true); $flattened = Hash::flatten($array); $keys = array_keys($flattened); $values = array_values($flattened); foreach ($keys as &$key) { if (preg_match('/^\\w+\\.(\\d+)\\.(\\w+)$/', $key, $matches)) { $key = sprintf('%s[%s]', $matches[2], $matches[1]); } } unset($key); $formatted = array_combine($keys, $values); return $formatted; }
/** * Add the CSRF and Security Component tokens if necessary. * * @param string $url The URL the form is being submitted on. * @param array $data The request body data. * @return array The request body with tokens added. */ protected function _addTokens($url, $data) { if ($this->_securityToken === true) { $keys = array_map(function ($field) { return preg_replace('/(\\.\\d+)+$/', '', $field); }, array_keys(Hash::flatten($data))); $tokenData = $this->_buildFieldToken($url, array_unique($keys)); $data['_Token'] = $tokenData; $data['_Token']['debug'] = 'SecurityComponent debug data would be added here'; } if ($this->_csrfToken === true) { if (!isset($this->_cookie['csrfToken'])) { $this->_cookie['csrfToken'] = Text::uuid(); } if (!isset($data['_csrfToken'])) { $data['_csrfToken'] = $this->_cookie['csrfToken']; } } return $data; }
/** * Add the CSRF and Security Component tokens if necessary. * * @param string $url The URL the form is being submitted on. * @param array $data The request body data. * @return array The request body with tokens added. */ protected function _addTokens($url, $data) { if ($this->_securityToken === true) { $keys = Hash::flatten($data); $tokenData = $this->_buildFieldToken($url, $keys); $data['_Token'] = $tokenData; } if ($this->_csrfToken === true) { $csrfToken = Text::uuid(); if (!isset($data['_csrfToken'])) { $data['_csrfToken'] = $csrfToken; } if (!isset($this->_cookie['csrfToken'])) { $this->_cookie['csrfToken'] = $csrfToken; } } return $data; }
/** * Get the number of files included in this request. * * @return string */ public function summary() { $data = $this->_data; if (empty($data)) { $data = $this->_prepare(); } return count(Hash::flatten($data)); }
/** * Return a list of all commands * * @return array */ public function commands() { $shellList = $this->getShellList(); $flatten = Hash::flatten($shellList); $duplicates = array_intersect($flatten, array_unique(array_diff_key($flatten, array_unique($flatten)))); $duplicates = Hash::expand($duplicates); $options = []; foreach ($shellList as $type => $commands) { foreach ($commands as $shell) { $prefix = ''; if (!in_array(strtolower($type), ['app', 'core']) && isset($duplicates[$type]) && in_array($shell, $duplicates[$type])) { $prefix = $type . '.'; } $options[] = $prefix . $shell; } } return $options; }
public function buildUrl($item, $request) { $url = $item['url']; $params = Hash::flatten($request); $result = []; if (is_array($url)) { foreach ($url as $key => $value) { if (is_string($value)) { if (!is_int($key)) { $result[$key] = Text::insert($value, $params); } else { $result[] = Text::insert($value, $params); } } else { $result[$key] = $value; } } } else { $result = Text::insert($url, $params); } return Router::url($result); }
/** * Creates an HTML link, but access the URL using the method you specify * (defaults to POST). Requires javascript to be enabled in browser. * * This method creates a `<form>` element. If you want to use this method inside of an * existing form, you must use the `block` option so that the new form is being set to * a view block that can be rendered outside of the main form. * * If all you are looking for is a button to submit your form, then you should use * `FormHelper::button()` or `FormHelper::submit()` instead. * * ### Options: * * - `data` - Array with key/value to pass in input hidden * - `method` - Request method to use. Set to 'delete' to simulate * HTTP/1.1 DELETE request. Defaults to 'post'. * - `confirm` - Confirm message to show. * - `block` - Set to true to append form to view block "postLink" or provide * custom block name. * - Other options are the same of HtmlHelper::link() method. * - The option `onclick` will be replaced. * * @param string $title The content to be wrapped by <a> tags. * @param string|array|null $url Cake-relative URL or array of URL parameters, or * external URL (starts with http://) * @param array $options Array of HTML attributes. * @return string An `<a />` element. * @link http://book.cakephp.org/3.0/en/views/helpers/form.html#creating-standalone-buttons-and-post-links */ public function postLink($title, $url = null, array $options = []) { $options += ['block' => null, 'confirm' => null]; $requestMethod = 'POST'; if (!empty($options['method'])) { $requestMethod = strtoupper($options['method']); unset($options['method']); } $confirmMessage = $options['confirm']; unset($options['confirm']); $formName = str_replace('.', '', uniqid('post_', true)); $formOptions = ['name' => $formName, 'style' => 'display:none;', 'method' => 'post']; if (isset($options['target'])) { $formOptions['target'] = $options['target']; unset($options['target']); } $templater = $this->templater(); $restoreAction = $this->_lastAction; $this->_lastAction($url); $action = $templater->formatAttributes(['action' => $this->Url->build($url), 'escape' => false]); $out = $this->formatTemplate('formStart', ['attrs' => $templater->formatAttributes($formOptions) . $action]); $out .= $this->hidden('_method', ['value' => $requestMethod, 'secure' => static::SECURE_SKIP]); $out .= $this->_csrfField(); $fields = []; if (isset($options['data']) && is_array($options['data'])) { foreach (Hash::flatten($options['data']) as $key => $value) { $fields[$key] = $value; $out .= $this->hidden($key, ['value' => $value, 'secure' => static::SECURE_SKIP]); } unset($options['data']); } $out .= $this->secure($fields); $out .= $this->formatTemplate('formEnd', []); $this->_lastAction = $restoreAction; if ($options['block']) { if ($options['block'] === true) { $options['block'] = __FUNCTION__; } $this->_View->append($options['block'], $out); $out = ''; } unset($options['block']); $url = '#'; $onClick = 'document.' . $formName . '.submit();'; if ($confirmMessage) { $options['onclick'] = $this->_confirm($confirmMessage, $onClick, '', $options); } else { $options['onclick'] = $onClick . ' '; } $options['onclick'] .= 'event.returnValue = false; return false;'; $out .= $this->Html->link($title, $url, $options); return $out; }
/** * Returns the extracted parameters from a parameters string. * * @param string $params The parameters string * @return array */ protected function formatParams($params) { //Clean parameters $params = preg_replace('/(\'[^\']+\')::[^ ,\\]]+/', '\\1', $params); if (preg_match('/^ARRAY\\[(.*)\\]$/', $params, $arrayParams)) { $params = [preg_split('/, /', $arrayParams[1], null, PREG_SPLIT_NO_EMPTY)]; } else { $params = preg_split('/, /', $params, null, PREG_SPLIT_NO_EMPTY); } //Trim quotes around values foreach (Hash::flatten($params) as $path => $value) { $params = Hash::insert($params, $path, preg_replace('/^\'(.*)\'$/', '\\1', $value)); } return $params; }
/** * adds a new ARO to the tree * * @param array $aro one or more ARO records * @return void */ public function addRole(array $aro) { foreach ($aro as $role => $inheritedRoles) { if (!isset($this->_tree[$role])) { $this->_tree[$role] = array(); } if (!empty($inheritedRoles)) { if (is_string($inheritedRoles)) { $inheritedRoles = array_map('trim', explode(',', $inheritedRoles)); } foreach ($inheritedRoles as $dependency) { // detect cycles $roles = $this->roles($dependency); if (in_array($role, Hash::flatten($roles))) { $path = ''; foreach ($roles as $roleDependencies) { $path .= implode('|', (array) $roleDependencies) . ' -> '; } trigger_error(sprintf('cycle detected when inheriting %s from %s. Path: %s', $role, $dependency, $path . $role)); continue; } if (!isset($this->_tree[$dependency])) { $this->_tree[$dependency] = array(); } $this->_tree[$dependency][] = $role; } } } }
public function southFour() { // Init table $resultsTable = TableRegistry::get('Results'); // Prepare $year1 = Hash::get($this->request->query, 'search_year1'); $month1 = Hash::get($this->request->query, 'search_month1'); $year2 = Hash::get($this->request->query, 'search_year2'); $month2 = Hash::get($this->request->query, 'search_month2'); $head = Hash::get($this->request->query, 'search_head'); $trail = Hash::get($this->request->query, 'search_trail'); $startFormat = ""; $endFormat = ""; $startFormatValue = ""; $endFormatValue = ""; $conditions = ['area' => Configure::read('Area.south.code'), 'level IN' => [1, 9]]; // Setting get data by year, month if (Validation::notBlank($year1)) { $startFormat .= '%Y'; $startFormatValue .= $year1; } if (Validation::notBlank($month1)) { $startFormat .= '%m'; $startFormatValue .= $month1; } if (Validation::notBlank($year2)) { $endFormat .= '%Y'; $endFormatValue .= $year2; } if (Validation::notBlank($month2)) { $endFormat .= '%m'; $endFormatValue .= $month2; } if ($startFormat) { $conditions[] = "DATE_FORMAT(date_result, '{$startFormat}') >= {$startFormatValue}"; } if ($endFormat) { $conditions[] = "DATE_FORMAT(date_result, '{$endFormat}') <= {$endFormatValue}"; } // Setting get data by head, trail if (Validation::notBlank($head)) { $conditions[] = "MID(content, -2, 1) = {$head}"; } if (Validation::notBlank($trail)) { $conditions[] = "MID(content, -1) = {$trail}"; } $query = $resultsTable->find('all'); $trailTwo = $query->func()->mid(['content' => 'literal', '-2']); $query->select(['id', 'date_result', 'trail' => $trailTwo, 'city', 'level'])->where($conditions)->order(['date_result' => 'DESC', 'city' => 'ASC', 'level' => 'DESC']); // process space $htmlSpace = []; $htmlSpaceHead = []; if (Validation::notBlank($head)) { $sorted = $query->sortBy(function ($trail) { return $trail->date_result->i18nFormat('yyyyMMdd'); }, SORT_ASC); foreach ($sorted as $key => $value) { $date = new \DateTime($value->date_result->i18nFormat('yyyy-MM-dd')); $line = in_array($value->city, Configure::read('COMMAND.CHANNEL.line1')) ? 1 : 2; $line = $line . "_" . ($value->level == 9 ? 1 : 2); $prevDate = isset($htmlSpace[$line]) ? $htmlSpace[$line]['prev_date'] : $date; $space = $prevDate->diff($date)->format("%a"); // Check is space greater two month $spaceMonth = $date->format('Ym') - $prevDate->format('Ym'); if ($space > 30 && $spaceMonth != 1 && $spaceMonth != 89) { continue; } if ($prevDate->format('Y-m-d') != $date->format('Y-m-d')) { $htmlSpace[$line][$space][] = $prevDate->format('Y-m-d') . " - " . $date->format('Y-m-d'); $htmlSpace[$line]["{$space}_count"] = count($htmlSpace[$line][$space]); } $htmlSpace[$line]['prev_date'] = $date; krsort($htmlSpace[$line]); if (!in_array($space, $htmlSpaceHead)) { $htmlSpaceHead[] = $space; } } ksort($htmlSpace); rsort($htmlSpaceHead); $htmlSpace = Hash::flatten($htmlSpace); //var_dump($htmlSpaceHead); //var_dump($htmlSpace);exit; } $this->set('trails', $query); $this->set('htmlSpace', $htmlSpace); $this->set('htmlSpaceHead', $htmlSpaceHead); }
/** * Extracts a list of words to by indexed for given entity. * * NOTE: Words can be repeated, this allows to search phrases. * * @param \Cake\Datasource\EntityInterface $entity The entity for which generate * the list of words * @return string Space-separated list of words. e.g. `cat dog this that` */ protected function _extractEntityWords(EntityInterface $entity) { $text = ''; $entityArray = $entity->toArray(); $entityArray = Hash::flatten($entityArray); foreach ($entityArray as $key => $value) { if (is_string($value) || is_numeric($value)) { $text .= " {$value}"; } } $text = str_replace(["\n", "\r"], '', trim((string) $text)); // remove new lines $text = strip_tags($text); // remove HTML tags, but keep their content $strict = $this->config('strict'); if (!empty($strict)) { // only: space, digits (0-9), letters (any language), ".", ",", "-", "_", "/", "\" $pattern = is_string($strict) ? $strict : '[^\\p{L}\\p{N}\\s\\@\\.\\,\\-\\_\\/\\0-9]'; $text = preg_replace('/' . $pattern . '/ui', ' ', $text); } $text = trim(preg_replace('/\\s{2,}/i', ' ', $text)); // remove double spaces $text = mb_strtolower($text); // all to lowercase $text = $this->_filterText($text); // filter $text = iconv('UTF-8', 'UTF-8//IGNORE', mb_convert_encoding($text, 'UTF-8')); // remove any invalid character return trim($text); }
/** * Dumps the state of Configure data into an ini formatted string. * * @param string $key The identifier to write to. If the key has a . it will be treated * as a plugin prefix. * @param array $data The data to convert to ini file. * @return bool Success. */ public function dump($key, array $data) { $result = []; foreach ($data as $k => $value) { $isSection = false; if ($k[0] !== '[') { $result[] = "[{$k}]"; $isSection = true; } if (is_array($value)) { $kValues = Hash::flatten($value, '.'); foreach ($kValues as $k2 => $v) { $result[] = "{$k2} = " . $this->_value($v); } } if ($isSection) { $result[] = ''; } } $contents = trim(implode("\n", $result)); $filename = $this->_getFilePath($key); return file_put_contents($filename, $contents) > 0; }
/** * Validate submitted form * * @param Controller $controller Instantiating controller * @return bool true if submitted form is valid */ protected function _validatePost(Controller $controller) { if (empty($controller->request->data)) { return true; } $check = $controller->request->data; if (!isset($check['_Token']) || !isset($check['_Token']['fields']) || !isset($check['_Token']['unlocked'])) { return false; } $locked = ''; $token = urldecode($check['_Token']['fields']); $unlocked = urldecode($check['_Token']['unlocked']); if (strpos($token, ':')) { list($token, $locked) = explode(':', $token, 2); } unset($check['_Token'], $check['_csrfToken']); $locked = explode('|', $locked); $unlocked = explode('|', $unlocked); $lockedFields = []; $fields = Hash::flatten($check); $fieldList = array_keys($fields); $multi = []; foreach ($fieldList as $i => $key) { if (preg_match('/(\\.\\d+){1,10}$/', $key)) { $multi[$i] = preg_replace('/(\\.\\d+){1,10}$/', '', $key); unset($fieldList[$i]); } else { $fieldList[$i] = (string) $key; } } if (!empty($multi)) { $fieldList += array_unique($multi); } $unlockedFields = array_unique(array_merge((array) $this->config('disabledFields'), (array) $this->_config['unlockedFields'], $unlocked)); foreach ($fieldList as $i => $key) { $isLocked = is_array($locked) && in_array($key, $locked); if (!empty($unlockedFields)) { foreach ($unlockedFields as $off) { $off = explode('.', $off); $field = array_values(array_intersect(explode('.', $key), $off)); $isUnlocked = $field === $off; if ($isUnlocked) { break; } } } if ($isUnlocked || $isLocked) { unset($fieldList[$i]); if ($isLocked) { $lockedFields[$key] = $fields[$key]; } } } sort($unlocked, SORT_STRING); sort($fieldList, SORT_STRING); ksort($lockedFields, SORT_STRING); $fieldList += $lockedFields; $unlocked = implode('|', $unlocked); $hashParts = [$controller->request->here(), serialize($fieldList), $unlocked, Security::salt()]; $check = Security::hash(implode('', $hashParts), 'sha1'); return $token === $check; }
/** * @param string $type: flaten or array * @return array */ public function getResources($type = 'flatten') { $controllers = $this->findControllers(); foreach (Configure::read('Hook.plugins') as $plugin) { $pluginName = Inflector::camelize($plugin); foreach (App::path('Plugin') as $pluginPath) { $pluginName = str_replace('Spider/', '', $pluginName); if (Plugin::loaded($pluginName)) { if (is_dir($pluginPath . $pluginName)) { $findedControllers = $this->findControllers($pluginPath . $pluginName . DS . 'src' . DS); if (!empty($findedControllers)) { $controllers[$pluginName] = $findedControllers; } break; } } } } $resources = []; foreach ($controllers as $pluginName => $controller) { if (is_integer($pluginName)) { $className = 'App' . DS . $controller; $cname = str_replace(['Controller' . DS, 'Controller', DS], ['', '', '/'], $controller); $className = str_replace('/', '\\', $className); $actions = $this->getActions($className); $resources[$cname] = $actions; } else { foreach ($controller as $controllerName) { $cname = str_replace(['Controller' . DS, 'Controller', DS], ['', '', '/'], $controllerName); $pName = $pluginName; $className = $pluginName . DS . $controllerName; $className = str_replace('/', '\\', $className); $actions = $this->getActions($className); $resources['plugin'][$pName][$cname] = $actions; } } } if ($type == 'flatten') { return Hash::flatten($resources, '/'); } return $resources; }
/** * Test that flattening a large complex set doesn't loop forever. * * @return void */ public function testFlattenInfiniteLoop() { $data = ['Order.ASI' => '0', 'Order.Accounting' => '0', 'Order.Admin' => '0', 'Order.Art' => '0', 'Order.ArtChecker' => '0', 'Order.Canned' => '0', 'Order.Customer_Tags' => '', 'Order.Embroidery' => '0', 'Order.Item.0.Product.style_number' => 'a11222', 'Order.Item.0.Product.slug' => 'a11222', 'Order.Item.0.Product._id' => '4ff8b8d3d7bbe8ad30000000', 'Order.Item.0.Product.Color.slug' => 'kelly_green', 'Order.Item.0.Product.ColorSizes.0.Color.color' => 'Sport Grey', 'Order.Item.0.Product.ColorSizes.0.Color.slug' => 'sport_grey', 'Order.Item.0.Product.ColorSizes.1.Color.color' => 'Kelly Green', 'Order.Item.0.Product.ColorSizes.1.Color.slug' => 'kelly_green', 'Order.Item.0.Product.ColorSizes.2.Color.color' => 'Orange', 'Order.Item.0.Product.ColorSizes.2.Color.slug' => 'orange', 'Order.Item.0.Product.ColorSizes.3.Color.color' => 'Yellow Haze', 'Order.Item.0.Product.ColorSizes.3.Color.slug' => 'yellow_haze', 'Order.Item.0.Product.brand' => 'OUTER BANKS', 'Order.Item.0.Product.style' => 'T-shirt', 'Order.Item.0.Product.description' => 'uhiuhuih oin ooi ioo ioio', 'Order.Item.0.Product.sizes.0.Size.qty' => '', 'Order.Item.0.Product.sizes.0.Size.size' => '0-3mo', 'Order.Item.0.Product.sizes.0.Size.id' => '38', 'Order.Item.0.Product.sizes.1.Size.qty' => '', 'Order.Item.0.Product.sizes.1.Size.size' => '3-6mo', 'Order.Item.0.Product.sizes.1.Size.id' => '39', 'Order.Item.0.Product.sizes.2.Size.qty' => '78', 'Order.Item.0.Product.sizes.2.Size.size' => '6-9mo', 'Order.Item.0.Product.sizes.2.Size.id' => '40', 'Order.Item.0.Product.sizes.3.Size.qty' => '', 'Order.Item.0.Product.sizes.3.Size.size' => '6-12mo', 'Order.Item.0.Product.sizes.3.Size.id' => '41', 'Order.Item.0.Product.sizes.4.Size.qty' => '', 'Order.Item.0.Product.sizes.4.Size.size' => '12-18mo', 'Order.Item.0.Product.sizes.4.Size.id' => '42', 'Order.Item.0.Art.imprint_locations.0.id' => 2, 'Order.Item.0.Art.imprint_locations.0.name' => 'Left Chest', 'Order.Item.0.Art.imprint_locations.0.imprint_type.id' => 7, 'Order.Item.0.Art.imprint_locations.0.imprint_type.type' => 'Embroidery', 'Order.Item.0.Art.imprint_locations.0.art' => '', 'Order.Item.0.Art.imprint_locations.0.num_colors' => 3, 'Order.Item.0.Art.imprint_locations.0.description' => 'Wooo! This is Embroidery!!', 'Order.Item.0.Art.imprint_locations.0.lines.0' => 'Platen', 'Order.Item.0.Art.imprint_locations.0.lines.1' => 'Logo', 'Order.Item.0.Art.imprint_locations.0.height' => 4, 'Order.Item.0.Art.imprint_locations.0.width' => 5, 'Order.Item.0.Art.imprint_locations.0.stitch_density' => 'Light', 'Order.Item.0.Art.imprint_locations.0.metallic_thread' => true, 'Order.Item.0.Art.imprint_locations.1.id' => 4, 'Order.Item.0.Art.imprint_locations.1.name' => 'Full Back', 'Order.Item.0.Art.imprint_locations.1.imprint_type.id' => 6, 'Order.Item.0.Art.imprint_locations.1.imprint_type.type' => 'Screenprinting', 'Order.Item.0.Art.imprint_locations.1.art' => '', 'Order.Item.0.Art.imprint_locations.1.num_colors' => 3, 'Order.Item.0.Art.imprint_locations.1.description' => 'Wooo! This is Screenprinting!!', 'Order.Item.0.Art.imprint_locations.1.lines.0' => 'Platen', 'Order.Item.0.Art.imprint_locations.1.lines.1' => 'Logo', 'Order.Item.0.Art.imprint_locations.2.id' => 26, 'Order.Item.0.Art.imprint_locations.2.name' => 'HS - JSY Name Below', 'Order.Item.0.Art.imprint_locations.2.imprint_type.id' => 9, 'Order.Item.0.Art.imprint_locations.2.imprint_type.type' => 'Names', 'Order.Item.0.Art.imprint_locations.2.description' => 'Wooo! This is Names!!', 'Order.Item.0.Art.imprint_locations.2.sizes.S.0.active' => 1, 'Order.Item.0.Art.imprint_locations.2.sizes.S.0.name' => 'Benjamin Talavera', 'Order.Item.0.Art.imprint_locations.2.sizes.S.0.color' => 'Red', 'Order.Item.0.Art.imprint_locations.2.sizes.S.0.height' => '3', 'Order.Item.0.Art.imprint_locations.2.sizes.S.0.layout' => 'Arched', 'Order.Item.0.Art.imprint_locations.2.sizes.S.0.style' => 'Classic', 'Order.Item.0.Art.imprint_locations.2.sizes.S.1.active' => 0, 'Order.Item.0.Art.imprint_locations.2.sizes.S.1.name' => 'Rishi Narayan', 'Order.Item.0.Art.imprint_locations.2.sizes.S.1.color' => 'Cardinal', 'Order.Item.0.Art.imprint_locations.2.sizes.S.1.height' => '4', 'Order.Item.0.Art.imprint_locations.2.sizes.S.1.layout' => 'Straight', 'Order.Item.0.Art.imprint_locations.2.sizes.S.1.style' => 'Team US', 'Order.Item.0.Art.imprint_locations.2.sizes.M.0.active' => 1, 'Order.Item.0.Art.imprint_locations.2.sizes.M.0.name' => 'Brandon Plasters', 'Order.Item.0.Art.imprint_locations.2.sizes.M.0.color' => 'Red', 'Order.Item.0.Art.imprint_locations.2.sizes.M.0.height' => '3', 'Order.Item.0.Art.imprint_locations.2.sizes.M.0.layout' => 'Arched', 'Order.Item.0.Art.imprint_locations.2.sizes.M.0.style' => 'Classic', 'Order.Item.0.Art.imprint_locations.2.sizes.M.1.active' => 0, 'Order.Item.0.Art.imprint_locations.2.sizes.M.1.name' => 'Andrew Reed', 'Order.Item.0.Art.imprint_locations.2.sizes.M.1.color' => 'Cardinal', 'Order.Item.0.Art.imprint_locations.2.sizes.M.1.height' => '4', 'Order.Item.0.Art.imprint_locations.2.sizes.M.1.layout' => 'Straight', 'Order.Item.0.Art.imprint_locations.2.sizes.M.1.style' => 'Team US', 'Order.Job.0._id' => 'job-1', 'Order.Job.0.type' => 'screenprinting', 'Order.Job.0.postPress' => 'job-2', 'Order.Job.1._id' => 'job-2', 'Order.Job.1.type' => 'embroidery', 'Order.Postpress' => '0', 'Order.PriceAdjustment.0._id' => 'price-adjustment-1', 'Order.PriceAdjustment.0.adjustment' => '-20', 'Order.PriceAdjustment.0.adjustment_type' => 'percent', 'Order.PriceAdjustment.0.type' => 'grand_total', 'Order.PriceAdjustment.1.adjustment' => '20', 'Order.PriceAdjustment.1.adjustment_type' => 'flat', 'Order.PriceAdjustment.1.min-items' => '10', 'Order.PriceAdjustment.1.type' => 'min-items', 'Order.PriceAdjustment.1._id' => 'another-test-adjustment', 'Order.Purchasing' => '0', 'Order.QualityControl' => '0', 'Order.Receiving' => '0', 'Order.ScreenPrinting' => '0', 'Order.Stage.art_approval' => 0, 'Order.Stage.draft' => 1, 'Order.Stage.quote' => 1, 'Order.Stage.order' => 1, 'Order.StoreLiason' => '0', 'Order.Tag_UI_Email' => '', 'Order.Tags' => '', 'Order._id' => 'test-2', 'Order.add_print_location' => '', 'Order.created' => '2011-Dec-29 05:40:18', 'Order.force_admin' => '0', 'Order.modified' => '2012-Jul-25 01:24:49', 'Order.name' => 'towering power', 'Order.order_id' => '135961', 'Order.slug' => 'test-2', 'Order.title' => 'test job 2', 'Order.type' => 'ttt']; $expanded = Hash::expand($data); $flattened = Hash::flatten($expanded); $this->assertEquals($data, $flattened); }
/** * Return the fields list for the hash calculation * * @param array $check Data array * @return array */ protected function _fieldsList(array $check) { $locked = ''; $token = urldecode($check['_Token']['fields']); $unlocked = $this->_unlocked($check); if (strpos($token, ':')) { list($token, $locked) = explode(':', $token, 2); } unset($check['_Token'], $check['_csrfToken']); $locked = explode('|', $locked); $unlocked = explode('|', $unlocked); $fields = Hash::flatten($check); $fieldList = array_keys($fields); $multi = $lockedFields = []; $isUnlocked = false; foreach ($fieldList as $i => $key) { if (preg_match('/(\\.\\d+){1,10}$/', $key)) { $multi[$i] = preg_replace('/(\\.\\d+){1,10}$/', '', $key); unset($fieldList[$i]); } else { $fieldList[$i] = (string) $key; } } if (!empty($multi)) { $fieldList += array_unique($multi); } $unlockedFields = array_unique(array_merge((array) $this->config('disabledFields'), (array) $this->_config['unlockedFields'], $unlocked)); foreach ($fieldList as $i => $key) { $isLocked = is_array($locked) && in_array($key, $locked); if (!empty($unlockedFields)) { foreach ($unlockedFields as $off) { $off = explode('.', $off); $field = array_values(array_intersect(explode('.', $key), $off)); $isUnlocked = $field === $off; if ($isUnlocked) { break; } } } if ($isUnlocked || $isLocked) { unset($fieldList[$i]); if ($isLocked) { $lockedFields[$key] = $fields[$key]; } } } sort($fieldList, SORT_STRING); ksort($lockedFields, SORT_STRING); $fieldList += $lockedFields; return $fieldList; }