* The newest version can be found at http://www.ashberg.de/bar * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* CONFIGURATION */ /* ******************************************************************** */ /* COLORS */ /* ******************************************************************** */ $bar_color=Array(0,0,0); $bg_color=Array(255,255,255); $text_color=Array(0,0,0); /* ******************************************************************** */ /* FONT FILE */ /* ******************************************************************** */ /* location the the ttf-font */ /* the file arialbd.ttf isn't included! */ /* SAMPLE1 : * use arialbd.ttf located in same directory like the script * which includes/requires php-barcode.php */ $font_loc=dirname($_SERVER["PATH_TRANSLATED"])."/img/"."arialbd.ttf"; /* SAMPLE2 : * use font specified by full-path */ //$font_loc="/path/font.ttf" /* Automatic-Detection of Font if running Windows * kick this lines if you don't need them! */ if (isset($_ENV['windir']) && file_exists($_ENV['windir'])){ $font_loc=$_ENV['windir']."\Fonts\arialbd.ttf"; } /* ******************************************************************** */ /* GENBARCODE */ /* ******************************************************************** */ /* location of 'genbarcode' * leave blank if you don't have them :( * genbarcode is needed to render encodings other than EAN-12/EAN-13/ISBN */ //$genbarcode_loc="c:\winnt\genbarcode.exe"; $genbarcode_loc="/usr/local/bin/genbarcode"; /* CONFIGURATION ENDS HERE */ require("encode_bars.php"); /* build-in encoders */ /* * barcode_outimage(text, bars [, scale [, mode [, total_y [, space ]]]] ) * * Outputs an image using libgd * * text : the text-line (:: ...) * bars : where to place the bars (...) * scale : scale factor ( 1 < scale < unlimited (scale 50 will produce * 5400x300 pixels when * using EAN-13!!!)) * mode : png,gif,jpg, depending on libgd ! (default='png') * total_y: the total height of the image ( default: scale * 60 ) * space : space * default: * $space[top] = 2 * $scale; * $space[bottom]= 2 * $scale; * $space[left] = 2 * $scale; * $space[right] = 2 * $scale; */ function barcode_outimage($text, $bars, $scale = 1, $mode = "png", $total_y = 0, $space = '', $filename = ''){ global $bar_color, $bg_color, $text_color; global $font_loc; /* set defaults */ if ($scale<1) $scale=2; $total_y=(int)($total_y); if ($total_y<1) $total_y=(int)$scale * 60; if (!$space) $space=array('top'=>2*$scale,'bottom'=>2*$scale,'left'=>2*$scale,'right'=>2*$scale); /* count total width */ $xpos=0; $width=true; for ($i=0;$i\n"; print "
\n"; print "
\n"; print "Short HOWTO
\n"; print "
\n"; print "Debian: # apt-get install php4-gd2
\n"; print "
\n"; print "SuSE: ask YaST
\n"; print "
\n"; print "OpenBSD: # pkg_add /path/php4-gd-4.X.X.tgz (read output, you have to enable it)
\n"; print "
\n"; print "Windows: Download the PHP zip package from php.net, NOT the windows-installer, unzip the php_gd2.dll to C:\PHP (this is the default install dir) and uncomment 'extension=php_gd2.dll' in C:\WINNT\php.ini (or where ever your os is installed)
\n"; print "
\n"; print "
\n"; print "The author of php-barcode will give not support on this topic!
\n"; print "
\n"; print "
\n"; print "Folke Ashberg's OpenSource PHP-Barcode
\n"; return ""; } $im=imagecreate($total_x, $total_y); /* create two images */ $col_bg=ImageColorAllocate($im,$bg_color[0],$bg_color[1],$bg_color[2]); $col_bar=ImageColorAllocate($im,$bar_color[0],$bar_color[1],$bar_color[2]); $col_text=ImageColorAllocate($im,$text_color[0],$text_color[1],$text_color[2]); $height=round($total_y-($scale*10)); $height2=round($total_y-$space['bottom']); /* paint the bars */ $width=true; for ($i=0;$i:: ...) * bars : where to place the bars (...) */ function barcode_outtext($code,$bars){ $width=true; $xpos=$heigh2=0; $bar_line=""; for ($i=0;$i:: ...) * bars : where to place the bars (...) * scale : scale factor ( 1 < scale < unlimited (scale 50 will produce * 5400x300 pixels when * using EAN-13!!!)) * total_y: the total height of the image ( default: scale * 60 ) * space : space * default: * $space[top] = 2 * $scale; * $space[bottom]= 2 * $scale; * $space[left] = 2 * $scale; * $space[right] = 2 * $scale; */ function barcode_outhtml($code, $bars, $scale = 1, $total_y = 0, $space = ''){ /* set defaults */ $total_y=(int)($total_y); if ($scale<1) $scale=2; if ($total_y<1) $total_y=(int)$scale * 60; if (!$space) $space=array('top'=>2*$scale,'bottom'=>2*$scale,'left'=>2*$scale,'right'=>2*$scale); /* generate html-code */ $height=round($total_y-($scale*10)); $height2=round($total_y)-$space['bottom']; $out= ''."\n". ''."\n". ''."\n". ''."\n". '
'."\n". ''; $width=true; for ($i=0;$i0) $out.=""; $width=false; continue; } if (ereg("[a-z]", $val)){ //hoher strich $val=ord($val)-ord('a')+1; $h=$height2; }else $h=$height; $w=$val*$scale; if ($w>0) $out.=''; $width=true; } $out.= ''. '
'."\n"; //for ($i=0;$i".$line[$i+1]." "; return $out; } /* barcode_encode_genbarcode(code, encoding) * encodes $code with $encoding using genbarcode * * return: * array[encoding] : the encoding which has been used * array[bars] : the bars * array[text] : text-positioning info */ function barcode_encode_genbarcode($code,$encoding){ global $genbarcode_loc; /* delete EAN-13 checksum */ if (eregi("^ean$", $encoding) && strlen($code)==13) $code=substr($code,0,12); if (!$encoding) $encoding="ANY"; $encoding=ereg_replace("[|\\]", "_", $encoding); $code=ereg_replace("[|\\]", "_", $code); $cmd=$genbarcode_loc." \"" .str_replace("\"", "\\\"",$code)."\" \"" .str_replace("\"", "\\\"",strtoupper($encoding))."\""; //print "'$cmd'
\n"; $fp=popen($cmd, "r"); if ($fp){ $bars=fgets($fp, 1024); $text=fgets($fp, 1024); $encoding=fgets($fp, 1024); pclose($fp); } else return false; $ret=array( "encoding" => trim($encoding), "bars" => trim($bars), "text" => trim($text) ); if (!$ret['encoding']) return false; if (!$ret['bars']) return false; if (!$ret['text']) return false; return $ret; } /* barcode_encode(code, encoding) * encodes $code with $encoding using genbarcode OR built-in encoder * if you don't have genbarcode only EAN-13/ISBN is possible * * You can use the following encodings (when you have genbarcode): * ANY choose best-fit (default) * EAN 8 or 13 EAN-Code * UPC 12-digit EAN * ISBN isbn numbers (still EAN-13) * 39 code 39 * 128 code 128 (a,b,c: autoselection) * 128C code 128 (compact form for digits) * 128B code 128, full printable ascii * I25 interleaved 2 of 5 (only digits) * 128RAW Raw code 128 (by Leonid A. Broukhis) * CBR Codabar (by Leonid A. Broukhis) * MSI MSI (by Leonid A. Broukhis) * PLS Plessey (by Leonid A. Broukhis) * * return: * array[encoding] : the encoding which has been used * array[bars] : the bars * array[text] : text-positioning info */ function barcode_encode($code,$encoding){ global $genbarcode_loc; if ( ((eregi("^ean$", $encoding) && ( strlen($code)==12 || strlen($code)==13))) || (($encoding) && (eregi("^isbn$", $encoding)) && (( strlen($code)==9 || strlen($code)==10) || (((ereg("^978", $code) && strlen($code)==12) || (strlen($code)==13))))) || (( !isset($encoding) || !$encoding || (eregi("^ANY$", $encoding) )) && (ereg("^[0-9]{12,13}$", $code))) ){ /* use built-in EAN-Encoder */ $bars=barcode_encode_ean($code, $encoding); } else if (file_exists($genbarcode_loc)){ /* use genbarcode */ $bars=barcode_encode_genbarcode($code, $encoding); } else { print "php-barcode needs an external programm for encodings other then EAN/ISBN
\n"; print "
    \n"; print "
  • download gnu-barcode from www.gnu.org/software/barcode/\n"; print "
  • compile and install them\n"; print "
  • download genbarcode from www.ashberg.de/bar/\n"; print "
  • compile and install them\n"; print "
  • specify path the genbarcode in php-barcode.php\n"; print "
