Complex classes like ProductGroup_Controller 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 ProductGroup_Controller, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
1696 | |||
1697 | return self::$_result_array[$this->ID]; |
||
1698 | } |
||
1699 | |||
1700 | public function getNumberOfProducts() |
||
1701 | { |
||
1702 | return Product::get()->filter(array('ParentID' => $this->ID))->count(); |
||
1703 | } |
||
1704 | } |
||
1705 | |||
1706 | class ProductGroup_Controller extends Page_Controller |
||
1707 | { |
||
1708 | /** |
||
1709 | * standard SS variable. |
||
1710 | * |
||
1711 | * @var array |
||
1712 | */ |
||
1713 | private static $allowed_actions = array( |
||
1714 | 'debug' => 'ADMIN', |
||
1715 | 'filterforgroup' => true, |
||
1716 | 'ProductSearchForm' => true, |
||
1717 | 'searchresults' => true, |
||
1718 | 'resetfilter' => true, |
||
1719 | ); |
||
1720 | |||
1721 | /** |
||
1722 | * The original Title of this page before filters, etc... |
||
1723 | * |
||
1724 | * @var string |
||
1725 | */ |
||
1726 | protected $originalTitle = ''; |
||
1727 | |||
1728 | /** |
||
1729 | * list of products that are going to be shown. |
||
1730 | * |
||
1731 | * @var DataList |
||
1732 | */ |
||
1733 | protected $products = null; |
||
1734 | |||
1735 | /** |
||
1736 | * Show all products on one page? |
||
1737 | * |
||
1738 | * @var bool |
||
1739 | */ |
||
1740 | protected $showFullList = false; |
||
1741 | |||
1742 | /** |
||
1743 | * The group filter that is applied to this page. |
||
1744 | * |
||
1745 | * @var ProductGroup |
||
1746 | */ |
||
1747 | protected $filterForGroupObject = null; |
||
1748 | |||
1749 | /** |
||
1750 | * Is this a product search? |
||
1751 | * |
||
1752 | * @var bool |
||
1753 | */ |
||
1754 | protected $isSearchResults = false; |
||
1755 | |||
1756 | /** |
||
1757 | * standard SS method. |
||
1758 | */ |
||
1759 | public function init() |
||
1760 | { |
||
1761 | parent::init(); |
||
1762 | $this->originalTitle = $this->Title; |
||
1763 | Requirements::themedCSS('ProductGroup', 'ecommerce'); |
||
1764 | Requirements::themedCSS('ProductGroupPopUp', 'ecommerce'); |
||
1765 | Requirements::javascript('ecommerce/javascript/EcomProducts.js'); |
||
1766 | //we save data from get variables... |
||
1767 | $this->saveUserPreferences(); |
||
1768 | } |
||
1769 | |||
1770 | /**************************************************** |
||
1771 | * ACTIONS |
||
1772 | /****************************************************/ |
||
1773 | |||
1774 | /** |
||
1775 | * standard selection of products. |
||
1776 | */ |
||
1777 | public function index() |
||
1778 | { |
||
1779 | //set the filter and the sort... |
||
1780 | $this->addSecondaryTitle(); |
||
1781 | $this->products = $this->paginateList($this->ProductsShowable(null)); |
||
1782 | if ($this->returnAjaxifiedProductList()) { |
||
1783 | return $this->renderWith('AjaxProductList'); |
||
1784 | } |
||
1785 | return array(); |
||
1786 | } |
||
1787 | |||
1788 | /** |
||
1789 | * cross filter with another product group.. |
||
1790 | * |
||
1791 | * e.g. socks (current product group) for brand A or B (the secondary product group) |
||
1792 | * |
||
1793 | * @param HTTPRequest |
||
1794 | */ |
||
1795 | public function filterforgroup($request) |
||
1796 | { |
||
1797 | $this->resetfilter(); |
||
1798 | $otherGroupURLSegment = Convert::raw2sql($request->param('ID')); |
||
1799 | $arrayOfIDs = array(0 => 0); |
||
1800 | if ($otherGroupURLSegment) { |
||
1801 | $otherProductGroup = DataObject::get_one( |
||
1802 | 'ProductGroup', |
||
1803 | array('URLSegment' => $otherGroupURLSegment) |
||
1804 | ); |
||
1805 | if ($otherProductGroup) { |
||
1806 | $this->filterForGroupObject = $otherProductGroup; |
||
1807 | $arrayOfIDs = $otherProductGroup->currentInitialProductsAsCachedArray($this->getMyUserPreferencesDefault('FILTER')); |
||
1808 | } |
||
1809 | } |
||
1810 | $this->addSecondaryTitle(); |
||
1811 | $this->products = $this->paginateList($this->ProductsShowable(array('ID' => $arrayOfIDs))); |
||
1812 | if ($this->returnAjaxifiedProductList()) { |
||
1813 | return $this->renderWith('AjaxProductList'); |
||
1814 | } |
||
1815 | |||
1816 | return array(); |
||
1817 | } |
||
1818 | |||
1819 | /** |
||
1820 | * get the search results. |
||
1821 | * |
||
1822 | * @param HTTPRequest |
||
1823 | */ |
||
1824 | public function searchresults($request) |
||
1825 | { |
||
1826 | $this->resetfilter(); |
||
1827 | $this->isSearchResults = true; |
||
1828 | //reset filter and sort |
||
1829 | $resultArray = $this->searchResultsArrayFromSession(); |
||
1830 | if (!$resultArray || !count($resultArray)) { |
||
1831 | $resultArray = array(0 => 0); |
||
1832 | } |
||
1833 | $defaultKeySort = $this->getMyUserPreferencesDefault('SORT'); |
||
1834 | $myKeySort = $this->getCurrentUserPreferences('SORT'); |
||
1835 | $searchArray = null; |
||
1836 | if ($defaultKeySort == $myKeySort) { |
||
1837 | $searchArray = $resultArray; |
||
1838 | } |
||
1839 | $this->addSecondaryTitle(); |
||
1840 | $this->products = $this->paginateList($this->ProductsShowable(array('ID' => $resultArray), $searchArray)); |
||
1841 | |||
1842 | return array(); |
||
1843 | } |
||
1844 | |||
1845 | /** |
||
1846 | * resets the filter only. |
||
1847 | */ |
||
1848 | public function resetfilter() |
||
1849 | { |
||
1850 | $defaultKey = $this->getMyUserPreferencesDefault('FILTER'); |
||
1851 | $filterGetVariable = $this->getSortFilterDisplayNames('FILTER', 'getVariable'); |
||
1852 | $this->saveUserPreferences( |
||
1853 | array( |
||
1854 | $filterGetVariable => $defaultKey, |
||
1855 | ) |
||
1856 | ); |
||
1857 | |||
1858 | return array(); |
||
1859 | } |
||
1860 | |||
1861 | /**************************************************** |
||
1862 | * TEMPLATE METHODS PRODUCTS |
||
1863 | /****************************************************/ |
||
1864 | |||
1865 | /** |
||
1866 | * Return the products for this group. |
||
1867 | * This is the call that is made from the template... |
||
1868 | * The actual final products being shown. |
||
1869 | * |
||
1870 | * @return PaginatedList |
||
1871 | **/ |
||
1872 | public function Products() |
||
1873 | { |
||
1874 | //IMPORTANT! |
||
1875 | //two universal actions! |
||
1876 | $this->addSecondaryTitle(); |
||
1877 | $this->cachingRelatedJavascript(); |
||
1878 | |||
1879 | //save products to session for later use |
||
1880 | $stringOfIDs = ''; |
||
1881 | $array = $this->getProductsThatCanBePurchasedArray(); |
||
1882 | if (is_array($array)) { |
||
1883 | $stringOfIDs = implode(',', $array); |
||
1884 | } |
||
1885 | //save list for future use |
||
1886 | Session::set(EcommerceConfig::get('ProductGroup', 'session_name_for_product_array'), $stringOfIDs); |
||
1887 | |||
1888 | return $this->products; |
||
1889 | } |
||
1890 | |||
1891 | /** |
||
1892 | * you can overload this function of ProductGroup Extensions. |
||
1893 | * |
||
1894 | * @return bool |
||
1895 | */ |
||
1896 | protected function returnAjaxifiedProductList() |
||
1897 | { |
||
1898 | return Director::is_ajax() ? true : false; |
||
1899 | } |
||
1900 | |||
1901 | /** |
||
1902 | * is the product list cache-able? |
||
1903 | * |
||
1904 | * @return bool |
||
1905 | */ |
||
1906 | public function ProductGroupListAreCacheable() |
||
1907 | { |
||
1908 | if ($this->productListsHTMLCanBeCached()) { |
||
1909 | //exception 1 |
||
1910 | if ($this->IsSearchResults()) { |
||
1911 | return false; |
||
1912 | } |
||
1913 | //exception 2 |
||
1914 | $currentOrder = ShoppingCart::current_order(); |
||
1915 | if ($currentOrder->getHasAlternativeCurrency()) { |
||
1916 | return false; |
||
1917 | } |
||
1918 | //can be cached... |
||
1919 | return true; |
||
1920 | } |
||
1921 | |||
1922 | return false; |
||
1923 | } |
||
1924 | |||
1925 | /** |
||
1926 | * is the product list ajaxified. |
||
1927 | * |
||
1928 | * @return bool |
||
1929 | */ |
||
1930 | public function ProductGroupListAreAjaxified() |
||
1931 | { |
||
1932 | return $this->IsSearchResults() ? false : true; |
||
1933 | } |
||
1934 | |||
1935 | /** |
||
1936 | * Unique caching key for the product list... |
||
1937 | * |
||
1938 | * @return string | Null |
||
1939 | */ |
||
1940 | public function ProductGroupListCachingKey() |
||
1941 | { |
||
1942 | if ($this->ProductGroupListAreCacheable()) { |
||
1943 | $displayKey = $this->getCurrentUserPreferences('DISPLAY'); |
||
1944 | $filterKey = $this->getCurrentUserPreferences('FILTER'); |
||
1945 | $filterForGroupKey = $this->filterForGroupObject ? $this->filterForGroupObject->ID : 0; |
||
1946 | $sortKey = $this->getCurrentUserPreferences('SORT'); |
||
1947 | $pageStart = $this->request->getVar('start') ? intval($this->request->getVar('start')) : 0; |
||
1948 | $isFullList = $this->IsShowFullList() ? 'Y' : 'N'; |
||
1949 | |||
1950 | $this->cacheKey( |
||
1951 | implode( |
||
1952 | '_', |
||
1953 | array( |
||
1954 | $displayKey, |
||
1955 | $filterKey, |
||
1956 | $filterForGroupKey, |
||
1957 | $sortKey, |
||
1958 | $pageStart, |
||
1959 | $isFullList, |
||
1960 | ) |
||
1961 | ) |
||
1962 | ); |
||
1963 | } |
||
1964 | |||
1965 | return; |
||
1966 | } |
||
1967 | |||
1968 | /** |
||
1969 | * adds Javascript to the page to make it work when products are cached. |
||
1970 | */ |
||
1971 | public function CachingRelatedJavascript() |
||
1972 | { |
||
1973 | if ($this->ProductGroupListAreAjaxified()) { |
||
1974 | Requirements::customScript(" |
||
1975 | if(typeof EcomCartOptions === 'undefined') { |
||
1976 | var EcomCartOptions = {}; |
||
1977 | } |
||
1978 | EcomCartOptions.ajaxifyProductList = true; |
||
1979 | EcomCartOptions.ajaxifiedListHolderSelector = '#".$this->AjaxDefinitions()->ProductListHolderID()."'; |
||
1980 | EcomCartOptions.ajaxifiedListAdjusterSelectors = '.".$this->AjaxDefinitions()->ProductListAjaxifiedLinkClassName()."'; |
||
1981 | EcomCartOptions.hiddenPageTitleID = '#".$this->AjaxDefinitions()->HiddenPageTitleID()."'; |
||
1982 | ", |
||
1983 | 'cachingRelatedJavascript_AJAXlist' |
||
1984 | ); |
||
1985 | } else { |
||
1986 | Requirements::customScript(" |
||
1987 | if(typeof EcomCartOptions === 'undefined') { |
||
1988 | var EcomCartOptions = {}; |
||
1989 | } |
||
1990 | EcomCartOptions.ajaxifyProductList = false; |
||
1991 | ", |
||
1992 | 'cachingRelatedJavascript_AJAXlist' |
||
1993 | ); |
||
1994 | } |
||
1995 | $currentOrder = ShoppingCart::current_order(); |
||
1996 | if ($currentOrder->TotalItems(true)) { |
||
1997 | $responseClass = EcommerceConfig::get('ShoppingCart', 'response_class'); |
||
1998 | $obj = new $responseClass(); |
||
1999 | $obj->setIncludeHeaders(false); |
||
2000 | $json = $obj->ReturnCartData(); |
||
2001 | Requirements::customScript(" |
||
2002 | if(typeof EcomCartOptions === 'undefined') { |
||
2003 | var EcomCartOptions = {}; |
||
2004 | } |
||
2005 | EcomCartOptions.initialData= ".$json."; |
||
2006 | ", |
||
2007 | 'cachingRelatedJavascript_JSON' |
||
2008 | ); |
||
2009 | } |
||
2010 | } |
||
2011 | |||
2012 | /** |
||
2013 | * you can overload this function of ProductGroup Extensions. |
||
2014 | * |
||
2015 | * @return bool |
||
2016 | */ |
||
2017 | protected function productListsHTMLCanBeCached() |
||
2018 | { |
||
2019 | return Config::inst()->get('ProductGroup', 'actively_check_for_can_purchase') ? false : true; |
||
2020 | } |
||
2021 | |||
2022 | /***************************************************** |
||
2023 | * DATALIST: totals, number per page, etc.. |
||
2024 | *****************************************************/ |
||
2025 | |||
2026 | /** |
||
2027 | * returns the total numer of products (before pagination). |
||
2028 | * |
||
2029 | * @return bool |
||
2030 | **/ |
||
2031 | public function TotalCountGreaterThanOne($greaterThan = 1) |
||
2032 | { |
||
2033 | return $this->TotalCount() > $greaterThan; |
||
2034 | } |
||
2035 | |||
2036 | /** |
||
2037 | * have the ProductsShowable been limited. |
||
2038 | * |
||
2039 | * @return bool |
||
2040 | **/ |
||
2041 | public function TotalCountGreaterThanMax() |
||
2042 | { |
||
2043 | return $this->RawCount() > $this->TotalCount(); |
||
2044 | } |
||
2045 | |||
2046 | /**************************************************** |
||
2047 | * TEMPLATE METHODS MENUS AND SIDEBARS |
||
2048 | /****************************************************/ |
||
2049 | |||
2050 | /** |
||
2051 | * title without additions. |
||
2052 | * |
||
2053 | * @return string |
||
2054 | */ |
||
2055 | public function OriginalTitle() |
||
2056 | { |
||
2057 | return $this->originalTitle; |
||
2058 | } |
||
2059 | /** |
||
2060 | * This method can be extended to show products in the side bar. |
||
2061 | */ |
||
2062 | public function SidebarProducts() |
||
2063 | { |
||
2064 | return; |
||
2065 | } |
||
2066 | |||
2067 | /** |
||
2068 | * returns child product groups for use in |
||
2069 | * 'in this section'. For example the vegetable Product Group |
||
2070 | * May have listed here: Carrot, Cabbage, etc... |
||
2071 | * |
||
2072 | * @return ArrayList (ProductGroups) |
||
2073 | */ |
||
2074 | public function MenuChildGroups() |
||
2075 | { |
||
2076 | return $this->ChildGroups(2, '"ShowInMenus" = 1'); |
||
2077 | } |
||
2078 | |||
2079 | /** |
||
2080 | * After a search is conducted you may end up with a bunch |
||
2081 | * of recommended product groups. They will be returned here... |
||
2082 | * We sort the list in the order that it is provided. |
||
2083 | * |
||
2084 | * @return DataList | Null (ProductGroups) |
||
2085 | */ |
||
2086 | public function SearchResultsChildGroups() |
||
2087 | { |
||
2088 | $groupArray = explode(',', Session::get($this->SearchResultsSessionVariable($isForGroup = true))); |
||
2089 | if (is_array($groupArray) && count($groupArray)) { |
||
2090 | $sortStatement = $this->createSortStatementFromIDArray($groupArray, 'ProductGroup'); |
||
2091 | |||
2092 | return ProductGroup::get()->filter(array('ID' => $groupArray, 'ShowInSearch' => 1))->sort($sortStatement); |
||
2093 | } |
||
2094 | |||
2095 | return; |
||
2096 | } |
||
2097 | |||
2098 | /**************************************************** |
||
2099 | * Search Form Related controllers |
||
2100 | /****************************************************/ |
||
2101 | |||
2102 | /** |
||
2103 | * returns a search form to search current products. |
||
2104 | * |
||
2105 | * @return ProductSearchForm object |
||
2106 | */ |
||
2107 | public function ProductSearchForm() |
||
2108 | { |
||
2109 | $onlySearchTitle = $this->originalTitle; |
||
2110 | if ($this->dataRecord instanceof ProductGroupSearchPage) { |
||
2111 | if ($this->HasSearchResults()) { |
||
2112 | $onlySearchTitle = 'Last Search Results'; |
||
2113 | } |
||
2114 | } |
||
2115 | $form = ProductSearchForm::create( |
||
2116 | $this, |
||
2117 | 'ProductSearchForm', |
||
2118 | $onlySearchTitle, |
||
2119 | $this->currentInitialProducts(null, $this->getMyUserPreferencesDefault('FILTER')) |
||
2120 | ); |
||
2121 | $filterGetVariable = $this->getSortFilterDisplayNames('FILTER', 'getVariable'); |
||
2122 | $sortGetVariable = $this->getSortFilterDisplayNames('SORT', 'getVariable'); |
||
2123 | $additionalGetParameters = $filterGetVariable.'='.$this->getMyUserPreferencesDefault('FILTER').'&'. |
||
2124 | $sortGetVariable.'='.$this->getMyUserPreferencesDefault('SORT'); |
||
2125 | $form->setAdditionalGetParameters($additionalGetParameters); |
||
2126 | |||
2127 | return $form; |
||
2128 | } |
||
2129 | |||
2130 | /** |
||
2131 | * Does this page have any search results? |
||
2132 | * If search was carried out without returns |
||
2133 | * then it returns zero (false). |
||
2134 | * |
||
2135 | * @return int | false |
||
2136 | */ |
||
2137 | public function HasSearchResults() |
||
2138 | { |
||
2139 | $resultArray = $this->searchResultsArrayFromSession(); |
||
2140 | if ($resultArray) { |
||
2141 | $count = count($resultArray) - 1; |
||
2142 | |||
2143 | return $count ? $count : 0; |
||
2144 | } |
||
2145 | |||
2146 | return 0; |
||
2147 | } |
||
2148 | |||
2149 | /** |
||
2150 | * Should the product search form be shown immediately? |
||
2151 | * |
||
2152 | * @return bool |
||
2153 | */ |
||
2154 | public function ShowSearchFormImmediately() |
||
2155 | { |
||
2156 | if ($this->IsSearchResults()) { |
||
2157 | return true; |
||
2158 | } |
||
2159 | if ((!$this->products) || ($this->products && $this->products->count())) { |
||
2160 | return false; |
||
2161 | } |
||
2162 | |||
2163 | return true; |
||
2164 | } |
||
2165 | |||
2166 | /** |
||
2167 | * Show a search form on this page? |
||
2168 | * |
||
2169 | * @return bool |
||
2170 | */ |
||
2171 | public function ShowSearchFormAtAll() |
||
2172 | { |
||
2173 | return true; |
||
2174 | } |
||
2175 | |||
2176 | /** |
||
2177 | * Is the current page a display of search results. |
||
2178 | * |
||
2179 | * This does not mean that something is actively being search for, |
||
2180 | * it could also be just "showing the search results" |
||
2181 | * |
||
2182 | * @return bool |
||
2183 | */ |
||
2184 | public function IsSearchResults() |
||
2185 | { |
||
2186 | return $this->isSearchResults; |
||
2187 | } |
||
2188 | |||
2189 | /** |
||
2190 | * Is there something actively being searched for? |
||
2191 | * |
||
2192 | * This is different from IsSearchResults. |
||
2193 | * |
||
2194 | * @return bool |
||
2195 | */ |
||
2196 | public function ActiveSearchTerm() |
||
2197 | { |
||
2198 | $data = Session::get(Config::inst()->get('ProductSearchForm', 'form_data_session_variable')); |
||
2199 | if (!empty($data['Keyword'])) { |
||
2200 | return $this->IsSearchResults(); |
||
2201 | } |
||
2202 | } |
||
2203 | |||
2204 | /**************************************************** |
||
2205 | * Filter / Sort / Display related controllers |
||
2206 | /****************************************************/ |
||
2207 | |||
2208 | /** |
||
2209 | * Do we show all products on one page? |
||
2210 | * |
||
2211 | * @return bool |
||
2212 | */ |
||
2213 | public function ShowFiltersAndDisplayLinks() |
||
2214 | { |
||
2215 | if ($this->TotalCountGreaterThanOne()) { |
||
2216 | if ($this->HasFilters()) { |
||
2217 | return true; |
||
2218 | } |
||
2219 | if ($this->DisplayLinks()) { |
||
2220 | return true; |
||
2221 | } |
||
2222 | } |
||
2223 | |||
2224 | return false; |
||
2225 | } |
||
2226 | |||
2227 | /** |
||
2228 | * Do we show the sort links. |
||
2229 | * |
||
2230 | * A bit arbitrary to say three, |
||
2231 | * but there is not much point to sort three or less products |
||
2232 | * |
||
2233 | * @return bool |
||
2234 | */ |
||
2235 | public function ShowSortLinks($minimumCount = 3) |
||
2236 | { |
||
2237 | if ($this->TotalCountGreaterThanOne($minimumCount)) { |
||
2238 | return true; |
||
2239 | } |
||
2240 | |||
2241 | return false; |
||
2242 | } |
||
2243 | |||
2244 | /** |
||
2245 | * Is there a special filter operating at the moment? |
||
2246 | * Is the current filter the default one (return inverse!)? |
||
2247 | * |
||
2248 | * @return bool |
||
2249 | */ |
||
2250 | public function HasFilter() |
||
2251 | { |
||
2252 | return $this->getCurrentUserPreferences('FILTER') != $this->getMyUserPreferencesDefault('FILTER') |
||
2253 | || $this->filterForGroupObject; |
||
2254 | } |
||
2255 | |||
2256 | /** |
||
2257 | * Is there a special sort operating at the moment? |
||
2258 | * Is the current sort the default one (return inverse!)? |
||
2259 | * |
||
2260 | * @return bool |
||
2261 | */ |
||
2262 | public function HasSort() |
||
2263 | { |
||
2264 | $sort = $this->getCurrentUserPreferences('SORT'); |
||
2265 | if ($sort != $this->getMyUserPreferencesDefault('SORT')) { |
||
2266 | return true; |
||
2267 | } |
||
2268 | } |
||
2269 | |||
2270 | /** |
||
2271 | * @return boolean |
||
2272 | */ |
||
2273 | public function HasFilterOrSort() |
||
2274 | { |
||
2275 | return $this->HasFilter() || $this->HasSort(); |
||
2276 | } |
||
2277 | |||
2278 | /** |
||
2279 | * @return boolean |
||
2280 | */ |
||
2281 | public function HasFilterOrSortFullList() |
||
2282 | { |
||
2283 | return $this->HasFilterOrSort() || $this->IsShowFullList(); |
||
2284 | } |
||
2285 | |||
2286 | /** |
||
2287 | * are filters available? |
||
2288 | * we check one at the time so that we do the least |
||
2289 | * amount of DB queries. |
||
2290 | * |
||
2291 | * @return bool |
||
2292 | */ |
||
2293 | public function HasFilters() |
||
2294 | { |
||
2295 | $countFilters = $this->FilterLinks()->count(); |
||
2296 | if ($countFilters > 1) { |
||
2297 | return true; |
||
2298 | } |
||
2299 | $countGroupFilters = $this->ProductGroupFilterLinks()->count(); |
||
2300 | if ($countGroupFilters > 1) { |
||
2301 | return true; |
||
2302 | } |
||
2303 | if ($countFilters + $countGroupFilters > 1) { |
||
2304 | return true; |
||
2305 | } |
||
2306 | |||
2307 | return false; |
||
2308 | } |
||
2309 | |||
2310 | /** |
||
2311 | * Do we show all products on one page? |
||
2312 | * |
||
2313 | * @return bool |
||
2314 | */ |
||
2315 | public function IsShowFullList() |
||
2316 | { |
||
2317 | return $this->showFullList; |
||
2318 | } |
||
2319 | |||
2320 | /** |
||
2321 | * returns the current filter applied to the list |
||
2322 | * in a human readable string. |
||
2323 | * |
||
2324 | * @return string |
||
2325 | */ |
||
2326 | public function CurrentDisplayTitle() |
||
2327 | { |
||
2328 | $displayKey = $this->getCurrentUserPreferences('DISPLAY'); |
||
2329 | if ($displayKey != $this->getMyUserPreferencesDefault('DISPLAY')) { |
||
2330 | return $this->getUserPreferencesTitle('DISPLAY', $displayKey); |
||
2331 | } |
||
2332 | } |
||
2333 | |||
2334 | /** |
||
2335 | * returns the current filter applied to the list |
||
2336 | * in a human readable string. |
||
2337 | * |
||
2338 | * @return string |
||
2339 | */ |
||
2340 | public function CurrentFilterTitle() |
||
2341 | { |
||
2342 | $filterKey = $this->getCurrentUserPreferences('FILTER'); |
||
2343 | $filters = array(); |
||
2344 | if ($filterKey != $this->getMyUserPreferencesDefault('FILTER')) { |
||
2345 | $filters[] = $this->getUserPreferencesTitle('FILTER', $filterKey); |
||
2346 | } |
||
2347 | if ($this->filterForGroupObject) { |
||
2348 | $filters[] = $this->filterForGroupObject->MenuTitle; |
||
2349 | } |
||
2350 | if (count($filters)) { |
||
2351 | return implode(', ', $filters); |
||
2352 | } |
||
2353 | } |
||
2354 | |||
2355 | /** |
||
2356 | * returns the current sort applied to the list |
||
2357 | * in a human readable string. |
||
2358 | * |
||
2359 | * @return string |
||
2360 | */ |
||
2361 | public function CurrentSortTitle() |
||
2362 | { |
||
2363 | $sortKey = $this->getCurrentUserPreferences('SORT'); |
||
2364 | if ($sortKey != $this->getMyUserPreferencesDefault('SORT')) { |
||
2365 | return $this->getUserPreferencesTitle('SORT', $sortKey); |
||
2366 | } |
||
2367 | } |
||
2368 | |||
2369 | /** |
||
2370 | * short-cut for getMyUserPreferencesDefault("DISPLAY") |
||
2371 | * for use in templtes. |
||
2372 | * |
||
2373 | * @return string - key |
||
2374 | */ |
||
2375 | public function MyDefaultDisplayStyle() |
||
2376 | { |
||
2377 | return $this->getMyUserPreferencesDefault('DISPLAY'); |
||
2378 | } |
||
2379 | |||
2380 | /** |
||
2381 | * Number of entries per page limited by total number of pages available... |
||
2382 | * |
||
2383 | * @return int |
||
2384 | */ |
||
2385 | public function MaxNumberOfProductsPerPage() |
||
2386 | { |
||
2387 | return $this->MyNumberOfProductsPerPage() > $this->TotalCount() ? $this->TotalCount() : $this->MyNumberOfProductsPerPage(); |
||
2388 | } |
||
2389 | |||
2390 | /**************************************************** |
||
2391 | * TEMPLATE METHODS FILTER LINK |
||
2392 | /****************************************************/ |
||
2393 | |||
2394 | /** |
||
2395 | * Provides a ArrayList of links for filters products. |
||
2396 | * |
||
2397 | * @return ArrayList( ArrayData(Name, Link, SelectKey, Current (boolean), LinkingMode)) |
||
2398 | */ |
||
2399 | public function FilterLinks() |
||
2400 | { |
||
2401 | $cacheKey = 'FilterLinks_'.($this->filterForGroupObject ? $this->filterForGroupObject->ID : 0); |
||
2402 | if ($list = $this->retrieveObjectStore($cacheKey)) { |
||
2403 | //do nothing |
||
2404 | } else { |
||
2405 | $list = $this->userPreferencesLinks('FILTER'); |
||
2406 | foreach ($list as $obj) { |
||
2407 | $key = $obj->SelectKey; |
||
2408 | if ($key != $this->getMyUserPreferencesDefault('FILTER')) { |
||
2409 | $count = count($this->currentInitialProductsAsCachedArray($key)); |
||
2410 | if ($count == 0) { |
||
2411 | $list->remove($obj); |
||
2412 | } else { |
||
2413 | $obj->Count = $count; |
||
2414 | } |
||
2415 | } |
||
2416 | } |
||
2417 | $this->saveObjectStore($list, $cacheKey); |
||
2418 | } |
||
2419 | $selectedItem = $this->getCurrentUserPreferences('FILTER'); |
||
2420 | foreach ($list as $obj) { |
||
2421 | $canHaveCurrent = true; |
||
2422 | if ($this->filterForGroupObject) { |
||
2423 | $canHaveCurrent = false; |
||
2424 | } |
||
2425 | $obj->Current = $selectedItem == $obj->SelectKey && $canHaveCurrent ? true : false; |
||
2426 | $obj->LinkingMode = $obj->Current ? 'current' : 'link'; |
||
2427 | $obj->Ajaxify = true; |
||
2428 | } |
||
2429 | |||
2430 | return $list; |
||
2431 | } |
||
2432 | |||
2433 | /** |
||
2434 | * returns a list of items (with links). |
||
2435 | * |
||
2436 | * @return ArrayList( ArrayData(Name, FilterLink, SelectKey, Current (boolean), LinkingMode)) |
||
2437 | */ |
||
2438 | public function ProductGroupFilterLinks() |
||
2439 | { |
||
2440 | if ($array = $this->retrieveObjectStore('ProductGroupFilterLinks')) { |
||
2441 | //do nothing |
||
2442 | } else { |
||
2443 | $arrayOfItems = array(); |
||
2444 | |||
2445 | $baseArray = $this->currentInitialProductsAsCachedArray($this->getMyUserPreferencesDefault('FILTER')); |
||
2446 | |||
2447 | //also show |
||
2448 | $items = $this->ProductGroupsFromAlsoShowProducts(); |
||
2449 | $arrayOfItems = array_merge($arrayOfItems, $this->productGroupFilterLinksCount($items, $baseArray, true)); |
||
2450 | //also show inverse |
||
2451 | $items = $this->ProductGroupsFromAlsoShowProductsInverse(); |
||
2452 | $arrayOfItems = array_merge($arrayOfItems, $this->productGroupFilterLinksCount($items, $baseArray, true)); |
||
2453 | |||
2454 | //parent groups |
||
2455 | $items = $this->ProductGroupsParentGroups(); |
||
2456 | $arrayOfItems = array_merge($arrayOfItems, $this->productGroupFilterLinksCount($items, $baseArray, true)); |
||
2457 | |||
2458 | //child groups |
||
2459 | $items = $this->MenuChildGroups(); |
||
2460 | $arrayOfItems = array_merge($arrayOfItems, $this->productGroupFilterLinksCount($items, $baseArray, true)); |
||
2461 | |||
2462 | ksort($arrayOfItems); |
||
2463 | $array = array(); |
||
2464 | foreach ($arrayOfItems as $arrayOfItem) { |
||
2465 | $array[] = $this->makeArrayItem($arrayOfItem); |
||
2466 | } |
||
2467 | $this->saveObjectStore($array, 'ProductGroupFilterLinks'); |
||
2468 | } |
||
2469 | $arrayList = ArrayList::create(); |
||
2470 | foreach ($array as $item) { |
||
2471 | $arrayList->push(ArrayData::create($item)); |
||
2472 | } |
||
2473 | return $arrayList; |
||
2474 | } |
||
2475 | |||
2476 | /** |
||
2477 | * counts the total number in the combination.... |
||
2478 | * |
||
2479 | * @param DataList $items - list of |
||
2480 | * @param Arary $baseArray - list of products on the current page |
||
2481 | * |
||
2482 | * @return array |
||
2483 | */ |
||
2484 | protected function productGroupFilterLinksCount($items, $baseArray, $ajaxify = true) |
||
2485 | { |
||
2486 | $array = array(); |
||
2487 | if ($items && $items->count()) { |
||
2488 | foreach ($items as $item) { |
||
2489 | $arrayOfIDs = $item->currentInitialProductsAsCachedArray($this->getMyUserPreferencesDefault('FILTER')); |
||
2490 | $newArray = array_intersect_key( |
||
2491 | $arrayOfIDs, |
||
2492 | $baseArray |
||
2493 | ); |
||
2494 | $count = count($newArray); |
||
2495 | if ($count) { |
||
2496 | $array[$item->Title] = array( |
||
2497 | 'Item' => $item, |
||
2498 | 'Count' => $count, |
||
2499 | 'Ajaxify' => $ajaxify, |
||
2500 | ); |
||
2501 | } |
||
2502 | } |
||
2503 | } |
||
2504 | |||
2505 | return $array; |
||
2506 | } |
||
2507 | |||
2508 | /** |
||
2509 | * @param array itemInArray (Item, Count, UserFilterAction) |
||
2510 | * |
||
2511 | * @return ArrayData |
||
2512 | */ |
||
2513 | protected function makeArrayItem($itemInArray) |
||
2514 | { |
||
2515 | $item = $itemInArray['Item']; |
||
2516 | $count = $itemInArray['Count']; |
||
2517 | $ajaxify = $itemInArray['Ajaxify']; |
||
2518 | $filterForGroupObjectID = $this->filterForGroupObject ? $this->filterForGroupObject->ID : 0; |
||
2519 | $isCurrent = $item->ID == $filterForGroupObjectID; |
||
2520 | if ($ajaxify) { |
||
2521 | $link = $this->Link('filterforgroup/'.$item->URLSegment); |
||
2522 | } else { |
||
2523 | $link = $item->Link(); |
||
2524 | } |
||
2525 | return array( |
||
2526 | 'Title' => $item->Title, |
||
2527 | 'Count' => $count, |
||
2528 | 'SelectKey' => $item->URLSegment, |
||
2529 | 'Current' => $isCurrent ? true : false, |
||
2530 | 'MyLinkingMode' => $isCurrent ? 'current' : 'link', |
||
2531 | 'FilterLink' => $link, |
||
2532 | 'Ajaxify' => $ajaxify ? true : false, |
||
2533 | ); |
||
2534 | } |
||
2535 | |||
2536 | /** |
||
2537 | * Provides a ArrayList of links for sorting products. |
||
2538 | */ |
||
2539 | public function SortLinks() |
||
2540 | { |
||
2541 | $list = $this->userPreferencesLinks('SORT'); |
||
2542 | $selectedItem = $this->getCurrentUserPreferences('SORT'); |
||
2543 | if ($list) { |
||
2544 | foreach ($list as $obj) { |
||
2545 | $obj->Current = $selectedItem == $obj->SelectKey ? true : false; |
||
2546 | $obj->LinkingMode = $obj->Current ? 'current' : 'link'; |
||
2547 | $obj->Ajaxify = true; |
||
2548 | } |
||
2549 | |||
2550 | return $list; |
||
2551 | } |
||
2552 | } |
||
2553 | |||
2554 | /** |
||
2555 | * Provides a ArrayList for displaying display links. |
||
2556 | */ |
||
2557 | public function DisplayLinks() |
||
2558 | { |
||
2559 | $list = $this->userPreferencesLinks('DISPLAY'); |
||
2560 | $selectedItem = $this->getCurrentUserPreferences('DISPLAY'); |
||
2561 | if ($list) { |
||
2562 | foreach ($list as $obj) { |
||
2563 | $obj->Current = $selectedItem == $obj->SelectKey ? true : false; |
||
2564 | $obj->LinkingMode = $obj->Current ? 'current' : 'link'; |
||
2565 | $obj->Ajaxify = true; |
||
2566 | } |
||
2567 | |||
2568 | return $list; |
||
2569 | } |
||
2570 | } |
||
2571 | |||
2572 | /** |
||
2573 | * The link that Google et al. need to index. |
||
2574 | * @return string |
||
2575 | */ |
||
2576 | public function CanonicalLink() |
||
2577 | { |
||
2578 | $link = $this->ListAllLink(); |
||
2579 | $this->extend('UpdateCanonicalLink', $link); |
||
2580 | |||
2581 | return $link; |
||
2582 | } |
||
2583 | |||
2584 | |||
2585 | /** |
||
2586 | * Link that returns a list of all the products |
||
2587 | * for this product group as a simple list. |
||
2588 | * |
||
2589 | * @return string |
||
2590 | */ |
||
2591 | public function ListAllLink() |
||
2592 | { |
||
2593 | if ($this->filterForGroupObject) { |
||
2594 | return $this->Link('filterforgroup/'.$this->filterForGroupObject->URLSegment).'?showfulllist=1'; |
||
2595 | } else { |
||
2596 | return $this->Link().'?showfulllist=1'; |
||
2597 | } |
||
2598 | } |
||
2599 | |||
2600 | /** |
||
2601 | * Link that returns a list of all the products |
||
2602 | * for this product group as a simple list. |
||
2603 | * |
||
2604 | * @return string |
||
2605 | */ |
||
2606 | public function ListAFewLink() |
||
2607 | { |
||
2608 | return str_replace('?showfulllist=1', '', $this->ListAllLink()); |
||
2609 | } |
||
2610 | |||
2611 | /** |
||
2612 | * Link that returns a list of all the products |
||
2613 | * for this product group as a simple list. |
||
2614 | * |
||
2615 | * It resets everything - not just filter.... |
||
2616 | * |
||
2617 | * @return string |
||
2618 | */ |
||
2619 | public function ResetPreferencesLink($escapedAmpersands = true) |
||
2620 | { |
||
2621 | $ampersand = '&'; |
||
2622 | if ($escapedAmpersands) { |
||
2623 | $ampersand = '&'; |
||
2624 | } |
||
2625 | $getVariableNameFilter = $this->getSortFilterDisplayNames('FILTER', 'getVariable'); |
||
2626 | $getVariableNameSort = $this->getSortFilterDisplayNames('SORT', 'getVariable'); |
||
2627 | |||
2628 | return $this->Link().'?'. |
||
2629 | $getVariableNameFilter.'='.$this->getMyUserPreferencesDefault('FILTER').$ampersand. |
||
2630 | $getVariableNameSort.'='.$this->getMyUserPreferencesDefault('SORT').$ampersand. |
||
2631 | 'reload=1'; |
||
2632 | } |
||
2633 | |||
2634 | /** |
||
2635 | * Link to the search results. |
||
2636 | * |
||
2637 | * @return string |
||
2638 | */ |
||
2639 | public function SearchResultLink() |
||
2640 | { |
||
2641 | if ($this->HasSearchResults() && !$this->isSearchResults) { |
||
2642 | return $this->Link('searchresults'); |
||
2643 | } |
||
2644 | } |
||
2645 | |||
2646 | /**************************************************** |
||
2647 | * INTERNAL PROCESSING: PRODUCT LIST |
||
2648 | /****************************************************/ |
||
2649 | |||
2650 | /** |
||
2651 | * turns full list into paginated list. |
||
2652 | * |
||
2653 | * @param SS_List |
||
2654 | * |
||
2655 | * @return PaginatedList |
||
2656 | */ |
||
2657 | protected function paginateList(SS_List $list) |
||
2658 | { |
||
2659 | if ($list && $list->count()) { |
||
2660 | if ($this->IsShowFullList()) { |
||
2661 | $obj = PaginatedList::create($list, $this->request); |
||
2662 | $obj->setPageLength(EcommerceConfig::get('ProductGroup', 'maximum_number_of_products_to_list') + 1); |
||
2663 | |||
2664 | return $obj; |
||
2665 | } else { |
||
2666 | $obj = PaginatedList::create($list, $this->request); |
||
2667 | $obj->setPageLength($this->MyNumberOfProductsPerPage()); |
||
2668 | |||
2669 | return $obj; |
||
2670 | } |
||
2671 | } |
||
2672 | } |
||
2673 | |||
2674 | /**************************************************** |
||
2675 | * INTERNAL PROCESSING: USER PREFERENCES |
||
2676 | /****************************************************/ |
||
2677 | |||
2678 | /** |
||
2679 | * Checks out a bunch of $_GET variables |
||
2680 | * that are used to work out user preferences |
||
2681 | * Some of these are saved to session. |
||
2682 | * |
||
2683 | * @param array $overrideArray - override $_GET variable settings |
||
2684 | */ |
||
2685 | protected function saveUserPreferences($overrideArray = array()) |
||
2686 | { |
||
2687 | |||
2688 | //save sort - filter - display |
||
2689 | $sortFilterDisplayNames = $this->getSortFilterDisplayNames(); |
||
2690 | foreach ($sortFilterDisplayNames as $type => $oneTypeArray) { |
||
2691 | $getVariableName = $oneTypeArray['getVariable']; |
||
2692 | $sessionName = $oneTypeArray['sessionName']; |
||
2693 | if (isset($overrideArray[$getVariableName])) { |
||
2694 | $newPreference = $overrideArray[$getVariableName]; |
||
2695 | } else { |
||
2696 | $newPreference = $this->request->getVar($getVariableName); |
||
2697 | } |
||
2698 | if ($newPreference) { |
||
2699 | $optionsVariableName = $oneTypeArray['configName']; |
||
2700 | $options = EcommerceConfig::get($this->ClassName, $optionsVariableName); |
||
2701 | if (isset($options[$newPreference])) { |
||
2702 | Session::set('ProductGroup_'.$sessionName, $newPreference); |
||
2703 | //save in model as well... |
||
2704 | } |
||
2705 | } else { |
||
2706 | $newPreference = Session::get('ProductGroup_'.$sessionName); |
||
2707 | } |
||
2708 | //save data in model... |
||
2709 | $this->setCurrentUserPreference($type, $newPreference); |
||
2710 | } |
||
2711 | /* save URLSegments in model |
||
2712 | $this->setCurrentUserPreference( |
||
2713 | "URLSegments", |
||
2714 | array( |
||
2715 | "Action" => $this->request->param("Action"), |
||
2716 | "ID" => $this->request->param("ID") |
||
2717 | ) |
||
2718 | ); |
||
2719 | */ |
||
2720 | |||
2721 | //clearing data.. |
||
2722 | if ($this->request->getVar('reload')) { |
||
2723 | //reset other session variables... |
||
2724 | Session::set($this->SearchResultsSessionVariable(false), ''); |
||
2725 | Session::set($this->SearchResultsSessionVariable(true), ''); |
||
2726 | |||
2727 | return $this->redirect($this->Link()); |
||
2728 | } |
||
2729 | |||
2730 | //full list .... |
||
2731 | if ($this->request->getVar('showfulllist')) { |
||
2732 | $this->showFullList = true; |
||
2733 | } |
||
2734 | } |
||
2735 | |||
2736 | /** |
||
2737 | * Checks for the most applicable user preferences for this user: |
||
2738 | * 1. session value |
||
2739 | * 2. getMyUserPreferencesDefault. |
||
2740 | * |
||
2741 | * @param string $type - FILTER | SORT | DISPLAY |
||
2742 | * |
||
2743 | * @return string |
||
2744 | * |
||
2745 | * @todo: move to controller? |
||
2746 | */ |
||
2747 | protected function getCurrentUserPreferences($type) |
||
2748 | { |
||
2749 | $sessionName = $this->getSortFilterDisplayNames($type, 'sessionName'); |
||
2750 | if ($sessionValue = Session::get('ProductGroup_'.$sessionName)) { |
||
2751 | $key = Convert::raw2sql($sessionValue); |
||
2752 | } else { |
||
2753 | $key = $this->getMyUserPreferencesDefault($type); |
||
2754 | } |
||
2755 | |||
2756 | return $key; |
||
2757 | } |
||
2758 | |||
2759 | /** |
||
2760 | * Provides a dataset of links for a particular user preference. |
||
2761 | * |
||
2762 | * @param string $type SORT | FILTER | DISPLAY - e.g. sort_options |
||
2763 | * |
||
2764 | * @return ArrayList( ArrayData(Name, Link, SelectKey, Current (boolean), LinkingMode)) |
||
2765 | */ |
||
2766 | protected function userPreferencesLinks($type) |
||
2767 | { |
||
2768 | //get basics |
||
2769 | $sortFilterDisplayNames = $this->getSortFilterDisplayNames(); |
||
2770 | $options = $this->getConfigOptions($type); |
||
2771 | |||
2772 | //if there is only one option then do not bother |
||
2773 | if (count($options) < 2) { |
||
2774 | return; |
||
2775 | } |
||
2776 | |||
2777 | //get more config names |
||
2778 | $translationCode = $sortFilterDisplayNames[$type]['translationCode']; |
||
2779 | $getVariableName = $sortFilterDisplayNames[$type]['getVariable']; |
||
2780 | $arrayList = ArrayList::create(); |
||
2781 | if (count($options)) { |
||
2782 | foreach ($options as $key => $array) { |
||
2783 | //$isCurrent = ($key == $selectedItem) ? true : false; |
||
2784 | |||
2785 | $link = '?'.$getVariableName."=$key"; |
||
2786 | if ($type == 'FILTER') { |
||
2787 | $link = $this->Link().$link; |
||
2788 | } else { |
||
2789 | $link = $this->request->getVar('url').$link; |
||
2790 | } |
||
2791 | $arrayList->push(ArrayData::create(array( |
||
2792 | 'Name' => _t('ProductGroup.'.$translationCode.strtoupper(str_replace(' ', '', $array['Title'])), $array['Title']), |
||
2793 | 'Link' => $link, |
||
2794 | 'SelectKey' => $key, |
||
2795 | //we add current at runtime, so we can store the object without current set... |
||
2796 | //'Current' => $isCurrent, |
||
2797 | //'LinkingMode' => $isCurrent ? "current" : "link" |
||
2798 | ))); |
||
2799 | } |
||
2800 | } |
||
2801 | |||
2802 | return $arrayList; |
||
2803 | } |
||
2804 | |||
2805 | /**************************************************** |
||
2806 | * INTERNAL PROCESSING: TITLES |
||
2807 | /****************************************************/ |
||
2808 | |||
2809 | /** |
||
2810 | * variable to make sure secondary title only gets |
||
2811 | * added once. |
||
2812 | * |
||
2813 | * @var bool |
||
2814 | */ |
||
2815 | protected $secondaryTitleHasBeenAdded = false; |
||
2816 | |||
2817 | /** |
||
2818 | * add a secondary title to the main title |
||
2819 | * in case there is, for example, a filter applied |
||
2820 | * e.g. Socks | MyBrand. |
||
2821 | * |
||
2822 | * @param string |
||
2823 | */ |
||
2824 | protected function addSecondaryTitle($secondaryTitle = '') |
||
2825 | { |
||
2826 | $pipe = _t('ProductGroup.TITLE_SEPARATOR', ' | '); |
||
2827 | if (! $this->secondaryTitleHasBeenAdded) { |
||
2828 | if (trim($secondaryTitle)) { |
||
2829 | $secondaryTitle = $pipe.$secondaryTitle; |
||
2830 | } |
||
2831 | if ($this->IsSearchResults()) { |
||
2832 | if ($array = $this->searchResultsArrayFromSession()) { |
||
2833 | //we remove 1 item here, because the array starts with 0 => 0 |
||
2834 | $count = count($array) - 1; |
||
2835 | if ($count > 3) { |
||
2836 | $toAdd = $count. ' '._t('ProductGroup.PRODUCTS_FOUND', 'Products Found'); |
||
2837 | $secondaryTitle .= $this->cleanSecondaryTitleForAddition($pipe, $toAdd); |
||
2838 | } |
||
2839 | } else { |
||
2840 | $toAdd = _t('ProductGroup.SEARCH_RESULTS', 'Search Results'); |
||
2841 | $secondaryTitle .= $this->cleanSecondaryTitleForAddition($pipe, $toAdd); |
||
2842 | } |
||
2843 | } |
||
2844 | if (is_object($this->filterForGroupObject)) { |
||
2845 | $toAdd = $this->filterForGroupObject->Title; |
||
2846 | $secondaryTitle .= $this->cleanSecondaryTitleForAddition($pipe, $toAdd); |
||
2847 | } |
||
2848 | $pagination = true; |
||
2849 | if ($this->IsShowFullList()) { |
||
2850 | $toAdd = _t('ProductGroup.LIST_VIEW', 'List View'); |
||
2851 | $secondaryTitle .= $this->cleanSecondaryTitleForAddition($pipe, $toAdd); |
||
2852 | $pagination = false; |
||
2853 | } |
||
2854 | $filter = $this->getCurrentUserPreferences('FILTER'); |
||
2855 | if ($filter != $this->getMyUserPreferencesDefault('FILTER')) { |
||
2856 | $toAdd = $this->getUserPreferencesTitle('FILTER', $this->getCurrentUserPreferences('FILTER')); |
||
2857 | $secondaryTitle .= $this->cleanSecondaryTitleForAddition($pipe, $toAdd); |
||
2858 | } |
||
2859 | if ($this->HasSort()) { |
||
2860 | $toAdd = $this->getUserPreferencesTitle('SORT', $this->getCurrentUserPreferences('SORT')); |
||
2861 | $secondaryTitle .= $this->cleanSecondaryTitleForAddition($pipe, $toAdd); |
||
2862 | } |
||
2863 | if ($secondaryTitle) { |
||
2864 | $this->Title .= $secondaryTitle; |
||
2865 | if (isset($this->MetaTitle)) { |
||
2866 | $this->MetaTitle .= $secondaryTitle; |
||
2867 | } |
||
2868 | } |
||
2869 | if($pagination) { |
||
2870 | if($pageStart = intval($this->request->getVar('start')) { |
||
2871 | if($pageStart > 0) { |
||
2872 | $from = $this->MyNumberOfProductsPerPage() * $pageStart; |
||
2873 | $to = $from + $this->MyNumberOfProductsPerPage(); |
||
2874 | if($to > $this->TotalCount()) { |
||
2875 | $to = $this->TotalCount(); |
||
2876 | } |
||
2877 | $toAdd .= _t('ProductGroup.PAGE', 'page') . ' '.$pageStart.' ('.$from ._t('ProductGroup.HYPHEN_SPACE', ' - ').$to.')'; |
||
2878 | $secondaryTitle .= $this->cleanSecondaryTitleForAddition($pipe, $toAdd); |
||
2879 | } |
||
2880 | } |
||
2881 | } |
||
2882 | //dont update menu title, because the entry in the menu |
||
2883 | //should stay the same as it links back to the unfiltered |
||
2884 | //page (in some cases). |
||
2885 | |||
2886 | $this->secondaryTitleHasBeenAdded = true; |
||
2887 | } |
||
2888 | } |
||
2889 | |||
2890 | /** |
||
2891 | * removes any spaces from the 'toAdd' bit and adds the pipe if there is |
||
2892 | * anything to add at all. Through the lang files, you can change the pipe |
||
2893 | * symbol to anything you like. |
||
2894 | * |
||
2895 | * @param string $pipe |
||
2896 | * @param string $toAdd |
||
2897 | * @return string |
||
2898 | */ |
||
2899 | protected function cleanSecondaryTitleForAddition($pipe, $toAdd) |
||
2900 | { |
||
2901 | $toAdd = trim($toAdd); |
||
2902 | $length = strlen($toAdd); |
||
2903 | if ($length > 0) { |
||
2904 | $toAdd = $pipe.$toAdd; |
||
2905 | } |
||
2906 | return $toAdd; |
||
2907 | } |
||
2908 | |||
2909 | /**************************************************** |
||
2910 | * DEBUG |
||
2911 | /****************************************************/ |
||
2912 | |||
2913 | public function debug() |
||
2914 | { |
||
2915 | $member = Member::currentUser(); |
||
2916 | if (!$member || !$member->IsShopAdmin()) { |
||
2917 | $messages = array( |
||
2918 | 'default' => 'You must login as an admin to use debug functions.', |
||
2919 | ); |
||
2920 | Security::permissionFailure($this, $messages); |
||
2921 | } |
||
2922 | $this->ProductsShowable(); |
||
2923 | $html = EcommerceTaskDebugCart::debug_object($this->dataRecord); |
||
2924 | $html .= '<ul>'; |
||
2925 | |||
2926 | $html .= '<li><hr /><h3>Available options</h3><hr /></li>'; |
||
2927 | $html .= '<li><b>Sort Options for Dropdown:</b><pre> '.print_r($this->getUserPreferencesOptionsForDropdown('SORT'), 1).'</pre> </li>'; |
||
2928 | $html .= '<li><b>Filter Options for Dropdown:</b><pre> '.print_r($this->getUserPreferencesOptionsForDropdown('FILTER'), 1).'</pre></li>'; |
||
2929 | $html .= '<li><b>Display Styles for Dropdown:</b><pre> '.print_r($this->getUserPreferencesOptionsForDropdown('DISPLAY'), 1).'</pre> </li>'; |
||
2930 | |||
2931 | $html .= '<li><hr /><h3>Selection Setting (what is set as default for this page)</h3><hr /></li>'; |
||
2932 | $html .= '<li><b>MyDefaultFilter:</b> '.$this->getMyUserPreferencesDefault('FILTER').' </li>'; |
||
2933 | $html .= '<li><b>MyDefaultSortOrder:</b> '.$this->getMyUserPreferencesDefault('SORT').' </li>'; |
||
2934 | $html .= '<li><b>MyDefaultDisplayStyle:</b> '.$this->getMyUserPreferencesDefault('DISPLAY').' </li>'; |
||
2935 | $html .= '<li><b>MyNumberOfProductsPerPage:</b> '.$this->MyNumberOfProductsPerPage().' </li>'; |
||
2936 | $html .= '<li><b>MyLevelOfProductsToshow:</b> '.$this->MyLevelOfProductsToShow().' = '.(isset($this->showProductLevels[$this->MyLevelOfProductsToShow()]) ? $this->showProductLevels[$this->MyLevelOfProductsToShow()] : 'ERROR!!!! $this->showProductLevels not set for '.$this->MyLevelOfProductsToShow()).' </li>'; |
||
2937 | |||
2938 | $html .= '<li><hr /><h3>Current Settings</h3><hr /></li>'; |
||
2939 | $html .= '<li><b>Current Sort Order:</b> '.$this->getCurrentUserPreferences('SORT').' </li>'; |
||
2940 | $html .= '<li><b>Current Filter:</b> '.$this->getCurrentUserPreferences('FILTER').' </li>'; |
||
2941 | $html .= '<li><b>Current display style:</b> '.$this->getCurrentUserPreferences('DISPLAY').' </li>'; |
||
2942 | |||
2943 | $html .= '<li><hr /><h3>DATALIST: totals, numbers per page etc</h3><hr /></li>'; |
||
2944 | $html .= '<li><b>Total number of products:</b> '.$this->TotalCount().' </li>'; |
||
2945 | $html .= '<li><b>Is there more than one product:</b> '.($this->TotalCountGreaterThanOne() ? 'YES' : 'NO').' </li>'; |
||
2946 | $html .= '<li><b>Number of products per page:</b> '.$this->MyNumberOfProductsPerPage().' </li>'; |
||
2947 | |||
2948 | $html .= '<li><hr /><h3>SQL Factors</h3><hr /></li>'; |
||
2949 | $html .= '<li><b>Default sort SQL:</b> '.print_r($this->getUserSettingsOptionSQL('SORT'), 1).' </li>'; |
||
2950 | $html .= '<li><b>User sort SQL:</b> '.print_r($this->getUserSettingsOptionSQL('SORT', $this->getCurrentUserPreferences('SORT')), 1).' </li>'; |
||
2951 | $html .= '<li><b>Default Filter SQL:</b> <pre>'.print_r($this->getUserSettingsOptionSQL('FILTER'), 1).'</pre> </li>'; |
||
2952 | $html .= '<li><b>User Filter SQL:</b> <pre>'.print_r($this->getUserSettingsOptionSQL('FILTER', $this->getCurrentUserPreferences('FILTER')), 1).'</pre> </li>'; |
||
2953 | $html .= '<li><b>Buyable Class name:</b> '.$this->getBuyableClassName().' </li>'; |
||
2954 | $html .= '<li><b>allProducts:</b> '.print_r(str_replace('"', '`', $this->allProducts->sql()), 1).' </li>'; |
||
2955 | |||
2956 | $html .= '<li><hr /><h3>Search</h3><hr /></li>'; |
||
2957 | $resultArray = $this->searchResultsArrayFromSession(); |
||
2958 | $productGroupArray = explode(',', Session::get($this->SearchResultsSessionVariable(true))); |
||
2959 | $html .= '<li><b>Is Search Results:</b> '.($this->IsSearchResults() ? 'YES' : 'NO').' </li>'; |
||
2960 | $html .= '<li><b>Products In Search (session variable : '.$this->SearchResultsSessionVariable(false).'):</b> '.print_r($resultArray, 1).' </li>'; |
||
2961 | $html .= '<li><b>Product Groups In Search (session variable : '.$this->SearchResultsSessionVariable(true).'):</b> '.print_r($productGroupArray, 1).' </li>'; |
||
2962 | |||
2963 | $html .= '<li><hr /><h3>Other</h3><hr /></li>'; |
||
2964 | if ($image = $this->BestAvailableImage()) { |
||
2965 | $html .= '<li><b>Best Available Image:</b> <img src="'.$image->Link.'" /> </li>'; |
||
2966 | } |
||
2967 | $html .= '<li><b>BestAvailableImage:</b> '.($this->BestAvailableImage() ? $this->BestAvailableImage()->Link : 'no image available').' </li>'; |
||
2968 | $html .= '<li><b>Is this an ecommerce page:</b> '.($this->IsEcommercePage() ? 'YES' : 'NO').' </li>'; |
||
2969 | $html .= '<li><hr /><h3>Related Groups</h3><hr /></li>'; |
||
2970 | $html .= '<li><b>Parent product group:</b> '.($this->ParentGroup() ? $this->ParentGroup()->Title : '[NO PARENT GROUP]').'</li>'; |
||
2971 | |||
2972 | $childGroups = $this->ChildGroups(99); |
||
2973 | if ($childGroups->count()) { |
||
2974 | $childGroups = $childGroups->map('ID', 'MenuTitle'); |
||
2975 | $html .= '<li><b>Child Groups (all):</b><pre> '.print_r($childGroups, 1).' </pre></li>'; |
||
3001 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.