|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2009-2011 Julian Kleinhans <typo3@kj187.de> 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * 00017 * This script is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * This copyright notice MUST APPEAR in all copies of the script! 00023 ***************************************************************/ 00024 00025 require_once(t3lib_extMgm::extPath('recycler', 'classes/helper/class.tx_recycler_helper.php')); 00026 00027 /** 00028 * Model class for the 'recycler' extension. 00029 * 00030 * @author Julian Kleinhans <typo3@kj187.de> 00031 * @package TYPO3 00032 * @subpackage tx_recycler 00033 * @version $Id: class.tx_recycler_model_deletedRecords.php 10120 2011-01-18 20:03:36Z ohader $ 00034 */ 00035 class tx_recycler_model_deletedRecords { 00036 /** 00037 * Array with all deleted rows 00038 * @var array 00039 */ 00040 protected $deletedRows = array(); 00041 00042 /** 00043 * String with the global limit 00044 * @var string 00045 */ 00046 protected $limit = ''; 00047 00048 /** 00049 * Array with all avaiable FE tables 00050 * @var array 00051 */ 00052 protected $table = array(); 00053 00054 /** 00055 * Object from helper class 00056 * @var tx_recycler_helper 00057 */ 00058 protected $recyclerHelper; 00059 00060 /** 00061 * Array with all label fields drom different tables 00062 * @var array 00063 */ 00064 public $label; 00065 00066 /** 00067 * Array with all title fields drom different tables 00068 * @var array 00069 */ 00070 public $title; 00071 00072 00073 /************************************************************ 00074 * GET DATA FUNCTIONS 00075 * 00076 * 00077 ************************************************************/ 00078 00079 /** 00080 * Load all deleted rows from $table 00081 * If table is not set, it iterates the TCA tables 00082 * 00083 * @param integer $id: UID from selected page 00084 * @param string $table: Tablename 00085 * @param integer $depth: How many levels recursive 00086 * @param integer $limit: MySQL LIMIT 00087 * @param string $filter: Filter text 00088 * @return recycler_model_delRecords 00089 */ 00090 public function loadData($id, $table, $depth, $limit='', $filter = '') { 00091 // set the limit 00092 $this->limit = trim($limit); 00093 00094 if ($table) { 00095 if (array_key_exists($table, $GLOBALS['TCA'])) { 00096 $this->table[] = $table; 00097 $this->setData($id, $table, $depth, $GLOBALS['TCA'][$table]['ctrl'], $filter); 00098 } 00099 } else { 00100 foreach ($GLOBALS['TCA'] as $tableKey => $tableValue) { 00101 // only go into this table if the limit allows it 00102 if ($this->limit != '') { 00103 $parts = t3lib_div::trimExplode(',', $this->limit); 00104 00105 // abort loop if LIMIT 0,0 00106 if ($parts[0] == 0 && $parts[1] == 0) { 00107 break; 00108 } 00109 } 00110 00111 $this->table[] = $tableKey; 00112 $this->setData($id, $tableKey, $depth, $tableValue['ctrl'], $filter); 00113 } 00114 } 00115 00116 return $this; 00117 } 00118 00119 /** 00120 * Find the total count of deleted records 00121 * 00122 * @param integer $id: UID from record 00123 * @param string $table: Tablename from record 00124 * @param integer $depth: How many levels recursive 00125 * @param string $filter: Filter text 00126 * @return void 00127 */ 00128 public function getTotalCount($id, $table, $depth, $filter) { 00129 $deletedRecords = $this->loadData($id, $table, $depth, '', $filter)->getDeletedRows(); 00130 $countTotal = 0; 00131 00132 foreach($this->table as $tableName) { 00133 $countTotal += count($deletedRecords[$tableName]); 00134 } 00135 00136 return $countTotal; 00137 } 00138 00139 /** 00140 * Set all deleted rows 00141 * 00142 * @param integer $id: UID from record 00143 * @param string $table: Tablename from record 00144 * @param integer $depth: How many levels recursive 00145 * @param array $ctrl: TCA CTRL Array 00146 * @param string $filter: Filter text 00147 * @return void 00148 */ 00149 protected function setData($id = 0, $table, $depth, $tcaCtrl, $filter) { 00150 $id = intval($id); 00151 00152 if (array_key_exists('delete', $tcaCtrl)) { 00153 // find the 'deleted' field for this table 00154 $deletedField = tx_recycler_helper::getDeletedField($table); 00155 00156 // create the filter WHERE-clause 00157 if (trim($filter) != '') { 00158 $filterWhere = ' AND (' . 00159 (t3lib_div::testInt($filter) ? 'uid = ' . $filter . ' OR pid = ' . $filter . ' OR ' : '') . 00160 $tcaCtrl['label'] . ' LIKE "%' . $this->escapeValueForLike($filter, $table) . '%"' . 00161 ')'; 00162 } 00163 00164 // get the limit 00165 if ($this->limit != '') { 00166 // count the number of deleted records for this pid 00167 $deletedCount = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows( 00168 'uid', 00169 $table, 00170 $deletedField . '!=0 AND pid = ' . $id . $filterWhere 00171 ); 00172 00173 // split the limit 00174 $parts = t3lib_div::trimExplode(',', $this->limit); 00175 $offset = $parts[0]; 00176 $rowCount = $parts[1]; 00177 00178 // subtract the number of deleted records from the limit's offset 00179 $result = $offset - $deletedCount; 00180 00181 // if the result is >= 0 00182 if ($result >= 0) { 00183 // store the new offset in the limit and go into the next depth 00184 $offset = $result; 00185 $this->limit = implode(',', array($offset, $rowCount)); 00186 00187 // do NOT query this depth; limit also does not need to be set, we set it anyways 00188 $allowQuery = false; 00189 $allowDepth = true; 00190 $limit = ''; // won't be queried anyways 00191 // if the result is < 0 00192 } else { 00193 // the offset for the temporary limit has to remain like the original offset 00194 // in case the original offset was just crossed by the amount of deleted records 00195 if ($offset != 0) { 00196 $tempOffset = $offset; 00197 } else { 00198 $tempOffset = 0; 00199 } 00200 00201 // set the offset in the limit to 0 00202 $newOffset = 0; 00203 00204 // convert to negative result to the positive equivalent 00205 $absResult = abs($result); 00206 00207 // if the result now is > limit's row count 00208 if ($absResult > $rowCount) { 00209 // use the limit's row count as the temporary limit 00210 $limit = implode(',', array($tempOffset, $rowCount)); 00211 00212 // set the limit's row count to 0 00213 $this->limit = implode(',', array($newOffset, 0)); 00214 00215 // do not go into new depth 00216 $allowDepth = false; 00217 } else { 00218 // if the result now is <= limit's row count 00219 // use the result as the temporary limit 00220 $limit = implode(',', array($tempOffset, $absResult)); 00221 00222 // subtract the result from the row count 00223 $newCount = $rowCount - $absResult; 00224 00225 // store the new result in the limit's row count 00226 $this->limit = implode(',', array($newOffset, $newCount)); 00227 00228 // if the new row count is > 0 00229 if ($newCount > 0) { 00230 // go into new depth 00231 $allowDepth = true; 00232 } else { 00233 // if the new row count is <= 0 (only =0 makes sense though) 00234 // do not go into new depth 00235 $allowDepth = false; 00236 } 00237 } 00238 00239 // allow query for this depth 00240 $allowQuery = true; 00241 } 00242 } else { 00243 $limit = ''; 00244 $allowDepth = true; 00245 $allowQuery = true; 00246 } 00247 00248 // query for actual deleted records 00249 if ($allowQuery) { 00250 $recordsToCheck = t3lib_BEfunc::getRecordsByField( 00251 $table, 00252 $deletedField, 00253 '1', 00254 ' AND pid = ' . $id . $filterWhere , 00255 '', 00256 '', 00257 $limit, 00258 false 00259 ); 00260 if ($recordsToCheck) { 00261 $this->checkRecordAccess($table, $recordsToCheck); 00262 } 00263 } 00264 00265 // go into depth 00266 if ($allowDepth && $depth >= 1) { 00267 // check recursively for elements beneath this page 00268 $resPages = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid=' . $id, '', 'sorting'); 00269 if (is_resource($resPages)) { 00270 while ($rowPages = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resPages)) { 00271 $this->setData($rowPages['uid'], $table, $depth - 1, $tcaCtrl, $filter); 00272 00273 // some records might have been added, check if we still have the limit for further queries 00274 if ('' != $this->limit) { 00275 $parts = t3lib_div::trimExplode(',', $this->limit); 00276 00277 // abort loop if LIMIT 0,0 00278 if ($parts[0] == 0 && $parts[1] == 0) { 00279 break; 00280 } 00281 } 00282 } 00283 $GLOBALS['TYPO3_DB']->sql_free_result($resPages); 00284 } 00285 } 00286 00287 $this->label[$table] = $tcaCtrl['label']; 00288 $this->title[$table] = $tcaCtrl['title']; 00289 } 00290 } 00291 00292 /** 00293 * Checks whether the current backend user has access to the given records. 00294 * 00295 * @param string $table: Name of the table 00296 * @param array $rows: Record row 00297 * @return void 00298 */ 00299 protected function checkRecordAccess($table, array $rows) { 00300 foreach ($rows as $key => $row) { 00301 if (tx_recycler_helper::checkAccess($table, $row)) { 00302 $this->setDeletedRows($table, $row); 00303 } 00304 } 00305 } 00306 00307 /** 00308 * Escapes a value to be used for like in a database query. 00309 * There is a special handling for the characters '%' and '_'. 00310 * 00311 * @param string $value: The value to be escaped for like conditions 00312 * @paran string $tableName: The name of the table the query should be used for 00313 * @return string The escaped value to be used for like conditions 00314 */ 00315 protected function escapeValueForLike($value, $tableName) { 00316 return $GLOBALS['TYPO3_DB']->escapeStrForLike( 00317 $GLOBALS['TYPO3_DB']->quoteStr($value, $tableName), 00318 $tableName 00319 ); 00320 } 00321 00322 00323 /************************************************************ 00324 * DELETE FUNCTIONS 00325 ************************************************************/ 00326 00327 /** 00328 * Delete element from any table 00329 * 00330 * @param string $recordArray: Representation of the records 00331 * @return void 00332 */ 00333 public function deleteData($recordsArray) { 00334 $recordsArray = json_decode($recordsArray); 00335 if (is_array($recordsArray)) { 00336 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 00337 $tce->start('', ''); 00338 $tce->disableDeleteClause(); 00339 foreach ($recordsArray as $key => $record) { 00340 $tce->deleteEl($record[0], $record[1], true, true); 00341 } 00342 return true; 00343 } 00344 return false; 00345 } 00346 00347 00348 /************************************************************ 00349 * UNDELETE FUNCTIONS 00350 ************************************************************/ 00351 00352 /** 00353 * Undelete records 00354 * If $recursive is true all records below the page uid would be undelete too 00355 * 00356 * @param string $recordArray: Representation of the records 00357 * @param boolean $recursive: true/false 00358 * @return boolean 00359 */ 00360 public function undeleteData($recordsArray, $recursive = false) { 00361 require_once PATH_t3lib . 'class.t3lib_tcemain.php'; 00362 $result = false; 00363 $depth = 999; 00364 00365 $recordsArray = json_decode($recordsArray); 00366 00367 if (is_array($recordsArray)) { 00368 $this->deletedRows = array(); 00369 $cmd = array(); 00370 00371 foreach ($recordsArray as $key => $row) { 00372 $cmd[$row[0]][$row[1]]['undelete'] = 1; 00373 if ($row[0] == 'pages' && $recursive == true) { 00374 $this->loadData($row[1], '', $depth, ''); 00375 $childRecords = $this->getDeletedRows(); 00376 if (count($childRecords)>0) { 00377 foreach ($childRecords as $table => $childRows) { 00378 foreach ($childRows as $childKey => $childRow) { 00379 $cmd[$table][$childRow['uid']]['undelete'] = 1; 00380 } 00381 } 00382 } 00383 } 00384 } 00385 00386 if ($cmd) { 00387 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 00388 $tce->start(array(), $cmd); 00389 $tce->process_cmdmap(); 00390 $result = true; 00391 } 00392 } 00393 00394 return $result; 00395 } 00396 00397 00398 /************************************************************ 00399 * SETTER FUNCTIONS 00400 ************************************************************/ 00401 00402 /** 00403 * Set deleted rows 00404 * 00405 * @param string $table: Tablename 00406 * @param array $row: Deleted record row 00407 * @return void 00408 */ 00409 public function setDeletedRows($table, array $row) { 00410 $this->deletedRows[$table][] = $row; 00411 } 00412 00413 00414 /************************************************************ 00415 * GETTER FUNCTIONS 00416 ************************************************************/ 00417 00418 /** 00419 * Get deleted Rows 00420 * 00421 * @return array $this->deletedRows: Array with all deleted rows from TCA 00422 */ 00423 public function getDeletedRows() { 00424 return $this->deletedRows; 00425 } 00426 00427 /** 00428 * Get table 00429 * 00430 * @return array $this->table: Array with table from TCA 00431 */ 00432 public function getTable() { 00433 return $this->table; 00434 } 00435 } 00436 00437 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/recycler/classes/model/class.tx_recycler_model_deletedRecords.php'])) { 00438 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/recycler/classes/model/class.tx_recycler_model_deletedRecords.php']); 00439 } 00440 00441 ?>
1.8.0