"cats.php", "version" => "4.13", "modified" => "2025.11.21", "release" => "release", "status" => "open source", "author" => "Sean Shrum", "email" => "sshrum01@gmail.com", "created" => "2005.07.21", "distribute" => "http://cats.shrum.net" ); // force the document root to the WWW Root debug("+ Script info
+ List of available parameters and their script set defaults (null'ed items unless specified get UNSET()):
+ Importing '".substr(basename(__FILE__), 0, -4 ).".ini' key => value pairs from all directories starting in [DOCUMENT_ROOT] thru ".$aParams['dir']."...
+ UNSET()'ing any parameters = 'null'...."); $iCut=0; ksort($aParams); foreach($aParams as $key => $value) { if (strtolower($value) == "null") { $iCut++; unset($aParams[$key]); } } debug("" . $iCut . " parameters removed
"); // display our finalized $aParams if debug defined debug("+ Current [PARAM]eters for this run (CATS.INI::[defaults] + URL-based parameters)
+ Current [PAGES] for this run (CATS.INI / [pages])
+ Current [KEYWORDS] for this run (CATS.INI / [keywords])
+ Retrieving templates...
+ [PLUGIN] defined => ".$aParams['plugin']."
"); if (substr($sTemp, -4, 4) != ".php") { $aParams['plugin'] .= ".php"; } if (isset($aParams['plugins'])) { debug("+ [PLUGINS] defined => ".$aParams['plugins']."
"); if (file_exists($_SERVER['DOCUMENT_ROOT'].$aParams['plugins'])) { debug("+ [PLUGINS] => [DOCUMENT_ROOT]".$aParams['plugins']."
"); $aParams['plugins'] = $_SERVER['DOCUMENT_ROOT'].$aParams['plugins']; } else { Print "+ [PLUGINS] => " . $aParams['plugins']." could not be found. Please check spelling and file existance. Exiting
"; exit; } } else { debug("+ [PLUGINS] undefined; using: [DOCUMENT_ROOT]
"); debug("+ [PLUGINS] => ".$_SERVER['DOCUMENT_ROOT']."
"); $aParams['plugins'] = $_SERVER['DOCUMENT_ROOT']; } if (file_exists($aParams['plugins']."/".$aParams['plugin'])) { debug("+ [PLUGINS]/[PLUGIN] => '".$aParams['plugins']."/".$aParams['plugin'] . "' FOUND"); require $aParams['plugins']."/".$aParams['plugin']; } else { print "
+ Calling [PLUGINS]/[PLUGIN] for [DATA] array...
"); $aScript['timer:plugin'] = microtime(); $aData = main($aParams); if (isset($aData) && is_array($aData) && count($aData) > 0 ) { debug("+ [DATA] => [".count($aData)."] x [".count($aData[0])."]
"); debug($aData); } $aA = explode(' ', $aScript['timer:plugin'].' '.microtime()); $aScript['timer:plugin'] = sprintf('%01.4f',($aA[2]+$aA[3])-($aA[0]+$aA[1])); } else { $aScript['timer:plugin'] = 0; } // [DATA] functions ****************************************************** while (true) { $aRecordset['start'] = 0; if (isset($aData) && is_array($aData) && count($aData) > 0 ) { // [WHERE] functions ****************************************************** // currently only handling 1 where field. // this allows the webmaster to define a top level recordset SEARCH // [search] will provide user end filtering within the WHERE recordset if (isset($aParams['where'])) { debug("+ [WHERE] => '" . $aParams['where']."'
"); list($sField, $sValue) = explode("=", $aParams['where']); if (array_key_exists($sField, $aData[0])) { $iCut=0; debug("+ Unsetting records from [DATA]..."); foreach ($aData as $key => $row) { if ($aData[$key][$sField] <> $sValue) { $iCut++; unset($aData[$key]); } } if ($iCut > 0) { $aData = array_values($aData); debug("".$iCut." entries cut
"); debug("+ [WHERE][DATA] => [".count($aData)."] x [".count($aData[0])."]
"); debug($aData); } else { debug("".$iCut." entries cut"); } } else { debug("+ [WHERE] field => '".$sValue."' not found in [DATA], operation skipped"); } } else { debug("
+ [WHERE] undefined; operation skipped"); } if (count($aData) == 0) { break; } $aRecordset['total'] = count($aData); $aRecordset['cols'] = count($aData[0]); if (!isset($aParams['search'])) { $sSearch = ""; } else { $sSearch = $aParams['search']; } if (!isset($aParams['in'])) { $sIn = ""; } else { $sIn = $aParams['in']; } if (!isset($aParams['order'])) { $sOrder = ""; } else { $sOrder = $aParams['order']; } if (!isset($aParams['sort'])) { $sSort = "undefined"; } else { if (substr(strtolower($aParams['sort']), 0, 1) == "a") { $sSort = "ascending"; } if (substr(strtolower($aParams['sort']), 0, 1) == "d") { $sSort = "descending"; } if (isset($sSort) && isset($aParams['order'])) { $sSort .= " ".$aParams['order']; } if (substr(strtolower($aParams['sort']), 0, 1) == "r") { $sSort = "random"; } } $aRecordset['ascdesc'] = $sSort; ass_search($aData, $sSearch, $sIn, $sOrder, $sSort); if (count($aData) == 0) { break; } $aRecordset['match'] = count($aData); $aRecordset['range'] = $aRecordset['match']; // 0 - all records if (isset($aParams['limit'])) { list($aRecordset['start'], $aRecordset['range']) = explode(",", $aParams['limit']); if (!isset($aRecordset['start']) || (!isset($aRecordset['range']))) { debug("
+ [LIMIT] badly formatted; should be in '#,#' format; [start],[range]
"); debug("+ [LIMIT] operations are skipped
"); } if ($aRecordset['start'] > $aRecordset['match']) { print "+ [LIMIT] start => '".$aRecordset['start']."' is beyond the total of records in [DATA]: '".$aRecordset['match']."'."; print "
Script execution halted."; exit; } if ($aRecordset['start'] + $aRecordset['range'] > $aRecordset['match']) { $aRecordset['range'] = $aRecordset['match'] - $aRecordset['start'];} if (count($aData) < $aRecordset['start'] + $aRecordset['range']) { $aRecordset['range'] = count($aData) - $aRecordset['start']; } debug("
+ [LIMIT] => [".$aRecordset['start'].",".$aRecordset['range']."]
"); $aData = array_slice($aData,$aRecordset['start'], $aRecordset['range']); debug($aData); } else { debug("+ [LIMIT] undefined, setting for all records => [".$aRecordset['start'].",".$aRecordset['range']."]
"); } $aRecordset['colnav'] = ""; for ($i = 1; $i <= 7; $i++) { if ($i == $aParams['cols']) { $sTemp = "" . $i . " "; } else { $sTemp = "" . $i . " "; } $aRecordset['colnav'] .= $sTemp; } $aRecordset['limitnav'] = ""; for ($i = 2; $i <= 4; $i++) { $sTemp = "" . $aParams['cols'] * $aParams['rows'] * $i . ""; $aRecordset['limitnav'] .= " " . $sTemp; } $aRecordset['first'] = $aRecordset['start'] + 1; $aRecordset['last'] = $aRecordset['start'] + $aRecordset['range']; // deals with last slices with row < range if (isset($aParams['limit'])) { list($aRecordset['start'], $aRecordset['range']) = explode(",", $aParams['limit']); } else { $aRecordset['range'] = $aRecordset['match']; } $aRecordset['slicecount'] = 1; $aRecordset['slicecurrent'] = 1; $aRecordset['sliceprevious'] = $_SERVER['REQUEST_URI']; $aRecordset['slicenext'] = $_SERVER['REQUEST_URI']; $aRecordset['sliceall'] = query_string_mod ($_SERVER['REQUEST_URI'], "limit", "null"); $aRecordset['slicefirst'] = query_string_mod ($_SERVER['REQUEST_URI'], "limit", "0,".$aRecordset['range']); $aRecordset['slicelast'] = query_string_mod ($_SERVER['REQUEST_URI'], "limit", floor($aRecordset['match']/$aRecordset['range']) * $aRecordset['range'] . ",".$aRecordset['range']); $aRecordset['sortasc'] = query_string_mod ($_SERVER['REQUEST_URI'], "sort", "asc"); $aRecordset['sortdesc'] = query_string_mod ($_SERVER['REQUEST_URI'], "sort", "desc"); $aRecordset['sortrandom'] = query_string_mod($_SERVER['REQUEST_URI'], "sort", "random"); if ($aRecordset['range'] <= $aRecordset['match']) { $aRecordset['slicecount'] = ceil($aRecordset['match']/$aRecordset['range']); $aRecordset['slicecurrent'] = ceil($aRecordset['first']/$aRecordset['range']); } if($aRecordset['slicecount'] > 1 ) { if($aRecordset['slicecurrent'] != 1 ) { $aRecordset['sliceprevious'] = query_string_mod($_SERVER['REQUEST_URI'], "limit", $aRecordset['start'] - $aRecordset['range'].",".$aRecordset['range']); } if ($aRecordset['slicecurrent'] != $aRecordset['slicecount'] ) { $aRecordset['slicenext'] = query_string_mod($_SERVER['REQUEST_URI'], "limit", $aRecordset['start'] + $aRecordset['range'].",".$aRecordset['range']); } } $aRecordset['slicecurrent'] = ceil(($aRecordset['start'] + 1) / $aRecordset['range']); // HR inclusion between rows; set as blank, change if needed $sHR = ""; if (isset($aParams['hr'])) { if (strtoupper($aParams['hr']) == "Y") { $sHR = "| ".$sRecord." | "; if ($iColNum == $aParams['cols']) { $sRecords .= ""; $iColNum = 0; $iRowNum++; } $iRecord++; } $aRecordset['return'] = count($aData); debug("DONE
+ Filtered [DATA] set contains ZERO records
"); $sRecords ="
+ Plugin returned ZERO records
"); $sRecords ="+ Combining templates; [RECORDS]=>[TABLE]=>[BODY]=>[PAGE]
"); $sPage = str_replace ('$nest$', $aTemplates['body'], $aTemplates['page']); $sPage = str_replace ('$nest$', $aTemplates['table'], $sPage); $sPage = str_replace ('$nest$', $sRecords, $sPage); debug("+ NAV replacement in output
"); $sPage = str_replace ('$nav$', $aTemplates['nav'], $sPage); // retrieve any user cats.ini [pages] into the final PAGE var (do this before PARAM s-n-r) if ((isset($aPages)) && (count($aPages) >= 1)) { debug("+ Retrieving and nesting user defined cats.ini [PAGES] into final PAGE var
+ Processing search and replace on template tokens..."); foreach($aParams as $key => $value) { $sPage = str_replace ("!".$key."!", stripslashes($value), $sPage); } foreach($_SERVER as $key => $value) { If (!is_array($value)) { $sPage = str_replace ("$".$key."$", stripslashes($value), $sPage); } } if (isset($aKeywords)) { foreach($aKeywords as $key => $value) { $sPage = str_replace ($key, $value, $sPage); } } foreach(date_array("0") as $key => $value) { $sPage = str_replace (":".$key.":", $value, $sPage); } // get the end time for timer:overall $aA = explode(' ', $aScript['timer:overall'].' '.microtime()); $aScript['timer:overall'] = sprintf('%01.4f',($aA[2]+$aA[3])-($aA[0]+$aA[1])); $aScript['timer:cats'] = $aScript['timer:overall'] - $aScript['timer:plugin'] - $aScript['timer:templates']; foreach($aScript as $key => $value) { $sPage = str_replace ("*".$key."*", stripslashes($value), $sPage); } $sPage = str_replace ("*pagesize*", number_format(strlen($sPage)/1024), $sPage); print($sPage); exit; //========================================================= // Function Library //========================================================= Function ass_search(&$aData, $sSearch, $sIn = "", $sOrder = "", $sSort = "") { debug("
+ ass_search()
"); // [DATA] validation if (!isset($aData) && !is_array($aData) && !count($aData) > 0) { debug("+ [DATA] is not set/an array/or empty; operation skipped
"); return; } // timer start $iTimer = microtime(); // [SEARCH] validation if ($sSearch !== "") { debug("+ [SEARCH] defined; => '" . $sSearch ."'
"); // [IN] validation and $aIn creation $iIn = 0; if ($sIn !== "") { $iIn = substr_count($sIn,',') + 1; debug("+ [IN] defined; => '".$sIn."'
"); $aIn = explode(",", $sIn); foreach ($aIn as $key => $value) { if (!array_key_exists($value, $aData[0])) { debug("+ [IN] => '".$value."' not found in [DATA]; removing
"); unset($aIn[$key]); } } $iIn = count($aIn); } // [SEARCH] breakdown into $aSearch => [operator][term] $aSearch = array(); while (True) { $sOperator = ""; $sTerm = ""; if (substr($sSearch, 0,1) == "-" || substr($sSearch, 0,1) == "+" || substr($sSearch, 0,1) == "^") { $sOperator = substr($sSearch, 0, 1); $sSearch = substr($sSearch, 1); $sSearch = substr($sSearch, strlen($sTerm)); } if (substr($sSearch, 0,1) == '"') { $sOperator = substr($sSearch, 0, 1); $sSearch = substr($sSearch, 1); $sTerm = substr($sSearch, 0, stripos($sSearch, '"')); $sSearch = substr($sSearch, strlen($sTerm)); $sSearch = substr($sSearch, 1); } else { if (strpos($sSearch, " ") == false) { $sTerm = $sSearch; $sSearch = ""; } else { $sTerm = substr($sSearch, 0, stripos($sSearch, " ")+1); $sSearch = substr($sSearch, strlen($sTerm)); } } $aSearch[] = array ("operator" => $sOperator, "term" => $sTerm); if ($sSearch == "") { break; } } debug("+ [SEARCH] ".count($aSearch)." term(s) detected
"); $iCut = 0; $iTerms = count($aSearch); debug($aSearch); debug("+ [SEARCH] applying search terms to [DATA]...
"); // [DATA] filtering based on [SEARCH] or [SEARCH][IN] foreach ($aData as $key => $row) { if ($iIn > 0) { $sData = ""; For ($i=0; $i < $iIn; $i++) { $sData .= $aData[$key][$aIn[$i]] . " | "; } If ($iIn > 1) { array_multisort("operator", SORT_ASC, SORT_NATURAL|SORT_FLAG_CASE, $aIn); } // -,+,none,^," } else { $sData = implode(" | ", $row); } // [SEARCH] operator handling For ($i=0; $i < $iTerms; $i++) { $iKeep = FALSE; if ($aSearch[$i]['operator'] == "-") { if (stripos($sData, $aSearch[$i]['term']) !== FALSE ) { $i = $iTerms; } else { $iKeep = TRUE; } } elseif ($aSearch[$i]['operator'] == "+") { if (stripos($sData, $aSearch[$i]['term']) == FALSE) { $i = $iTerms; } else { $iKeep = TRUE; } } elseif ($aSearch[$i]['operator'] == "" || $aSearch[$i]['operator'] == '"') { if (stripos($sData, $aSearch[$i]['term']) !== FALSE) { $iKeep = TRUE; } } elseif ($aSearch[$i]['operator'] == "^") { if (strpos($sData, $aSearch[$i]['term']) !== FALSE) { $iKeep = TRUE; } } if ($iKeep == FALSE) { break; } } if ($iKeep == False) { $iCut++; unset($aData[$key]); } } $aData = array_values($aData); debug("+ [SEARCH] ".$iCut." entries cut
"); if (count($aData) > 0) { debug("+ [DATA] => [".count($aData)."] x [".count($aData[0])."]
"); debug($aData); } } else { debug("+ [SEARCH] undefined; operation skipped"); } // Are there any records left after [SEARCH] for [ORDER][SORT] and [LIMIT] if (count($aData) == 0) { debug("
+ ass_search():[DATA] contains matching records
"); return; } // [ORDER][SORT] functions ****************************************************** if ($sOrder !== "") { // right now I only take 1 order field. // need to create routine to take multiple order fields for array_multisort() // also need to clean this up so random is in with asc and desc // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV if (array_key_exists($sOrder, $aData[0])) { debug("+ [ORDER] defined => '" . $sOrder ."', header exists
"); // [ORDER][SORT] functions ****************************************************** if ($sSort !== "undefined" or $sSort !== "" or $sSort !== "random") { debug("+ [SORT] defined => ". $sSort . "
"); $aData = array_values($aData); $order = array_column($aData, $sOrder); If (substr(strtolower($sSort), 0, 1) == "a") { array_multisort($order, SORT_ASC, SORT_NATURAL|SORT_FLAG_CASE, $aData); } elseif (substr(strtolower($sSort), 0, 1) == "d") { array_multisort($order, SORT_DESC, SORT_NATURAL|SORT_FLAG_CASE, $aData); } debug("
+ [ORDER]+[SORT] => [".$sSort."]
"); } else { debug("+ [SORT] undefined; operation skipped
"); } } else { // [ORDER] field not found in [DATA] debug("+ [ORDER] => '".$sOrder."' header does not exist in DATA; operations skipped."); } } else { debug("
+ [ORDER] undefined; [ORDER]+[SORT] operations skipped."); } // [SORT] Randomize; [ORDER] not needed for randomization if (substr(strtolower($sSort), 0, 1) == "r") { debug("
+ [SORT] undefined; [ORDER]+[SORT] operations skipped."); shuffle($aData); } $aA = explode(' ', $iTimer.' '.microtime()); debug("
+ ass_search():time => ". sprintf('%01.4f',($aA[2]+$aA[3])-($aA[0]+$aA[1])) . "/s
"); }Function debug($data) { if (isset($_REQUEST['debug'])) { if (!is_array($data)) { print($data); } else { if (count($data) > 0) { $sTable ="| " . htmlspecialchars($header) . " | "; } $sTable .= "
|---|
| " . htmlspecialchars($cell) . " | "; } $sTable .= "