/** * Pre-process the selectors to add Page status checks * * @param Selectors $selectors * @param array $options * */ protected function setupStatusChecks(Selectors $selectors, array &$options) { $maxStatus = null; $limit = 0; // for getTotal auto detection $start = 0; foreach ($selectors as $key => $selector) { $fieldName = $selector->field; if ($fieldName == 'status') { $value = $selector->value; if (!ctype_digit("{$value}")) { // allow use of some predefined labels for Page statuses if ($value == 'hidden') { $selector->value = Page::statusHidden; } else { if ($value == 'unpublished') { $selector->value = Page::statusUnpublished; } else { if ($value == 'locked') { $selector->value = Page::statusLocked; } else { if ($value == 'trash') { $selector->value = Page::statusTrash; } else { if ($value == 'max') { $selector->value = Page::statusMax; } else { $selector->value = 1; } } } } } } $not = false; if ($selector->operator == '!=' && !$selector->not || $selector->not && $selector->operator == '=') { $s = new SelectorBitwiseAnd('status', $selector->value); $s->not = true; $not = true; $selectors[$key] = $s; } else { if ($selector->operator == '=' || $selector->operator == '!=' && $selector->not) { $selectors[$key] = new SelectorBitwiseAnd('status', $selector->value); } else { $not = $selector->not; // some other operator like: >, <, >=, <= } } if (!$not && (is_null($maxStatus) || $selector->value > $maxStatus)) { $maxStatus = (int) $selector->value; } } else { if ($fieldName == 'include' && $selector->operator == '=' && in_array($selector->value, array('hidden', 'all', 'unpublished', 'trash'))) { if ($selector->value == 'hidden') { $options['findHidden'] = true; } else { if ($selector->value == 'unpublished') { $options['findUnpublished'] = true; } else { if ($selector->value == 'trash') { $options['findTrash'] = true; } else { if ($selector->value == 'all') { $options['findAll'] = true; } } } } $selectors->remove($key); } else { if ($fieldName == 'check_access' || $fieldName == 'checkAccess') { $this->checkAccess = (int) $selector->value > 0 ? true : false; $selectors->remove($key); } else { if ($fieldName == 'limit') { // for getTotal auto detect $limit = (int) $selector->value; } else { if ($fieldName == 'start ') { // for getTotal auto detect $start = (int) $selector->value; } else { if ($fieldName == 'sort') { // sorting is not needed if we are only retrieving totals if ($options['loadPages'] === false) { $selectors->remove($selector); } } else { if ($fieldName == 'getTotal' || $fieldName == 'get_total') { // whether to retrieve the total, and optionally what type: calc or count // this applies only if user hasn't themselves created a field called getTotal or get_total if (!$this->wire('fields')->get($fieldName)) { if (ctype_digit("{$selector->value}")) { $options['getTotal'] = (bool) $selector->value; } else { if (in_array($selector->value, array('calc', 'count'))) { $options['getTotal'] = true; $options['getTotalType'] = $selector->value; } } $selectors->remove($selector); } } } } } } } } } // foreach($selectors) if (!is_null($maxStatus) && empty($options['findAll']) && empty($options['findUnpublished'])) { // if a status was already present in the selector, without a findAll/findUnpublished, then just make sure the page isn't unpublished if ($maxStatus < Page::statusUnpublished) { $selectors->add(new SelectorLessThan('status', Page::statusUnpublished)); } } else { if ($options['findAll']) { // findAll option means that unpublished, hidden, trash, system may be included // $selectors->add(new SelectorLessThan('status', Page::statusMax)); $this->checkAccess = false; } else { if ($options['findOne'] || $options['findHidden']) { // findHidden|findOne option, apply optimizations enabling hidden pages to be loaded $selectors->add(new SelectorLessThan('status', Page::statusUnpublished)); } else { if ($options['findUnpublished']) { $selectors->add(new SelectorLessThan('status', Page::statusTrash)); } else { if ($options['findTrash']) { $selectors->add(new SelectorLessThan('status', Page::statusDeleted)); } else { // no status is present, so exclude everything hidden and above $selectors->add(new SelectorLessThan('status', Page::statusHidden)); } } } } } if ($options['findOne']) { // findOne option is never paginated, always starts at 0 $selectors->add(new SelectorEqual('start', 0)); $selectors->add(new SelectorEqual('limit', 1)); // getTotal default is false when only finding 1 page if (is_null($options['getTotal'])) { $options['getTotal'] = false; } } else { if (!$limit && !$start) { // getTotal is not necessary since there is no limit specified (getTotal=same as count) if (is_null($options['getTotal'])) { $options['getTotal'] = false; } } else { // get Total default is true when finding multiple pages if (is_null($options['getTotal'])) { $options['getTotal'] = true; } } } $this->lastOptions = $options; }
/** * Pre-process the selectors to add Page status checks * */ protected function setupStatusChecks(Selectors $selectors) { $maxStatus = null; $options = $this->options; foreach ($selectors as $key => $selector) { if ($selector->field == 'status') { $value = $selector->value; if (!ctype_digit("{$value}")) { // allow use of some predefined labels for Page statuses if ($value == 'hidden') { $selector->value = Page::statusHidden; } else { if ($value == 'unpublished') { $selector->value = Page::statusUnpublished; } else { if ($value == 'locked') { $selector->value = Page::statusLocked; } else { if ($value == 'max') { $selector->value = Page::statusMax; } else { $selector->value = 1; } } } } if ($selector->operator == '=') { // there is no point in an equals operator here, so we make it a bitwise AND, for simplification $selectors[$key] = new SelectorBitwiseAnd('status', $selector->value); } } if (is_null($maxStatus) || $value > $maxStatus) { $maxStatus = (int) $selector->value; } } else { if ($selector->field == 'include' && $selector->operator == '=' && in_array($selector->value, array('hidden', 'all'))) { if ($selector->value == 'hidden') { $options['findHidden'] = true; } else { if ($selector->value == 'all') { $options['findAll'] = true; } } $selectors->remove($key); } else { if ($selector->field == 'check_access' || $selector->field == 'checkAccess') { $this->checkAccess = (int) $selector->value > 0 ? true : false; $selectors->remove($key); } } } } if (!is_null($maxStatus)) { // if a status was already present in the selector, then just make sure the page isn't unpublished if ($maxStatus < Page::statusUnpublished) { $selectors->add(new SelectorLessThan('status', Page::statusUnpublished)); } } else { if ($options['findAll']) { // findAll option means that unpublished, hidden, trash, system may be included $selectors->add(new SelectorLessThan('status', Page::statusMax)); $this->checkAccess = false; } else { if ($options['findOne'] || $options['findHidden']) { // findHidden|findOne option, apply optimizations enabling hidden pages to be loaded $selectors->add(new SelectorLessThan('status', Page::statusUnpublished)); } else { // no status is present, so exclude everything hidden and above $selectors->add(new SelectorLessThan('status', Page::statusHidden)); } } } if ($options['findOne']) { $selectors->add(new SelectorEqual('start', 0)); $selectors->add(new SelectorEqual('limit', 1)); } }
/** * Filter out Wires that don't match the selector. * * This is applicable to and destructive to the WireArray. * This function contains additions and modifications by @niklaka. * * @param string|Selectors $selectors AttributeSelector string to use as the filter. * @param bool $not Make this a "not" filter? (default is false) * @return WireArray reference to current [filtered] instance * */ protected function filterData($selectors, $not = false) { if (is_object($selectors) && $selectors instanceof Selectors) { // fantastic } else { if (ctype_digit("{$selectors}")) { $selectors = "id={$selectors}"; } $selectors = new Selectors($selectors); } $sort = array(); $start = 0; $limit = null; // leave sort, limit and start away from filtering selectors foreach ($selectors as $selector) { $remove = true; if ($selector->field === 'sort') { // use all sort selectors $sort[] = $selector->value; } else { if ($selector->field === 'start') { // use only the last start selector $start = (int) $selector->value; } else { if ($selector->field === 'limit') { // use only the last limit selector $limit = (int) $selector->value; } else { // everything else is to be saved for filtering $remove = false; } } } if ($remove) { $selectors->remove($selector); } } // now filter the data according to the selectors that remain foreach ($this->data as $key => $item) { foreach ($selectors as $selector) { if (is_array($selector->field)) { $value = array(); foreach ($selector->field as $field) { $value[] = (string) $this->getItemPropertyValue($item, $field); } } else { $value = (string) $this->getItemPropertyValue($item, $selector->field); } if ($not === $selector->matches($value)) { unset($this->data[$key]); } } } // if $limit has been given, tell sort the amount of rows that will be used if (count($sort)) { $this->_sort($sort, $limit ? $start + $limit : null); } if ($start || $limit) { $this->data = array_slice($this->data, $start, $limit, true); } $this->trackChange("filterData:{$selectors}"); return $this; }