Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like contentBlueprintsPages often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use contentBlueprintsPages, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 13 | class contentBlueprintsPages extends AdministrationPage |
||
| 14 | { |
||
| 15 | public $_errors = array(); |
||
| 16 | protected $_hilights = array(); |
||
| 17 | |||
| 18 | /** |
||
| 19 | * The Pages page has /action/id/flag/ context. |
||
| 20 | * eg. /edit/1/saved/ |
||
| 21 | * |
||
| 22 | * @param array $context |
||
| 23 | * @param array $parts |
||
| 24 | * @return array |
||
| 25 | */ |
||
| 26 | View Code Duplication | public function parseContext(array &$context, array $parts) |
|
| 39 | |||
| 40 | public function insertBreadcrumbsUsingPageIdentifier($page_id, $preserve_last = true) |
||
| 83 | |||
| 84 | public function __viewIndex() |
||
| 85 | { |
||
| 86 | $this->setPageType('table'); |
||
| 87 | $this->setTitle(__('%1$s – %2$s', array(__('Pages'), __('Symphony')))); |
||
| 88 | |||
| 89 | $nesting = Symphony::Configuration()->get('pages_table_nest_children', 'symphony') === 'yes'; |
||
| 90 | |||
| 91 | if ($nesting && isset($_GET['parent']) && is_numeric($_GET['parent'])) { |
||
| 92 | $parent = PageManager::fetchPageByID((int)$_GET['parent'], array('title', 'id')); |
||
| 93 | } |
||
| 94 | |||
| 95 | $this->appendSubheading(isset($parent) ? $parent['title'] : __('Pages'), Widget::Anchor( |
||
| 96 | __('Create New'), Administration::instance()->getCurrentPageURL() . 'new/' . ($nesting && isset($parent) ? "?parent={$parent['id']}" : null), |
||
| 97 | __('Create a new page'), 'create button', null, array('accesskey' => 'c') |
||
| 98 | )); |
||
| 99 | |||
| 100 | if (isset($parent)) { |
||
| 101 | $this->insertBreadcrumbsUsingPageIdentifier($parent['id'], false); |
||
| 102 | } |
||
| 103 | |||
| 104 | $aTableHead = array( |
||
| 105 | array(__('Name'), 'col'), |
||
| 106 | array(__('Template'), 'col'), |
||
| 107 | array('<abbr title="' . __('Universal Resource Locator') . '">' . __('URL') . '</abbr>', 'col'), |
||
| 108 | array(__('Parameters'), 'col'), |
||
| 109 | array(__('Type'), 'col') |
||
| 110 | ); |
||
| 111 | $aTableBody = array(); |
||
| 112 | |||
| 113 | if ($nesting) { |
||
| 114 | $aTableHead[] = array(__('Children'), 'col'); |
||
| 115 | $where = array( |
||
| 116 | 'parent ' . (isset($parent) ? " = {$parent['id']} " : ' IS NULL ') |
||
| 117 | ); |
||
| 118 | } else { |
||
| 119 | $where = array(); |
||
| 120 | } |
||
| 121 | |||
| 122 | $pages = PageManager::fetch(true, array('*'), $where); |
||
| 123 | |||
| 124 | if (!is_array($pages) || empty($pages)) { |
||
| 125 | $aTableBody = array(Widget::TableRow(array( |
||
| 126 | Widget::TableData(__('None found.'), 'inactive', null, count($aTableHead)) |
||
| 127 | ), 'odd')); |
||
| 128 | } else { |
||
| 129 | foreach ($pages as $page) { |
||
| 130 | $class = array(); |
||
| 131 | |||
| 132 | $page_title = ($nesting ? $page['title'] : PageManager::resolvePageTitle($page['id'])); |
||
| 133 | $page_url = URL . '/' . PageManager::resolvePagePath($page['id']) . '/'; |
||
| 134 | $page_edit_url = Administration::instance()->getCurrentPageURL() . 'edit/' . $page['id'] . '/'; |
||
| 135 | $page_template = PageManager::createFilePath($page['path'], $page['handle']); |
||
| 136 | |||
| 137 | $col_title = Widget::TableData(Widget::Anchor($page_title, $page_edit_url, $page['handle'])); |
||
| 138 | $col_title->appendChild(Widget::Label(__('Select Page %s', array($page_title)), null, 'accessible', null, array( |
||
| 139 | 'for' => 'page-' . $page['id'] |
||
| 140 | ))); |
||
| 141 | $col_title->appendChild(Widget::Input('items['.$page['id'].']', 'on', 'checkbox', array( |
||
| 142 | 'id' => 'page-' . $page['id'] |
||
| 143 | ))); |
||
| 144 | |||
| 145 | $col_template = Widget::TableData($page_template . '.xsl'); |
||
| 146 | |||
| 147 | $col_url = Widget::TableData(Widget::Anchor($page_url, $page_url)); |
||
| 148 | |||
| 149 | View Code Duplication | if ($page['params']) { |
|
| 150 | $col_params = Widget::TableData(trim($page['params'], '/')); |
||
| 151 | } else { |
||
| 152 | $col_params = Widget::TableData(__('None'), 'inactive'); |
||
| 153 | } |
||
| 154 | |||
| 155 | View Code Duplication | if (!empty($page['type'])) { |
|
| 156 | $col_types = Widget::TableData(implode(', ', $page['type'])); |
||
| 157 | } else { |
||
| 158 | $col_types = Widget::TableData(__('None'), 'inactive'); |
||
| 159 | } |
||
| 160 | |||
| 161 | if (in_array($page['id'], $this->_hilights)) { |
||
| 162 | $class[] = 'failed'; |
||
| 163 | } |
||
| 164 | |||
| 165 | $columns = array($col_title, $col_template, $col_url, $col_params, $col_types); |
||
| 166 | |||
| 167 | if ($nesting) { |
||
| 168 | if (PageManager::hasChildPages($page['id'])) { |
||
| 169 | $col_children = Widget::TableData( |
||
| 170 | Widget::Anchor(PageManager::getChildPagesCount($page['id']) . ' →', |
||
| 171 | SYMPHONY_URL . '/blueprints/pages/?parent=' . $page['id']) |
||
| 172 | ); |
||
| 173 | } else { |
||
| 174 | $col_children = Widget::TableData(__('None'), 'inactive'); |
||
| 175 | } |
||
| 176 | |||
| 177 | $columns[] = $col_children; |
||
| 178 | } |
||
| 179 | |||
| 180 | $aTableBody[] = Widget::TableRow( |
||
| 181 | $columns, |
||
| 182 | implode(' ', $class) |
||
| 183 | ); |
||
| 184 | } |
||
| 185 | } |
||
| 186 | |||
| 187 | $table = Widget::Table( |
||
| 188 | Widget::TableHead($aTableHead), null, |
||
| 189 | Widget::TableBody($aTableBody), 'orderable selectable', |
||
| 190 | null, array('role' => 'directory', 'aria-labelledby' => 'symphony-subheading', 'data-interactive' => 'data-interactive') |
||
| 191 | ); |
||
| 192 | |||
| 193 | $this->Form->appendChild($table); |
||
| 194 | |||
| 195 | $version = new XMLElement('p', 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), array( |
||
| 196 | 'id' => 'version' |
||
| 197 | )); |
||
| 198 | $this->Form->appendChild($version); |
||
| 199 | |||
| 200 | $tableActions = new XMLElement('div'); |
||
| 201 | $tableActions->setAttribute('class', 'actions'); |
||
| 202 | |||
| 203 | $options = array( |
||
| 204 | array(null, false, __('With Selected...')), |
||
| 205 | array('delete', false, __('Delete'), 'confirm', null, array( |
||
| 206 | 'data-message' => __('Are you sure you want to delete the selected pages?') |
||
| 207 | )) |
||
| 208 | ); |
||
| 209 | |||
| 210 | /** |
||
| 211 | * Allows an extension to modify the existing options for this page's |
||
| 212 | * With Selected menu. If the `$options` parameter is an empty array, |
||
| 213 | * the 'With Selected' menu will not be rendered. |
||
| 214 | * |
||
| 215 | * @delegate AddCustomActions |
||
| 216 | * @since Symphony 2.3.2 |
||
| 217 | * @param string $context |
||
| 218 | * '/blueprints/pages/' |
||
| 219 | * @param array $options |
||
| 220 | * An array of arrays, where each child array represents an option |
||
| 221 | * in the With Selected menu. Options should follow the same format |
||
| 222 | * expected by `Widget::__SelectBuildOption`. Passed by reference. |
||
| 223 | */ |
||
| 224 | Symphony::ExtensionManager()->notifyMembers('AddCustomActions', '/blueprints/pages/', array( |
||
| 225 | 'options' => &$options |
||
| 226 | )); |
||
| 227 | |||
| 228 | if (!empty($options)) { |
||
| 229 | $tableActions->appendChild(Widget::Apply($options)); |
||
| 230 | $this->Form->appendChild($tableActions); |
||
| 231 | } |
||
| 232 | } |
||
| 233 | |||
| 234 | public function __viewNew() |
||
| 235 | { |
||
| 236 | $this->__viewEdit(); |
||
| 237 | } |
||
| 238 | |||
| 239 | public function __viewEdit() |
||
| 542 | |||
| 543 | public function __compare_pages($a, $b) |
||
| 544 | { |
||
| 545 | return strnatcasecmp($a[2], $b[2]); |
||
| 546 | } |
||
| 547 | |||
| 548 | public function __actionIndex() |
||
| 549 | { |
||
| 550 | $checked = (is_array($_POST['items'])) ? array_keys($_POST['items']) : null; |
||
| 551 | |||
| 552 | if (is_array($checked) && !empty($checked)) { |
||
| 553 | /** |
||
| 554 | * Extensions can listen for any custom actions that were added |
||
| 555 | * through `AddCustomPreferenceFieldsets` or `AddCustomActions` |
||
| 556 | * delegates. |
||
| 557 | * |
||
| 558 | * @delegate CustomActions |
||
| 559 | * @since Symphony 2.3.2 |
||
| 560 | * @param string $context |
||
| 561 | * '/blueprints/pages/' |
||
| 562 | * @param array $checked |
||
| 563 | * An array of the selected rows. The value is usually the ID of the |
||
| 564 | * the associated object. |
||
| 565 | */ |
||
| 566 | Symphony::ExtensionManager()->notifyMembers('CustomActions', '/blueprints/pages/', array( |
||
| 567 | 'checked' => $checked |
||
| 568 | )); |
||
| 569 | |||
| 570 | switch ($_POST['with-selected']) { |
||
| 571 | case 'delete': |
||
| 572 | $this->__actionDelete($checked, SYMPHONY_URL . '/blueprints/pages/'); |
||
| 573 | break; |
||
| 574 | } |
||
| 575 | } |
||
| 576 | } |
||
| 577 | |||
| 578 | public function __actionNew() |
||
| 582 | |||
| 583 | public function __actionEdit() |
||
| 584 | { |
||
| 585 | if ($this->_context['action'] !== 'new' && !$page_id = (int)$this->_context['id']) { |
||
| 586 | redirect(SYMPHONY_URL . '/blueprints/pages/'); |
||
| 587 | } |
||
| 588 | |||
| 589 | $parent_link_suffix = null; |
||
| 590 | |||
| 591 | View Code Duplication | if (isset($_REQUEST['parent']) && is_numeric($_REQUEST['parent'])) { |
|
| 592 | $parent_link_suffix = '?parent=' . $_REQUEST['parent']; |
||
| 593 | } |
||
| 594 | |||
| 595 | if (@array_key_exists('delete', $_POST['action'])) { |
||
| 596 | $this->__actionDelete($page_id, SYMPHONY_URL . '/blueprints/pages/' . $parent_link_suffix); |
||
| 597 | } |
||
| 598 | |||
| 599 | if (@array_key_exists('save', $_POST['action'])) { |
||
| 600 | $fields = $_POST['fields']; |
||
| 601 | $this->_errors = array(); |
||
| 602 | $autogenerated_handle = false; |
||
| 603 | |||
| 604 | View Code Duplication | if (!isset($fields['title']) || trim($fields['title']) === '') { |
|
| 605 | $this->_errors['title'] = __('This is a required field'); |
||
| 606 | } |
||
| 607 | |||
| 608 | if (trim($fields['type']) !== '' && preg_match('/(index|404|403)/i', $fields['type'])) { |
||
| 609 | $types = preg_split('/\s*,\s*/', strtolower($fields['type']), -1, PREG_SPLIT_NO_EMPTY); |
||
| 610 | |||
| 611 | if (in_array('index', $types) && PageManager::hasPageTypeBeenUsed($page_id, 'index')) { |
||
| 612 | $this->_errors['type'] = __('An index type page already exists.'); |
||
| 613 | } elseif (in_array('404', $types) && PageManager::hasPageTypeBeenUsed($page_id, '404')) { |
||
| 614 | $this->_errors['type'] = __('A 404 type page already exists.'); |
||
| 615 | } elseif (in_array('403', $types) && PageManager::hasPageTypeBeenUsed($page_id, '403')) { |
||
| 616 | $this->_errors['type'] = __('A 403 type page already exists.'); |
||
| 617 | } |
||
| 618 | } |
||
| 619 | |||
| 620 | if (trim($fields['handle']) === '') { |
||
| 621 | $fields['handle'] = $fields['title']; |
||
| 622 | $autogenerated_handle = true; |
||
| 623 | } |
||
| 624 | |||
| 625 | $fields['handle'] = PageManager::createHandle($fields['handle']); |
||
| 626 | |||
| 627 | if (empty($fields['handle']) && !isset($this->_errors['title'])) { |
||
| 628 | $this->_errors['handle'] = __('Please ensure handle contains at least one Latin-based character.'); |
||
| 629 | } |
||
| 630 | |||
| 631 | /** |
||
| 632 | * Just after the Symphony validation has run, allows Developers |
||
| 633 | * to run custom validation logic on a Page |
||
| 634 | * |
||
| 635 | * @delegate PagePostValidate |
||
| 636 | * @since Symphony 2.2 |
||
| 637 | * @param string $context |
||
| 638 | * '/blueprints/pages/' |
||
| 639 | * @param array $fields |
||
| 640 | * The `$_POST['fields']` array. This should be read-only and not changed |
||
| 641 | * through this delegate. |
||
| 642 | * @param array $errors |
||
| 643 | * An associative array of errors, with the key matching a key in the |
||
| 644 | * `$fields` array, and the value being the string of the error. `$errors` |
||
| 645 | * is passed by reference. |
||
| 646 | */ |
||
| 647 | Symphony::ExtensionManager()->notifyMembers('PagePostValidate', '/blueprints/pages/', array('fields' => $fields, 'errors' => &$errors)); |
||
| 648 | |||
| 649 | if (empty($this->_errors)) { |
||
| 650 | $autogenerated_handle = false; |
||
| 651 | |||
| 652 | if ($fields['params']) { |
||
| 653 | $fields['params'] = trim(preg_replace('@\/{2,}@', '/', $fields['params']), '/'); |
||
| 654 | } |
||
| 655 | |||
| 656 | // Clean up type list |
||
| 657 | $types = preg_split('/\s*,\s*/', $fields['type'], -1, PREG_SPLIT_NO_EMPTY); |
||
| 658 | $types = @array_map('trim', $types); |
||
| 659 | unset($fields['type']); |
||
| 660 | |||
| 661 | $fields = array_filter($fields); |
||
| 662 | |||
| 663 | $fields['parent'] = ($fields['parent'] !== __('None') ? $fields['parent'] : null); |
||
| 664 | $fields['data_sources'] = is_array($fields['data_sources']) ? implode(',', $fields['data_sources']) : null; |
||
| 665 | $fields['events'] = is_array($fields['events']) ? implode(',', $fields['events']) : null; |
||
| 666 | $fields['path'] = null; |
||
| 667 | |||
| 668 | if ($fields['parent']) { |
||
| 669 | $fields['path'] = PageManager::resolvePagePath((integer)$fields['parent']); |
||
| 670 | } |
||
| 671 | |||
| 672 | // Check for duplicates: |
||
| 673 | $current = PageManager::fetchPageByID($page_id); |
||
| 674 | |||
| 675 | if (empty($current)) { |
||
| 676 | $fields['sortorder'] = PageManager::fetchNextSortOrder(); |
||
| 677 | } |
||
| 678 | |||
| 679 | $where = array(); |
||
| 680 | |||
| 681 | if (!empty($current)) { |
||
| 682 | $where[] = "p.id != {$page_id}"; |
||
| 683 | } |
||
| 684 | |||
| 685 | $where[] = "p.handle = '" . $fields['handle'] . "'"; |
||
| 686 | $where[] = (is_null($fields['path'])) |
||
| 687 | ? "p.path IS null" |
||
| 688 | : "p.path = '" . $fields['path'] . "'"; |
||
| 689 | $duplicate = PageManager::fetch(false, array('*'), $where); |
||
| 690 | |||
| 691 | // If duplicate |
||
| 692 | if (!empty($duplicate)) { |
||
| 693 | if ($autogenerated_handle) { |
||
| 694 | $this->_errors['title'] = __('A page with that title already exists'); |
||
| 695 | } else { |
||
| 696 | $this->_errors['handle'] = __('A page with that handle already exists'); |
||
| 697 | } |
||
| 698 | |||
| 699 | // Create or move files: |
||
| 700 | } else { |
||
| 701 | // New page? |
||
| 702 | if (empty($current)) { |
||
| 703 | $file_created = PageManager::createPageFiles( |
||
| 704 | $fields['path'], |
||
| 705 | $fields['handle'] |
||
| 706 | ); |
||
| 707 | |||
| 708 | // Existing page, potentially rename files |
||
| 709 | } else { |
||
| 710 | $file_created = PageManager::createPageFiles( |
||
| 711 | $fields['path'], |
||
| 712 | $fields['handle'], |
||
| 713 | $current['path'], |
||
| 714 | $current['handle'] |
||
| 715 | ); |
||
| 716 | } |
||
| 717 | |||
| 718 | // If the file wasn't created, it's usually permissions related |
||
| 719 | if (!$file_created) { |
||
| 720 | $redirect = null; |
||
| 721 | return $this->pageAlert( |
||
| 722 | __('Page Template could not be written to disk.') |
||
| 723 | . ' ' . __('Please check permissions on %s.', array('<code>/workspace/pages</code>')), |
||
| 724 | Alert::ERROR |
||
| 725 | ); |
||
| 726 | } |
||
| 727 | |||
| 728 | // Insert the new data: |
||
| 729 | if (empty($current)) { |
||
| 730 | /** |
||
| 731 | * Just prior to creating a new Page record in `tbl_pages`, provided |
||
| 732 | * with the `$fields` associative array. Use with caution, as no |
||
| 733 | * duplicate page checks are run after this delegate has fired |
||
| 734 | * |
||
| 735 | * @delegate PagePreCreate |
||
| 736 | * @since Symphony 2.2 |
||
| 737 | * @param string $context |
||
| 738 | * '/blueprints/pages/' |
||
| 739 | * @param array $fields |
||
| 740 | * The `$_POST['fields']` array passed by reference |
||
| 741 | */ |
||
| 742 | Symphony::ExtensionManager()->notifyMembers('PagePreCreate', '/blueprints/pages/', array('fields' => &$fields)); |
||
| 743 | |||
| 744 | View Code Duplication | if (!$page_id = PageManager::add($fields)) { |
|
| 745 | $this->pageAlert( |
||
| 746 | __('Unknown errors occurred while attempting to save.') |
||
| 747 | . '<a href="' . SYMPHONY_URL . '/system/log/">' |
||
| 748 | . __('Check your activity log') |
||
| 749 | . '</a>.', |
||
| 750 | Alert::ERROR |
||
| 751 | ); |
||
| 752 | } else { |
||
| 753 | /** |
||
| 754 | * Just after the creation of a new page in `tbl_pages` |
||
| 755 | * |
||
| 756 | * @delegate PagePostCreate |
||
| 757 | * @since Symphony 2.2 |
||
| 758 | * @param string $context |
||
| 759 | * '/blueprints/pages/' |
||
| 760 | * @param integer $page_id |
||
| 761 | * The ID of the newly created Page |
||
| 762 | * @param array $fields |
||
| 763 | * An associative array of data that was just saved for this page |
||
| 764 | */ |
||
| 765 | Symphony::ExtensionManager()->notifyMembers('PagePostCreate', '/blueprints/pages/', array('page_id' => $page_id, 'fields' => &$fields)); |
||
| 766 | |||
| 767 | $redirect = "/blueprints/pages/edit/{$page_id}/created/{$parent_link_suffix}"; |
||
| 768 | } |
||
| 769 | |||
| 770 | // Update existing: |
||
| 771 | } else { |
||
| 772 | /** |
||
| 773 | * Just prior to updating a Page record in `tbl_pages`, provided |
||
| 774 | * with the `$fields` associative array. Use with caution, as no |
||
| 775 | * duplicate page checks are run after this delegate has fired |
||
| 776 | * |
||
| 777 | * @delegate PagePreEdit |
||
| 778 | * @since Symphony 2.2 |
||
| 779 | * @param string $context |
||
| 780 | * '/blueprints/pages/' |
||
| 781 | * @param integer $page_id |
||
| 782 | * The ID of the Page that is about to be updated |
||
| 783 | * @param array $fields |
||
| 784 | * The `$_POST['fields']` array passed by reference |
||
| 785 | */ |
||
| 786 | Symphony::ExtensionManager()->notifyMembers('PagePreEdit', '/blueprints/pages/', array('page_id' => $page_id, 'fields' => &$fields)); |
||
| 787 | |||
| 788 | View Code Duplication | if (!PageManager::edit($page_id, $fields, true)) { |
|
| 789 | return $this->pageAlert( |
||
| 790 | __('Unknown errors occurred while attempting to save.') |
||
| 791 | . '<a href="' . SYMPHONY_URL . '/system/log/">' |
||
| 792 | . __('Check your activity log') |
||
| 793 | . '</a>.', |
||
| 794 | Alert::ERROR |
||
| 795 | ); |
||
| 796 | } else { |
||
| 797 | /** |
||
| 798 | * Just after updating a page in `tbl_pages` |
||
| 799 | * |
||
| 800 | * @delegate PagePostEdit |
||
| 801 | * @since Symphony 2.2 |
||
| 802 | * @param string $context |
||
| 803 | * '/blueprints/pages/' |
||
| 804 | * @param integer $page_id |
||
| 805 | * The ID of the Page that was just updated |
||
| 806 | * @param array $fields |
||
| 807 | * An associative array of data that was just saved for this page |
||
| 808 | */ |
||
| 809 | Symphony::ExtensionManager()->notifyMembers('PagePostEdit', '/blueprints/pages/', array('page_id' => $page_id, 'fields' => $fields)); |
||
| 810 | |||
| 811 | $redirect = "/blueprints/pages/edit/{$page_id}/saved/{$parent_link_suffix}"; |
||
| 812 | } |
||
| 813 | } |
||
| 814 | } |
||
| 815 | |||
| 816 | // Only proceed if there was no errors saving/creating the page |
||
| 817 | if (empty($this->_errors)) { |
||
| 818 | /** |
||
| 819 | * Just before the page's types are saved into `tbl_pages_types`. |
||
| 820 | * Use with caution as no further processing is done on the `$types` |
||
| 821 | * array to prevent duplicate `$types` from occurring (ie. two index |
||
| 822 | * page types). Your logic can use the PageManger::hasPageTypeBeenUsed |
||
| 823 | * function to perform this logic. |
||
| 824 | * |
||
| 825 | * @delegate PageTypePreCreate |
||
| 826 | * @since Symphony 2.2 |
||
| 827 | * @see toolkit.PageManager#hasPageTypeBeenUsed |
||
| 828 | * @param string $context |
||
| 829 | * '/blueprints/pages/' |
||
| 830 | * @param integer $page_id |
||
| 831 | * The ID of the Page that was just created or updated |
||
| 832 | * @param array $types |
||
| 833 | * An associative array of the types for this page passed by reference. |
||
| 834 | */ |
||
| 835 | Symphony::ExtensionManager()->notifyMembers('PageTypePreCreate', '/blueprints/pages/', array('page_id' => $page_id, 'types' => &$types)); |
||
| 836 | |||
| 837 | // Assign page types: |
||
| 838 | PageManager::addPageTypesToPage($page_id, $types); |
||
| 839 | |||
| 840 | // Find and update children: |
||
| 841 | if ($this->_context['action'] === 'edit') { |
||
| 842 | PageManager::editPageChildren($page_id, $fields['path'] . '/' . $fields['handle']); |
||
| 843 | } |
||
| 844 | |||
| 845 | if ($redirect) { |
||
| 846 | redirect(SYMPHONY_URL . $redirect); |
||
| 847 | } |
||
| 848 | } |
||
| 849 | } |
||
| 850 | |||
| 851 | // If there was any errors, either with pre processing or because of a |
||
| 852 | // duplicate page, return. |
||
| 853 | View Code Duplication | if (is_array($this->_errors) && !empty($this->_errors)) { |
|
| 854 | return $this->pageAlert( |
||
| 855 | __('An error occurred while processing this form. See below for details.'), |
||
| 856 | Alert::ERROR |
||
| 857 | ); |
||
| 858 | } |
||
| 859 | } |
||
| 860 | } |
||
| 861 | |||
| 862 | public function __actionDelete($pages, $redirect) |
||
| 943 | } |
||
| 944 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.