oxadminlist.php

Go to the documentation of this file.
00001 <?php
00002 
00006 class oxAdminList extends oxAdminView
00007 {
00008 
00014     protected $_sListClass = null;
00015 
00021     protected $_sListType = 'oxlist';
00022 
00028     protected $_oList = null;
00029 
00035     protected $_iCurrListPos = 0;
00036 
00042     protected $_iListSize = 0;
00043 
00049     protected $_aWhere = null;
00050 
00056     protected $_blDesc = false;
00057 
00063     protected $_blEmployMultilanguage = null;
00064 
00070     protected $_iOverPos = null;
00071 
00077     protected $_iViewListSize = 0;
00078 
00084     protected $_iDefViewListSize = 50;
00085 
00091     protected $_aCurrSorting = null;
00092 
00098     protected $_sDefSortField = null;
00099 
00105     protected $_aListFilter = null;
00106 
00112     public function getListSorting()
00113     {
00114         if ($this->_aCurrSorting === null) {
00115             $this->_aCurrSorting = oxRegistry::getConfig()->getRequestParameter('sort');
00116 
00117             if (!$this->_aCurrSorting && $this->_sDefSortField && ($oBaseObject = $this->getItemListBaseObject())) {
00118                 $this->_aCurrSorting[$oBaseObject->getCoreTableName()] = array($this->_sDefSortField => "asc");
00119             }
00120         }
00121 
00122         return $this->_aCurrSorting;
00123     }
00124 
00130     public function getListFilter()
00131     {
00132         if ($this->_aListFilter === null) {
00133             $this->_aListFilter = oxRegistry::getConfig()->getRequestParameter("where");
00134         }
00135 
00136         return $this->_aListFilter;
00137     }
00138 
00144     protected function _getViewListSize()
00145     {
00146         if (!$this->_iViewListSize) {
00147             $myConfig = $this->getConfig();
00148             if ($aProfile = oxRegistry::getSession()->getVariable('profile')) {
00149                 if (isset($aProfile[1])) {
00150                     $myConfig->setConfigParam('iAdminListSize', (int) $aProfile[1]);
00151                 }
00152             }
00153 
00154             $this->_iViewListSize = (int) $myConfig->getConfigParam('iAdminListSize');
00155             if (!$this->_iViewListSize) {
00156                 $this->_iViewListSize = 10;
00157                 $myConfig->setConfigParam('iAdminListSize', $this->_iViewListSize);
00158             }
00159         }
00160 
00161         return $this->_iViewListSize;
00162     }
00163 
00169     public function getViewListSize()
00170     {
00171         return $this->_getViewListSize();
00172     }
00173 
00179     protected function _getUserDefListSize()
00180     {
00181         if (!$this->_iViewListSize) {
00182             if (!($iViewListSize = (int) oxRegistry::getConfig()->getRequestParameter('viewListSize'))) {
00183                 $iViewListSize = $this->_iDefViewListSize;
00184             }
00185             $this->_iViewListSize = $iViewListSize;
00186         }
00187 
00188         return $this->_iViewListSize;
00189     }
00190 
00196     public function render()
00197     {
00198         $sReturn = parent::render();
00199 
00200         // assign our list
00201         $this->_aViewData['mylist'] = $this->getItemList();
00202 
00203         // set navigation parameters
00204         $this->_setListNavigationParams();
00205 
00206         return $sReturn;
00207     }
00208 
00214     public function deleteEntry()
00215     {
00216         $oDelete = oxNew($this->_sListClass);
00217 
00218 
00219         $blDelete = $oDelete->delete($this->getEditObjectId());
00220 
00221         // #A - we must reset object ID
00222         if ($blDelete && isset($_POST['oxid'])) {
00223             $_POST['oxid'] = -1;
00224         }
00225 
00226         $this->resetContentCache();
00227 
00228         $this->init();
00229     }
00230 
00236     protected function _calcListItemsCount($sSql)
00237     {
00238         $oStr = getStr();
00239 
00240         // count SQL
00241         $sSql = $oStr->preg_replace('/select .* from/i', 'select count(*) from ', $sSql);
00242 
00243         // removing order by
00244         $sSql = $oStr->preg_replace('/order by .*$/i', '', $sSql);
00245 
00246         // con of list items which fits current search conditions
00247         $this->_iListSize = oxDb::getDb()->getOne($sSql, false, false);
00248 
00249         // set it into session that other frames know about size of DB
00250         oxRegistry::getSession()->setVariable('iArtCnt', $this->_iListSize);
00251     }
00252 
00258     protected function _setCurrentListPosition($sPage = null)
00259     {
00260         $iAdminListSize = $this->_getViewListSize();
00261 
00262         $iJumpTo = $sPage ? ((int) $sPage) : ((int) ((int) oxRegistry::getConfig()->getRequestParameter('lstrt')) / $iAdminListSize);
00263         $iJumpTo = ($sPage && $iJumpTo) ? ($iJumpTo - 1) : $iJumpTo;
00264 
00265         $iJumpTo = $iJumpTo * $iAdminListSize;
00266         if ($iJumpTo < 1) {
00267             $iJumpTo = 0;
00268         } elseif ($iJumpTo >= $this->_iListSize) {
00269             $iJumpTo = floor($this->_iListSize / $iAdminListSize - 1) * $iAdminListSize;
00270         }
00271 
00272         $this->_iCurrListPos = $this->_iOverPos = (int) $iJumpTo;
00273     }
00274 
00282     protected function _prepareOrderByQuery($sSql = null)
00283     {
00284         // sorting
00285         $aSortFields = $this->getListSorting();
00286 
00287         if (is_array($aSortFields) && count($aSortFields)) {
00288 
00289             // only add order by at full sql not for count(*)
00290             $sSql .= ' order by ';
00291             $blSep = false;
00292 
00293             $oListItem = $this->getItemListBaseObject();
00294             $iLangId = $oListItem->isMultilang() ? $oListItem->getLanguage() : oxRegistry::getLang()->getBaseLanguage();
00295 
00296             $blSortDesc = oxRegistry::getConfig()->getRequestParameter('adminorder');
00297             $blSortDesc = $blSortDesc !== null ? (bool) $blSortDesc : $this->_blDesc;
00298 
00299             foreach ($aSortFields as $sTable => $aFieldData) {
00300 
00301                 $sTable = $sTable ? (getViewName($sTable, $iLangId) . '.') : '';
00302                 foreach ($aFieldData as $sColumn => $sSortDir) {
00303 
00304                     $sField = $sTable . $sColumn;
00305 
00306                     //add table name to column name if no table name found attached to column name
00307                     $sSql .= ((($blSep) ? ', ' : '')) . oxDb::getInstance()->escapeString($sField);
00308 
00309                     //V oxActive field search always DESC
00310                     if ($blSortDesc || $sColumn == "oxactive" || strcasecmp($sSortDir, 'desc') == 0) {
00311                         $sSql .= ' desc ';
00312                     }
00313 
00314                     $blSep = true;
00315                 }
00316             }
00317         }
00318 
00319         return $sSql;
00320     }
00321 
00329     protected function _buildSelectString($oListObject = null)
00330     {
00331         return $oListObject !== null ? $oListObject->buildSelectString(null) : "";
00332     }
00333 
00334 
00344     protected function _processFilter($sFieldValue)
00345     {
00346         $oStr = getStr();
00347 
00348         //removing % symbols
00349         $sFieldValue = $oStr->preg_replace("/^%|%$/", "", trim($sFieldValue));
00350 
00351         return $oStr->preg_replace("/\s+/", " ", $sFieldValue);
00352     }
00353 
00362     protected function _buildFilter($sVal, $blIsSearchValue)
00363     {
00364         if ($blIsSearchValue) {
00365             //is search string, using LIKE
00366             $sQ = " like " . oxDb::getDb()->quote('%' . $sVal . '%') . " ";
00367         } else {
00368             //not search string, values must be equal
00369             $sQ = " = " . oxDb::getDb()->quote($sVal) . " ";
00370         }
00371 
00372         return $sQ;
00373     }
00374 
00382     protected function _isSearchValue($sFieldValue)
00383     {
00384         //check if this is search string (contains % sign at beginning and end of string)
00385         $blIsSearchValue = false;
00386         $oStr = getStr();
00387         if ($oStr->preg_match('/^%/', $sFieldValue) && $oStr->preg_match('/%$/', $sFieldValue)) {
00388             $blIsSearchValue = true;
00389         }
00390 
00391         //removing % symbols
00392         return $blIsSearchValue;
00393     }
00394 
00405     protected function _prepareWhereQuery($aWhere, $sqlFull)
00406     {
00407         if (count($aWhere)) {
00408             $myUtilsString = oxRegistry::get("oxUtilsString");
00409             while (list($sFieldName, $sFieldValue) = each($aWhere)) {
00410                 $sFieldValue = trim($sFieldValue);
00411 
00412                 //check if this is search string (contains % sign at beginning and end of string)
00413                 $blIsSearchValue = $this->_isSearchValue($sFieldValue);
00414 
00415                 //removing % symbols
00416                 $sFieldValue = $this->_processFilter($sFieldValue);
00417 
00418                 if (strlen($sFieldValue)) {
00419                     $aVal = explode(' ', $sFieldValue);
00420 
00421                     //for each search field using AND action
00422                     $sSqlBoolAction = ' and (';
00423 
00424                     foreach ($aVal as $sVal) {
00425                         // trying to search spec chars in search value
00426                         // if found, add cleaned search value to search sql
00427                         $sUml = $myUtilsString->prepareStrForSearch($sVal);
00428                         if ($sUml) {
00429                             $sSqlBoolAction .= '(';
00430                         }
00431 
00432                         $sFieldName = oxDb::getInstance()->escapeString($sFieldName);
00433                         $sqlFull .= " {$sSqlBoolAction} {$sFieldName} ";
00434 
00435                         //for search in same field for different values using AND
00436                         $sSqlBoolAction = ' and ';
00437 
00438                         $sqlFull .= $this->_buildFilter($sVal, $blIsSearchValue);
00439 
00440                         if ($sUml) {
00441                             $sqlFull .= " or {$sFieldName} ";
00442 
00443                             $sqlFull .= $this->_buildFilter($sUml, $blIsSearchValue);
00444                             $sqlFull .= ')'; // end of OR section
00445                         }
00446                     }
00447 
00448                     // end for AND action
00449                     $sqlFull .= ' ) ';
00450                 }
00451             }
00452         }
00453 
00454         return $sqlFull;
00455     }
00456 
00464     protected function _changeselect($sSql)
00465     {
00466         return $sSql;
00467     }
00468 
00469 
00475     public function buildWhere()
00476     {
00477         if ($this->_aWhere === null && ($oList = $this->getItemList())) {
00478 
00479             $this->_aWhere = array();
00480             $aFilter = $this->getListFilter();
00481             if (is_array($aFilter)) {
00482 
00483                 $oListItem = $this->getItemListBaseObject();
00484                 $iLangId = $oListItem->isMultilang() ? $oListItem->getLanguage() : oxRegistry::getLang()->getBaseLanguage();
00485                 $sLocalDateFormat = $this->getConfig()->getConfigParam('sLocalDateFormat');
00486 
00487                 foreach ($aFilter as $sTable => $aFilterData) {
00488                     foreach ($aFilterData as $sName => $sValue) {
00489                         if ($sValue || '0' === ( string ) $sValue) {
00490 
00491                             $sField = "{$sTable}__{$sName}";
00492 
00493                             // if no table name attached to field name, add it
00494                             $sName = $sTable ? getViewName($sTable, $iLangId) . ".{$sName}" : $sName;
00495 
00496                             // #M1260: if field is date
00497                             if ($sLocalDateFormat && $sLocalDateFormat != 'ISO' && isset($oListItem->$sField)) {
00498                                 $sFldType = $oListItem->{$sField}->fldtype;
00499                                 if ("datetime" == $sFldType || "date" == $sFldType) {
00500                                     $sValue = $this->_convertToDBDate($sValue, $sFldType);
00501                                 }
00502                             }
00503 
00504                             $this->_aWhere[$sName] = "%{$sValue}%";
00505                         }
00506                     }
00507                 }
00508             }
00509         }
00510 
00511         return $this->_aWhere;
00512     }
00513 
00522     protected function _convertToDBDate($sValue, $sFldType)
00523     {
00524         $oConvObject = new oxField();
00525         $oConvObject->setValue($sValue);
00526         if ($sFldType == "datetime") {
00527             if (strlen($sValue) == 10 || strlen($sValue) == 22 || (strlen($sValue) == 19 && !stripos($sValue, "m"))) {
00528                 oxRegistry::get("oxUtilsDate")->convertDBDateTime($oConvObject, true);
00529             } else {
00530                 if (strlen($sValue) > 10) {
00531                     return $this->_convertTime($sValue);
00532                 } else {
00533                     return $this->_convertDate($sValue);
00534                 }
00535             }
00536         } elseif ($sFldType == "date") {
00537             if (strlen($sValue) == 10) {
00538                 oxRegistry::get("oxUtilsDate")->convertDBDate($oConvObject, true);
00539             } else {
00540                 return $this->_convertDate($sValue);
00541             }
00542         }
00543 
00544         return $oConvObject->value;
00545     }
00546 
00554     protected function _convertDate($sDate)
00555     {
00556         // regexps to validate input
00557         $aDatePatterns = array("/^([0-9]{2})\.([0-9]{4})/" => "EUR2", // MM.YYYY
00558                                "/^([0-9]{2})\.([0-9]{2})/" => "EUR1", // DD.MM
00559                                "/^([0-9]{2})\/([0-9]{4})/" => "USA2", // MM.YYYY
00560                                "/^([0-9]{2})\/([0-9]{2})/" => "USA1" // DD.MM
00561         );
00562 
00563         // date/time formatting rules
00564         $aDFormats = array("EUR1" => array(2, 1),
00565                            "EUR2" => array(2, 1),
00566                            "USA1" => array(1, 2),
00567                            "USA2" => array(2, 1)
00568         );
00569 
00570         // looking for date field
00571         $aDateMatches = array();
00572         $oStr = getStr();
00573         foreach ($aDatePatterns as $sPattern => $sType) {
00574             if ($oStr->preg_match($sPattern, $sDate, $aDateMatches)) {
00575                 $sDate = $aDateMatches[$aDFormats[$sType][0]] . "-" . $aDateMatches[$aDFormats[$sType][1]];
00576                 break;
00577             }
00578         }
00579 
00580         return $sDate;
00581     }
00582 
00590     protected function _convertTime($sFullDate)
00591     {
00592         $sDate = substr($sFullDate, 0, 10);
00593         $oConvObject = new oxField();
00594         $oConvObject->setValue($sDate);
00595         oxRegistry::get("oxUtilsDate")->convertDBDate($oConvObject, true);
00596         $oStr = getStr();
00597 
00598         // looking for time field
00599         $sTime = substr($sFullDate, 11);
00600         if ($oStr->preg_match("/([0-9]{2}):([0-9]{2}) ([AP]{1}[M]{1})$/", $sTime, $aTimeMatches)) {
00601             if ($aTimeMatches[3] == "PM") {
00602                 $iIntVal = (int) $aTimeMatches[1];
00603                 if ($iIntVal < 13) {
00604                     $sTime = ($iIntVal + 12) . ":" . $aTimeMatches[2];
00605                 }
00606             } else {
00607                 $sTime = $aTimeMatches[1] . ":" . $aTimeMatches[2];
00608             }
00609         } elseif ($oStr->preg_match("/([0-9]{2}) ([AP]{1}[M]{1})$/", $sTime, $aTimeMatches)) {
00610             if ($aTimeMatches[2] == "PM") {
00611                 $iIntVal = (int) $aTimeMatches[1];
00612                 if ($iIntVal < 13) {
00613                     $sTime = ($iIntVal + 12);
00614                 }
00615             } else {
00616                 $sTime = $aTimeMatches[1];
00617             }
00618         } else {
00619             $sTime = str_replace(".", ":", $sTime);
00620         }
00621 
00622         return $oConvObject->value . " " . $sTime;
00623     }
00624 
00628     protected function _setListNavigationParams()
00629     {
00630         $myConfig = $this->getConfig();
00631 
00632         // list navigation
00633         $blShowNavigation = false;
00634         $iAdminListSize = $this->_getViewListSize();
00635         if ($this->_iListSize > $iAdminListSize) {
00636             // yes, we need to build the navigation object
00637             $pageNavigation = new stdClass();
00638             $pageNavigation->pages = round((($this->_iListSize - 1) / $iAdminListSize) + 0.5, 0);
00639             $pageNavigation->actpage = ($pageNavigation->actpage > $pageNavigation->pages) ? $pageNavigation->pages : round(($this->_iCurrListPos / $iAdminListSize) + 0.5, 0);
00640             $pageNavigation->lastlink = ($pageNavigation->pages - 1) * $iAdminListSize;
00641             $pageNavigation->nextlink = null;
00642             $pageNavigation->backlink = null;
00643 
00644             $iPos = $this->_iCurrListPos + $iAdminListSize;
00645             if ($iPos < $this->_iListSize) {
00646                 $pageNavigation->nextlink = $iPos = $this->_iCurrListPos + $iAdminListSize;
00647             }
00648 
00649             if (($this->_iCurrListPos - $iAdminListSize) >= 0) {
00650                 $pageNavigation->backlink = $iPos = $this->_iCurrListPos - $iAdminListSize;
00651             }
00652 
00653             // calculating list start position
00654             $iStart = $pageNavigation->actpage - 5;
00655             $iStart = ($iStart <= 0) ? 1 : $iStart;
00656 
00657             // calculating list end position
00658             $iEnd = $pageNavigation->actpage + 5;
00659             $iEnd = ($iEnd < $iStart + 10) ? $iStart + 10 : $iEnd;
00660             $iEnd = ($iEnd > $pageNavigation->pages) ? $pageNavigation->pages : $iEnd;
00661 
00662             // once again adjusting start pos ..
00663             $iStart = ($iEnd - 10 > 0) ? $iEnd - 10 : $iStart;
00664             $iStart = ($pageNavigation->pages <= 11) ? 1 : $iStart;
00665 
00666             // navigation urls
00667             for ($i = $iStart; $i <= $iEnd; $i++) {
00668                 $page = new stdclass();
00669                 $page->selected = 0;
00670                 if ($i == $pageNavigation->actpage) {
00671                     $page->selected = 1;
00672                 }
00673                 $pageNavigation->changePage[$i] = $page;
00674             }
00675 
00676             $this->_aViewData['pagenavi'] = $pageNavigation;
00677 
00678             if (isset($this->_iOverPos)) {
00679                 $iPos = $this->_iOverPos;
00680                 $this->_iOverPos = null;
00681             } else {
00682                 $iPos = oxRegistry::getConfig()->getRequestParameter('lstrt');
00683             }
00684 
00685             if (!$iPos) {
00686                 $iPos = 0;
00687             }
00688 
00689             $this->_aViewData['lstrt'] = $iPos;
00690             $this->_aViewData['listsize'] = $this->_iListSize;
00691             $blShowNavigation = true;
00692         }
00693 
00694         // determine not used space in List
00695         $iShowListSize = $this->_iListSize - $this->_iCurrListPos;
00696         $iAdminListSize = $this->_getViewListSize();
00697         $iNotUsed = $iAdminListSize - min($iShowListSize, $iAdminListSize);
00698         $iSpace = $iNotUsed * 15;
00699 
00700         if (!$blShowNavigation) {
00701             $iSpace += 20;
00702         }
00703 
00704         $this->_aViewData['iListFillsize'] = $iSpace;
00705     }
00706 
00712     protected function _setupNavigation($sNode)
00713     {
00714         // navigation according to class
00715         if ($sNode) {
00716 
00717             $myAdminNavigation = $this->getNavigation();
00718 
00719             $sOxId = $this->getEditObjectId();
00720 
00721             if ($sOxId == -1) {
00722                 //on first call or when pressed creating new item button, reseting active tab
00723                 $iActTab = $this->_iDefEdit;
00724             } else {
00725                 // active tab
00726                 $iActTab = oxRegistry::getConfig()->getRequestParameter('actedit');
00727                 $iActTab = $iActTab ? $iActTab : $this->_iDefEdit;
00728             }
00729 
00730             // tabs
00731             $this->_aViewData['editnavi'] = $myAdminNavigation->getTabs($sNode, $iActTab);
00732 
00733             // active tab
00734             $this->_aViewData['actlocation'] = $myAdminNavigation->getActiveTab($sNode, $iActTab);
00735 
00736             // default tab
00737             $this->_aViewData['default_edit'] = $myAdminNavigation->getActiveTab($sNode, $this->_iDefEdit);
00738 
00739             // assign active tab number
00740             $this->_aViewData['actedit'] = $iActTab;
00741         }
00742     }
00743 
00749     public function getItemList()
00750     {
00751         if ($this->_oList === null && $this->_sListClass) {
00752 
00753             $this->_oList = oxNew($this->_sListType);
00754             $this->_oList->clear();
00755             $this->_oList->init($this->_sListClass);
00756 
00757             $aWhere = $this->buildWhere();
00758 
00759             $oListObject = $this->_oList->getBaseObject();
00760 
00761             oxRegistry::getSession()->setVariable('tabelle', $this->_sListClass);
00762             $this->_aViewData['listTable'] = getViewName($oListObject->getCoreTableName());
00763             $this->getConfig()->setGlobalParameter('ListCoreTable', $oListObject->getCoreTableName());
00764 
00765             if ($oListObject->isMultilang()) {
00766                 // is the object multilingual?
00767                 $oListObject->setLanguage(oxRegistry::getLang()->getBaseLanguage());
00768 
00769                 if (isset($this->_blEmployMultilanguage)) {
00770                     $oListObject->setEnableMultilang($this->_blEmployMultilanguage);
00771                 }
00772             }
00773 
00774             $sSql = $this->_buildSelectString($oListObject);
00775             $sSql = $this->_prepareWhereQuery($aWhere, $sSql);
00776             $sSql = $this->_prepareOrderByQuery($sSql);
00777             $sSql = $this->_changeselect($sSql);
00778 
00779             // calculates count of list items
00780             $this->_calcListItemsCount($sSql);
00781 
00782             // setting current list position (page)
00783             $this->_setCurrentListPosition(oxRegistry::getConfig()->getRequestParameter('jumppage'));
00784 
00785             // setting addition params for list: current list size
00786             $this->_oList->setSqlLimit($this->_iCurrListPos, $this->_getViewListSize());
00787 
00788             $this->_oList->selectString($sSql);
00789         }
00790 
00791         return $this->_oList;
00792     }
00793 
00797     public function clearItemList()
00798     {
00799         $this->_oList = null;
00800     }
00801 
00807     public function getItemListBaseObject()
00808     {
00809         if (($oList = $this->getItemList())) {
00810             return $oList->getBaseObject();
00811         }
00812     }
00813 }