\n"; print "
\n"; print "Folke Ashberg's OpenSource PHP-Barcode
\n"; return false; } return $bars; } /* barcode_print(code [, encoding [, scale [, mode ]]] ); * * encodes and prints a barcode * * return: * array[encoding] : the encoding which has been used * array[bars] : the bars * array[text] : text-positioning info */ function barcode_print($code, $encoding="ANY", $scale = 2 ,$mode = "png", $filename='' ){ $bars=barcode_encode($code,$encoding); if (!$bars) return; if (!$mode) $mode="png"; if (eregi($mode,"^(text|txt|plain)$")) print barcode_outtext($bars['text'],$bars['bars']); elseif (eregi($mode,"^(html|htm)$")) print barcode_outhtml($bars['text'],$bars['bars'], $scale,0, 0); else barcode_outimage($bars['text'],$bars['bars'],$scale, $mode, 0, '', $filename); return $bars; } ?> // WWW: http://dev.e-taller.net/dbtree/ // Category: Databases // Description: PHP class implementing a Nested Sets approach to storing // tree-like structures in database tables. This technique was // introduced by Joe Celko and has some // advantages over a widely used method called Adjacency Matrix. //**************************************************************************** // The lib is FREEWARE. This means you may use it anywhere you want, you may // do anything with it. The Author mentioned above is NOT responsible for any // consequences of using this library. // If you don't agree with this, you MAY NOT use the lib! //**************************************************************************** // All improvings, feature requests, bug reports, etc. are gladly accepted. //**************************************************************************** // SAMPLE DB TABLE STRUCTURE: // // CREATE TABLE categories ( // cat_id INT UNSIGNED NOT NULL AUTO_INCREMENT, // cat_left INT UNSIGNED NOT NULL, // cat_right INT UNSIGNED NOT NULL, // cat_level INT UNSIGNED NOT NULL, // PRIMARY KEY(cat_id), // KEY(cat_left, cat_right, cat_level) // ); // // This is believed to be the optimal Nested Sets use case. Use `one-to-one` // relations on `cat_id` field between this `structure` table and // another `data` table in your database. // //**************************************************************************** // NOTE: Although you may use this library to retrieve data from the table, // it is recommended to write your own queries to do that. // The main purpose of the library is to provide a simpler way to // create, update and delete records. Not to SELECT them. //**************************************************************************** // // IMPORTANT! DO NOT create either UNIQUE or PRIMARY keys on the set of // fields (`cat_left`, `cat_right` and `cat_level`)! // Unique keys will destroy the Nested Sets structure! // //**************************************************************************** // CHANGELOG: // 16-Apr-2003 -=- 1.1 // - Added moveAll() method // - Added fourth parameter to the constructor // - Renamed getElementInfo() to getNodeInfo() /keeping BC/ // - Added "Sample Table Structure" comment // - Now it die()'s in case of any serious error, because if not you // will lose the Nested Sets structure in your table //**************************************************************************** // Note: For best viewing of the code Tab size 4 is recommended //**************************************************************************** class CDBTree { var $db; // CDatabase class to plug to var $table; // Table with Nested Sets implemented var $id; // Name of the ID-auto_increment-field in the table. // These 3 variables are names of fields which are needed to implement // Nested Sets. All 3 fields should exist in your table! // However, you may want to change their names here to avoid name collisions. var $left = 'cat_left'; var $right = 'cat_right'; var $level = 'cat_level'; var $qryParams = ''; var $qryFields = ''; var $qryTables = ''; var $qryWhere = ''; var $qryGroupBy = ''; var $qryHaving = ''; var $qryOrderBy = ''; var $qryLimit = ''; var $sqlNeedReset = true; var $sql; // Last SQL query //************************************************************************ // Constructor // $DB : CDatabase class instance to link to // $tableName : table in database where to implement nested sets // $itemId : name of the field which will uniquely identify every record // $fieldNames : optional configuration array to set field names. Example: // array( // 'left' => 'cat_left', // 'right' => 'cat_right', // 'level' => 'cat_level' // ) function CDBTree(&$DB, $tableName, $itemId, $fieldNames=array()) { if((empty($tableName)) || (empty($itemId))) die("phpDbTree error: ".$this->db->error()); $this->db = $DB; $this->db->show_query='off'; $this->table = $tableName; $this->id = $itemId; if(is_array($fieldNames) && sizeof($fieldNames)) foreach($fieldNames as $k => $v) $this->$k = $v; } //************************************************************************ // Returns a Left and Right IDs and Level of an element or false on error // $ID : an ID of the element function getElementInfo($ID) { return $this->getNodeInfo($ID); } function getNodeInfo($ID) { $this->sql = 'SELECT '.$this->left.','.$this->right.','.$this->level.' FROM '.$this->table.' WHERE '.$this->id.'=\''.$ID.'\''; if(($query=$this->db->query($this->sql)) && ($this->db->num_rows($query) == 1) && ($Data = $this->db->fetch_array($query))) return array((int)$Data[$this->left], (int)$Data[$this->right], (int)$Data[$this->level]); else die("phpDbTree error: ".$this->db->error()); } //************************************************************************ // Clears table and creates 'root' node // $data : optional argument with data for the root node function clear($data=array()) { // clearing table if((!$this->db->query('TRUNCATE '.$this->table)) && (!$this->db->query('DELETE FROM '.$this->table))) die("phpDbTree error: ".$this->db->error()); // preparing data to be inserted $data[$this->left]="1"; $data[$this->right]="2"; $data[$this->level]="0"; // inserting new record return $this->db->add_field($this->table,$data); } //************************************************************************ // Updates a record // $ID : element ID // $data : array with data to update: array( => ) function update($ID, $data) { $sql_set = ''; foreach($data as $k=>$v) $sql_set .= ','.$k.'=\''.addslashes($v).'\''; return $this->db->query('UPDATE '.$this->table.' SET '.substr($sql_set,1).' WHERE '.$this->id.'=\''.$ID.'\''); } //************************************************************************ // Inserts a record into the table with nested sets // $ID : an ID of the parent element // $data : array with data to be inserted: array( => ) // Returns : true on success, or false on error function insert($ID, $data) { if(!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) die("phpDbTree error: ".$this->db->error()); // preparing data to be inserted if(sizeof($data)) { $fld_names = implode(',', array_keys($data)).','; $fld_values = '\''.implode('\',\'', array_values($data)).'\','; } $fld_names .= $this->left.','.$this->right.','.$this->level; $fld_values .= ($rightId).','.($rightId+1).','.($level+1); // creating a place for the record being inserted if($ID) { $this->sql = 'UPDATE IGNORE '.$this->table.' SET ' . $this->left.'=IF('.$this->left.'>'.$rightId.','.$this->left.'+2,'.$this->left.'),' . $this->right.'=IF('.$this->right.'>='.$rightId.','.$this->right.'+2,'.$this->right.')' . 'WHERE '.$this->right.'>='.$rightId; if(!($this->db->query($this->sql))) die("phpDbTree error: ".$this->db->error()); } // inserting new record $this->sql = 'INSERT INTO '.$this->table.'('.$fld_names.') VALUES('.$fld_values.')'; if(!($this->db->query($this->sql))) die("phpDbTree error: ".$this->db->error()); return $this->db->insert_id(); } function reorderAll($nodeID, $afterID){ // Помещает узел $nodeID после $afterID if(!(list($nleftId, $nrightId, $nlevel) = $this->getNodeInfo($nodeID))) die("phpDbTree error: ".$this->db->error()); if(!(list($aleftId, $arightId, $alevel) = $this->getNodeInfo($afterID))) die("phpDbTree error: ".$this->db->error()); $deltaB=($nrightId-$nleftId)+1; $deltaA=""; // "-" - элемент идет вверх; "+" - вниз if ($nleftId<($arightId+1)) { $deltaB=-$deltaB; $deltaA=$arightId-$nrightId; $minleftId=$nleftId;} else $minleftId=$arightId+1; if ($nrightId>($arightId+1)) { $deltaA=($arightId+1)-$nleftId; $maxrightId=$nrightId; } else $maxrightId=($arightId+1); $nodeInfo=$this->db->arAll("SELECT id FROM ". $this->table ." WHERE cat_left>='".$nleftId. "' AND cat_right<='".$nrightId."'"); /* echo "nleftId, nrightId, nlevel ==>" . $nleftId . ":" . $nrightId . ":" . $nlevel . "
"; echo "aleftId, arightId, alevel ==>" . $aleftId . ":" . $arightId . ":" . $alevel . "
"; echo "deltaA:" . $deltaA . " deltaB:" . $deltaB; echo "
"; echo "minleftId:" . $minleftId; echo "
"; echo "maxrightId:" . $maxrightId; echo "
"; */ // обработка текущего элемента if($nodeInfo) { $this->sql = 'UPDATE '.$this->table.' SET ' . $this->left.'='.$this->left.'+('.$deltaA.'), ' . $this->right.'='.$this->right.'+('.$deltaA.') ' . 'WHERE '.$this->right.'<='.$nrightId.' AND ' . $this->left . '>=' . $nleftId; // echo $this->sql; if(!($this->db->query($this->sql))) die("phpDbTree error: ".$this->db->error()); } // echo "
"; foreach ($nodeInfo as $nodeID){ $c++; $set.="`id`<>" . $nodeID[id]; if (count($nodeInfo)!=$c) $set.=" AND "; // Если не конец массива, то ставим запятые } $this->sql = 'UPDATE '.$this->table.' SET ' . $this->left.'='.$this->left.'+('.$deltaB.'), ' . $this->right.'='.$this->right.'+('.$deltaB.') ' . 'WHERE '.$this->right.'<='.$maxrightId.' AND ' . $this->left . '>=' . $minleftId . ' AND ('.$set.')'; // echo $this->sql; if(!($this->db->query($this->sql))) die("phpDbTree error: ".$this->db->error()); } //************************************************************************ // Assigns a node with all its children to another parent // $ID : node ID // $newParentID : ID of new parent node // Returns : false on error function moveAll($ID, $newParentId) { if(!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) die("phpDbTree error: ".$this->db->error()); if(!(list($leftIdP, $rightIdP, $levelP) = $this->getNodeInfo($newParentId))) die("phpDbTree error: ".$this->db->error()); if($ID == $newParentId || $leftId == $leftIdP || ($leftIdP >= $leftId && $leftIdP <= $rightId)) return false; if($leftIdP < $leftId) { $this->sql = 'UPDATE '.$this->table.' SET ' . $this->level.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->level.sprintf('%+d', -($level-1)+$levelP).', '.$this->level.'), ' . $this->left.'=IF('.$this->left.' BETWEEN '.$rightIdP.' AND '.($leftId-1).', '.$this->left.'+'.($rightId-$leftId+1).', ' . 'IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->left.'-'.($leftId-$rightIdP).', '.$this->left.') ' . '), ' . $this->right.'=IF('.$this->right.' BETWEEN '.$rightIdP.' AND '.$leftId.', '.$this->right.'+'.($rightId-$leftId+1).', ' . 'IF('.$this->right.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->right.'-'.($leftId-$rightIdP).', '.$this->right.') ' . ') ' . 'WHERE '.$this->left.' BETWEEN '.$leftIdP.' AND '.$rightId ; } else { $this->sql = 'UPDATE '.$this->table.' SET ' . $this->level.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->level.sprintf('%+d', -($level-1)+$levelP).', '.$this->level.'), ' . $this->left.'=IF('.$this->left.' BETWEEN '.$rightId.' AND '.$rightIdP.', '.$this->left.'-'.($rightId-$leftId+1).', ' . 'IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->left.'+'.($rightIdP-1-$rightId).', '.$this->left.')' . '), ' . $this->right.'=IF('.$this->right.' BETWEEN '.($rightId+1).' AND '.($rightIdP-1).', '.$this->right.'-'.($rightId-$leftId+1).', ' . 'IF('.$this->right.' BETWEEN '.$leftId.' AND '.$rightId.', '.$this->right.'+'.($rightIdP-1-$rightId).', '.$this->right.') ' . ') ' . 'WHERE '.$this->left.' BETWEEN '.$leftId.' AND '.$rightIdP ; } return $this->db->query($this->sql) or die("phpDbTree error: ".$this->db->error()); } //************************************************************************ // Deletes a record wihtout deleting its children // $ID : an ID of the element to be deleted // Returns : true on success, or false on error function delete($ID) { if(!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) die("phpDbTree error: ".$this->db->error()); // Deleting record $this->sql = 'DELETE FROM '.$this->table.' WHERE '.$this->id.'=\''.$ID.'\''; if(!$this->db->query($this->sql)) die("phpDbTree error: ".$this->db->error()); // Clearing blank spaces in a tree $this->sql = 'UPDATE '.$this->table.' SET ' . $this->left.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.','.$this->left.'-1,'.$this->left.'),' . $this->right.'=IF('.$this->right.' BETWEEN '.$leftId.' AND '.$rightId.','.$this->right.'-1,'.$this->right.'),' . $this->level.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.','.$this->level.'-1,'.$this->level.'),' . $this->left.'=IF('.$this->left.'>'.$rightId.','.$this->left.'-2,'.$this->left.'),' . $this->right.'=IF('.$this->right.'>'.$rightId.','.$this->right.'-2,'.$this->right.') ' . 'WHERE '.$this->right.'>'.$leftId ; if(!$this->db->query($this->sql)) die("phpDbTree error: ".$this->db->error()); return true; } //************************************************************************ // Deletes a record with all its children // $ID : an ID of the element to be deleted // Returns : true on success, or false on error function deleteAll($ID) { if(!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) die("phpDbTree error: ".$this->db->error()); // Deleteing record(s) $this->sql = 'DELETE FROM '.$this->table.' WHERE '.$this->left.' BETWEEN '.$leftId.' AND '.$rightId; if(!$this->db->query($this->sql)) die("phpDbTree error: ".$this->db->error()); // Clearing blank spaces in a tree $deltaId = ($rightId - $leftId)+1; $this->sql = 'UPDATE '.$this->table.' SET ' . $this->left.'=IF('.$this->left.'>'.$leftId.','.$this->left.'-'.$deltaId.','.$this->left.'),' . $this->right.'=IF('.$this->right.'>'.$leftId.','.$this->right.'-'.$deltaId.','.$this->right.') ' . 'WHERE '.$this->right.'>'.$rightId ; if(!$this->db->query($this->sql)) die("phpDbTree error: ".$this->db->error()); return true; } //************************************************************************ // Enumerates children of an element // $ID : an ID of an element which children to be enumerated // $start_level : relative level from which start to enumerate children // $end_level : the last relative level at which enumerate children // 1. If $end_level isn't given, only children of // $start_level levels are enumerated // 2. Level values should always be greater than zero. // Level 1 means direct children of the element // Returns : a result id for using with other DB functions function enumChildrenAll($ID) { return $this->enumChildren($ID, 1, 0); } function enumChildren($ID, $start_level=1, $end_level=1) { if($start_level < 0) die("phpDbTree error: ".$this->db->error()); // We could use sprintf() here, but it'd be too slow $whereSql1 = ' AND '.$this->table.'.'.$this->level; $whereSql2 = '_'.$this->table.'.'.$this->level.'+'; if(!$end_level) $whereSql = $whereSql1.'>='.$whereSql2.(int)$start_level; else { $whereSql = ($end_level <= $start_level) ? $whereSql1.'='.$whereSql2.(int)$start_level : ' AND '.$this->table.'.'.$this->level.' BETWEEN _'.$this->table.'.'.$this->level.'+'.(int)$start_level .' AND _'.$this->table.'.'.$this->level.'+'.(int)$end_level; } $this->sql = $this->sqlComposeSelect(array( '', // Params '', // Fields $this->table.' _'.$this->table.', '.$this->table, // Tables '_'.$this->table.'.'.$this->id.'=\''.$ID.'\'' .' AND '.$this->table.'.'.$this->left.' BETWEEN _'.$this->table.'.'.$this->left.' AND _'.$this->table.'.'.$this->right .$whereSql )); return $this->db->arAll($this->sql); } //************************************************************************ // Enumerates the PATH from an element to its top level parent // $ID : an ID of an element // $showRoot : whether to show root node in a path // Returns : a result id for using with other DB functions // Одномерный массив родителей элемента function enumPath($ID, $showRoot=false) { $this->sql = $this->sqlComposeSelect(array( '', // Params '', // Fields $this->table.' _'.$this->table.', '.$this->table, // Tables '_'.$this->table.'.'.$this->id.'=\''.$ID.'\'' .' AND _'.$this->table.'.'.$this->left.' BETWEEN '.$this->table.'.'.$this->left.' AND '.$this->table.'.'.$this->right .(($showRoot) ? '' : ' AND '.$this->table.'.'.$this->level.'>0'), // Where '', // GroupBy '', // Having $this->table.'.'.$this->left // OrderBy )); return $this->db->query($this->sql); } //************************************************************************ // Returns query result to fetch data of the element's parent // $ID : an ID of an element which parent to be retrieved // $level : Relative level of parent // Returns : a result id for using with other DB functions function getParent($ID, $level=1) { if($level < 1) die("phpDbTree error: ".$this->db->error()); $this->sql = $this->sqlComposeSelect(array( '', // Params '', // Fields $this->table.' _'.$this->table.', '.$this->table, // Tables '_'.$this->table.'.'.$this->id.'=\''.$ID.'\'' .' AND _'.$this->table.'.'.$this->left.' BETWEEN '.$this->table.'.'.$this->left.' AND '.$this->table.'.'.$this->right .' AND '.$this->table.'.'.$this->level.'=_'.$this->table.'.'.$this->level.'-'.(int)$level // Where )); return $this->db->r($this->sql); } //************************************************************************ function sqlReset() { $this->qryParams = ''; $this->qryFields = ''; $this->qryTables = ''; $this->qryWhere = ''; $this->qryGroupBy = ''; $this->qryHaving = ''; $this->qryOrderBy = ''; $this->qryLimit = ''; return true; } //************************************************************************ function sqlSetReset($resetMode) { $this->sqlNeedReset = ($resetMode) ? true : false; } //************************************************************************ function sqlParams($param='') { return (empty($param)) ? $this->qryParams : $this->qryParams = $param; } function sqlFields($param='') { return (empty($param)) ? $this->qryFields : $this->qryFields = $param; } function sqlSelect($param='') { return $this->sqlFields($param); } function sqlTables($param='') { return (empty($param)) ? $this->qryTables : $this->qryTables = $param; } function sqlFrom($param='') { return $this->sqlTables($param); } function sqlWhere($param='') { return (empty($param)) ? $this->qryWhere : $this->qryWhere = $param; } function sqlGroupBy($param='') { return (empty($param)) ? $this->qryGroupBy : $this->qryGroupBy = $param; } function sqlHaving($param='') { return (empty($param)) ? $this->qryHaving : $this->qryHaving = $param; } function sqlOrderBy($param='') { return (empty($param)) ? $this->qryOrderBy : $this->qryOrderBy = $param; } function sqlLimit($param='') { return (empty($param)) ? $this->qryLimit : $this->qryLimit = $param; } //************************************************************************ function sqlComposeSelect($arSql) { $joinTypes = array('join'=>1, 'cross'=>1, 'inner'=>1, 'straight'=>1, 'left'=>1, 'natural'=>1, 'right'=>1); $this->sql = 'SELECT '.$arSql[0].' '; if(!empty($this->qryParams)) $this->sql .= $this->sqlParams.' '; if(empty($arSql[1]) && empty($this->qryFields)) $this->sql .= $this->table.'.'.$this->id; else { if(!empty($arSql[1])) $this->sql .= $arSql[1]; if(!empty($this->qryFields)) $this->sql .= ((empty($arSql[1])) ? '' : ',') . $this->qryFields; } $this->sql .= ' FROM '; $isJoin = ($tblAr=explode(' ',trim($this->qryTables))) && ($joinTypes[strtolower($tblAr[0])]); if(empty($arSql[2]) && empty($this->qryTables)) $this->sql .= $this->table; else { if(!empty($arSql[2])) $this->sql .= $arSql[2]; if(!empty($this->qryTables)) { if(!empty($arSql[2])) $this->sql .= (($isJoin)?' ':','); elseif($isJoin) $this->sql .= $this->table.' '; $this->sql .= $this->qryTables; } } if((!empty($arSql[3])) || (!empty($this->qryWhere))) { $this->sql .= ' WHERE ' . $arSql[3] . ' '; if(!empty($this->qryWhere)) $this->sql .= (empty($arSql[3])) ? $this->qryWhere : 'AND('.$this->qryWhere.')'; } if((!empty($arSql[4])) || (!empty($this->qryGroupBy))) { $this->sql .= ' GROUP BY ' . $arSql[4] . ' '; if(!empty($this->qryGroupBy)) $this->sql .= (empty($arSql[4])) ? $this->qryGroupBy : ','.$this->qryGroupBy; } if((!empty($arSql[5])) || (!empty($this->qryHaving))) { $this->sql .= ' HAVING ' . $arSql[5] . ' '; if(!empty($this->qryHaving)) $this->sql .= (empty($arSql[5])) ? $this->qryHaving : 'AND('.$this->qryHaving.')'; } if((!empty($arSql[6])) || (!empty($this->qryOrderBy))) { $this->sql .= ' ORDER BY ' . $arSql[6] . ' '; if(!empty($this->qryOrderBy)) $this->sql .= (empty($arSql[6])) ? $this->qryOrderBy : ','.$this->qryOrderBy; } if(!empty($arSql[7])) $this->sql .= ' LIMIT '.$arSql[7]; elseif(!empty($this->qryLimit)) $this->sql .= ' LIMIT '.$this->qryLimit; if($this->sqlNeedReset) $this->sqlReset(); return $this->sql; } //************************************************************************ function defaultLang($lang_id=''){ if (!$lang_id) $lang_id=$this->db->r("SELECT id FROM lang WHERE `default`='y'"); else $lang_id=$lang_id; } function orderBy($id){ $orderby=$this->db->r("SELECT CONCAT(orderbynames.orderby,\" \",orderby.direction) FROM orderby, orderbynames WHERE section_id='".$id."' AND orderby_id=orderbynames.id"); if ($orderby) return $orderby . ", "; } function ParentsWithNodeListing($id, $lang_id=''){ // Выдает листинг дерева с открытой веткой $this->defaultLang(&$lang_id); $q="SELECT N.name, N.keywords, N.description, A. * , IF ( A.cat_left + 1 < A.cat_right, 1, 0 ) AS nflag FROM ".$this->table." A, ".$this->table." B, names as N WHERE B.id = '".$id."' AND ( ( B.cat_left BETWEEN A.cat_left AND A.cat_right ) OR ( ( A.cat_left BETWEEN B.cat_left AND B.cat_right ) AND A.cat_level = B.cat_level + 1 ) ) AND N.section_id = A.id AND N.lang_id = '".$lang_id."' ORDER BY A.cat_left"; return $this->db->arAll($q); } function ShowHoleTree($lang_id=''){ // Листинг всего дерева $this->defaultLang(&$lang_id); $q="SELECT N.name, N.keywords, N.description, A. * , IF ( A.cat_left + 1 < A.cat_right, 1, 0 ) AS nflag FROM ".$this->table." A, names as N WHERE N.section_id = A.id AND N.lang_id = '".$lang_id."' ORDER BY A.cat_left"; return $this->db->arAll($q); } function GetAllSectionInfo($id, $lang_id=''){ // Выдает всю информацию об элементе $this->defaultLang(&$lang_id); $q="SELECT N.name, N.keywords, N.description, A. * , IF ( A.cat_left + 1 < A.cat_right, 1, 0 ) AS nflag FROM ".$this->table." A, names as N WHERE A.id = '".$id."' AND N.section_id = A.id AND N.lang_id = '".$lang_id."'"; return $this->db->assoc($q); } function ParentsListing($id, $lang_id='',$hidden='n'){ // Выдает листинг родилей элемента $this->defaultLang(&$lang_id); $q="SELECT N.name, N.keywords, N.description, A. * , IF ( A.cat_left + 1 < A.cat_right, 1, 0 ) AS nflag FROM ".$this->table." A, ".$this->table." B, names as N WHERE B.id = '".$id."' AND ( B.cat_left BETWEEN A.cat_left AND A.cat_right ) AND N.section_id = A.id AND N.lang_id = '".$lang_id."' ORDER BY A.cat_left"; return $this->db->arAll($q); } function findByMnemo($mnemo, $cat_left, $cat_right, $level, $lang_id='',$hidden='AND A.hidden=\'n\''){ $this->defaultLang(&$lang_id); $q="SELECT N.name, N.keywords, N.description, A. * , IF ( A.cat_left + 1 < A.cat_right, 1, 0 ) AS nflag FROM ".$this->table." A, names as N WHERE A.mnemo = '".ereg_replace('[[:space:]]+','',$mnemo)."' AND ( A.cat_left > ".$cat_left." AND A.cat_right < ".$cat_right.") AND A.cat_level='".$level."' AND N.section_id = A.id AND N.lang_id = '".$lang_id."' ".$hidden." ORDER BY A.cat_left"; return $this->db->assoc($q); } function ChildrenListing($id, $lang_id='', $with_node="AND A.id <> B.id",$hidden='AND A.hidden=\'n\'', $limit=''){ // Выдает листинг детей элемента $this->defaultLang(&$lang_id); $q="SELECT N.name, N.keywords, N.description, A. * , IF ( A.cat_left + 1 < A.cat_right, 1, 0 ) AS nflag FROM ".$this->table." A, ".$this->table." B, names as N WHERE B.id = '".$id."' AND A.cat_left BETWEEN B.cat_left AND B.cat_right ".$with_node." AND N.section_id = A.id AND N.lang_id = '".$lang_id."' ".$hidden." ORDER BY ".$this->orderBy($id)." A.cat_left " . $limit; return $this->db->arAll($q); } function ChildrenListingCount($id, $lang_id='',$hidden='AND A.hidden=\'n\''){ // Выдает общее количество детей элемента $this->defaultLang(&$lang_id); $q="SELECT count(A.id) FROM ".$this->table." A, ".$this->table." B, names as N WHERE B.id = '".$id."' AND A.cat_left BETWEEN B.cat_left AND B.cat_right AND A.id <> B.id AND N.section_id = A.id AND N.lang_id = '".$lang_id."' ".$hidden." ORDER BY A.cat_left"; return $this->db->r($q); } function ChildrenListingCurrentNode($id, $lang_id='',$hidden='AND A.hidden=\'n\'', $limit=''){ // Выдает листинг детей элемента без открытия веток детей $this->defaultLang(&$lang_id); if (!$_SESSION[user] && !$_SESSION[zuser]) $registered=" AND A.for_registered<>'y'"; $q="SELECT N.name, N.keywords, N.description, A. * , IF ( A.cat_left + 1 < A.cat_right, 1, 0 ) AS nflag FROM ".$this->table." A, ".$this->table." B, names as N WHERE B.id = '".$id."' AND A.cat_left BETWEEN B.cat_left AND B.cat_right AND A.id <> B.id AND N.section_id = A.id AND A.cat_level = B.cat_level + 1 AND N.lang_id = '".$lang_id."' ".$hidden." ".$registered." ORDER BY ".$this->orderBy($id)." A.cat_left " . $limit; return $this->db->arAll($q); } function ChildrenListingCurrentNodeCount($id, $lang_id='',$hidden='AND A.hidden=\'n\''){ // Выдает общее количество детей элемента без открытия веток детей $this->defaultLang(&$lang_id); if (!$_SESSION[user] && !$_SESSION[zuser]) $registered=" AND A.for_registered<>'y'"; $q="SELECT SUM(1) FROM ".$this->table." A, ".$this->table." B, names as N WHERE B.id = '".$id."' AND A.cat_left BETWEEN B.cat_left AND B.cat_right AND A.id <> B.id AND N.section_id = A.id AND A.cat_level = B.cat_level + 1 AND N.lang_id = '".$lang_id."' ".$hidden." ".$registered; return $this->db->r($q); } function NodeDropDown($nodeID, $name,$field='',$field_value='', $value_num=1, $content_num=0, $submit='n',$highlight_arr=array(),$additional_arr=array()){ // Выпадающее меню // field и field_value - переменные для отматывания на какой-то пукт меню // name - имя переменной селекта // value_num - номер столбца в выборке, кот. подставляется в value // content_num - видимая часть селекта // submit - при изменении выбора в select'е форма обновляется // highlight_arr - подсветка определенных пунктов цветом highlight // additional_arr - дополнительные значения $result=$this->ChildrenListingCurrentNode($nodeID); if ($submit=='y') $onevent=" onChange=\"javascript:submit();\""; $res="\r\n" . '' . "\r\n"; return $res; } function isNode($id, $hidden='AND A.hidden<>\'y\''){ // узел или лист (имеет ли наследников, или нет). 1 - узел, 0 - лист return ($this->db->r("SELECT IF ( A.cat_left + 1 < A.cat_right, 1, 0 ) AS nflag FROM ".$this->table." A, ".$this->table." WHERE A.id = '".$id."' ".$hidden)); } } ?>