Changeset 402 for trunk


Ignore:
Timestamp:
Mar 30, 2004, 12:40:21 AM (20 years ago)
Author:
z0rglub
Message:

code refactoring

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/identification.php

    r393 r402  
    2626// +-----------------------------------------------------------------------+
    2727
    28 //----------------------------------------------------------- include
     28//--------------------------------------------------------------------- include
    2929define('PHPWG_ROOT_PATH','./');
    3030include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
     
    4343    $session_id = session_create( $_POST['username'] );
    4444    $url = 'category.php?id='.$session_id;
     45    redirect( $url );
    4546    header( 'Request-URI: '.$url );
    4647    header( 'Content-Location: '.$url ); 
     
    6263$template->set_filenames( array('identification'=>'identification.tpl') );
    6364
    64 $template->assign_vars(array(
    65   'MAIL_ADMIN' => $conf['mail_webmaster'],
    66 
    67   'L_TITLE' => $lang['ident_title'],
    68   'L_USERNAME' => $lang['login'],
    69   'L_PASSWORD' => $lang['password'],
    70   'L_LOGIN' => $lang['submit'],
    71   'L_GUEST' => $lang['ident_guest_visit'],
    72   'L_REGISTER' => $lang['ident_register'],
    73   'L_FORGET' => $lang['ident_forgotten_password'],
    74  
    75   'T_STYLE' => $user['template'],
    76  
    77   'F_LOGIN_ACTION' => add_session_id('identification.php')
    78   ));
    79 
     65$template->assign_vars(
     66  array(
     67    'MAIL_ADMIN' => $conf['mail_webmaster'],
     68   
     69    'L_TITLE' => $lang['ident_title'],
     70    'L_USERNAME' => $lang['login'],
     71    'L_PASSWORD' => $lang['password'],
     72    'L_LOGIN' => $lang['submit'],
     73    'L_GUEST' => $lang['ident_guest_visit'],
     74    'L_REGISTER' => $lang['ident_register'],
     75    'L_FORGET' => $lang['ident_forgotten_password'],
     76   
     77    'T_STYLE' => $user['template'],
     78   
     79    'F_LOGIN_ACTION' => add_session_id('identification.php')
     80    ));
    8081//-------------------------------------------------------------- errors display
    8182if ( sizeof( $errors ) != 0 )
  • trunk/include/template.php

    r362 r402  
    2727
    2828/**
    29  * Template class. By Nathan Codding of the phpBB group.
    30  * The interface was originally inspired by PHPLib templates,
    31  * and the template file formats are quite similar.
    32  *
     29 * Template class. By Nathan Codding of the phpBB group. The interface was
     30 * originally inspired by PHPLib templates, and the template file formats
     31 * are quite similar.
    3332 */
    3433
    3534class Template {
    36         var $classname = "Template";
    37 
    38         // variable that holds all the data we'll be substituting into
    39         // the compiled templates.
    40         // ...
    41         // This will end up being a multi-dimensional array like this:
    42         // $this->_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value
    43         // if it's a root-level variable, it'll be like this:
    44         // $this->_tpldata[.][0][varname] == value
    45         var $_tpldata = array();
    46 
    47         // Hash of filenames for each template handle.
    48         var $files = array();
    49 
    50         // Root template directory.
    51         var $root = "";
    52 
    53         // this will hash handle names to the compiled code for that handle.
    54         var $compiled_code = array();
    55 
    56         // This will hold the uncompiled code for that handle.
    57         var $uncompiled_code = array();
    58 
    59         /**
    60          * Constructor. Simply sets the root dir.
    61          *
    62          */
    63         function Template($root = ".")
    64         {
    65                 $this->set_rootdir($root);
    66         }
    67 
    68         /**
    69          * Destroys this template object. Should be called when you're done with it, in order
    70          * to clear out the template data so you can load/parse a new template set.
    71          */
    72         function destroy()
    73         {
    74                 $this->_tpldata = array();
    75         }
    76 
    77         /**
    78          * Sets the template root directory for this Template object.
    79          */
    80         function set_rootdir($dir)
    81         {
    82                 if (!is_dir($dir))
    83                 {
    84                         return false;
    85                 }
    86 
    87                 $this->root = $dir;
    88                 return true;
    89         }
    90 
    91         /**
    92          * Sets the template filenames for handles. $filename_array
    93          * should be a hash of handle => filename pairs.
    94          */
    95         function set_filenames($filename_array)
    96         {
    97                 if (!is_array($filename_array))
    98                 {
    99                         return false;
    100                 }
    101 
    102                 reset($filename_array);
    103                 while(list($handle, $filename) = each($filename_array))
    104                 {
    105                         $this->files[$handle] = $this->make_filename($filename);
    106                 }
    107 
    108                 return true;
    109         }
    110 
    111 
    112         /**
    113          * Load the file for the handle, compile the file,
    114          * and run the compiled code. This will print out
    115          * the results of executing the template.
    116          */
    117         function pparse($handle)
    118         {
    119                 if (!$this->loadfile($handle))
    120                 {
    121                         die("Template->pparse(): Couldn't load template file for handle $handle");
    122                 }
    123 
    124                 // actually compile the template now.
    125                 if (!isset($this->compiled_code[$handle]) || empty($this->compiled_code[$handle]))
    126                 {
    127                         // Actually compile the code now.
    128                         $this->compiled_code[$handle] = $this->compile($this->uncompiled_code[$handle]);
    129                 }
    130 
    131                 // Run the compiled code.
    132                 //echo ("<!-- ".$this->compiled_code[$handle]." -->");
    133                 eval($this->compiled_code[$handle]);
    134                 return true;
    135         }
    136 
    137         /**
    138          * Inserts the uncompiled code for $handle as the
    139          * value of $varname in the root-level. This can be used
    140          * to effectively include a template in the middle of another
    141          * template.
    142          * Note that all desired assignments to the variables in $handle should be done
    143          * BEFORE calling this function.
    144          */
    145         function assign_var_from_handle($varname, $handle)
    146         {
    147                 if (!$this->loadfile($handle))
    148                 {
    149                         die("Template->assign_var_from_handle(): Couldn't load template file for handle $handle");
    150                 }
    151 
    152                 // Compile it, with the "no echo statements" option on.
    153                 $_str = "";
    154                 $code = $this->compile($this->uncompiled_code[$handle], true, '_str');
    155 
    156                 // evaluate the variable assignment.
    157                 eval($code);
    158                 // assign the value of the generated variable to the given varname.
    159                 $this->assign_var($varname, $_str);
    160 
    161                 return true;
    162         }
    163 
    164         /**
    165          * Block-level variable assignment. Adds a new block iteration with the given
    166          * variable assignments. Note that this should only be called once per block
    167          * iteration.
    168          */
    169         function assign_block_vars($blockname, $vararray)
    170         {
    171                 if (strstr($blockname, '.'))
    172                 {
    173                         // Nested block.
    174                         $blocks = explode('.', $blockname);
    175                         $blockcount = sizeof($blocks) - 1;
    176                         $str = '$this->_tpldata';
    177                         for ($i = 0; $i < $blockcount; $i++)
    178                         {
    179                                 $str .= '[\'' . $blocks[$i] . '.\']';
    180                                 eval('$lastiteration = sizeof(' . $str . ') - 1;');
    181                                 $str .= '[' . $lastiteration . ']';
    182                         }
    183                         // Now we add the block that we're actually assigning to.
    184                         // We're adding a new iteration to this block with the given
    185                         // variable assignments.
    186                         $str .= '[\'' . $blocks[$blockcount] . '.\'][] = $vararray;';
    187 
    188                         // Now we evaluate this assignment we've built up.
    189                         eval($str);
    190                 }
    191                 else
    192                 {
    193                         // Top-level block.
    194                         // Add a new iteration to this block with the variable assignments
    195                         // we were given.
    196                         $this->_tpldata[$blockname . '.'][] = $vararray;
    197                 }
    198 
    199                 return true;
    200         }
    201 
    202         /**
    203          * Root-level variable assignment. Adds to current assignments, overriding
    204          * any existing variable assignment with the same name.
    205          */
    206         function assign_vars($vararray)
    207         {
    208                 reset ($vararray);
    209                 while (list($key, $val) = each($vararray))
    210                 {
    211                         $this->_tpldata['.'][0][$key] = $val;
    212                 }
    213 
    214                 return true;
    215         }
    216 
    217         /**
    218          * Root-level variable assignment. Adds to current assignments, overriding
    219          * any existing variable assignment with the same name.
    220          */
    221         function assign_var($varname, $varval)
    222         {
    223                 $this->_tpldata['.'][0][$varname] = $varval;
    224 
    225                 return true;
    226         }
    227 
    228 
    229         /**
    230          * Generates a full path+filename for the given filename, which can either
    231          * be an absolute name, or a name relative to the rootdir for this Template
    232          * object.
    233          */
    234         function make_filename($filename)
    235         {
    236                 // Check if it's an absolute or relative path.
    237                 if (substr($filename, 0, 1) != '/')
    238                 {
    239                 $filename = realpath($this->root . '/' . $filename);
    240                 }
    241 
    242                 if (!file_exists($filename))
    243                 {
    244                         die("Template->make_filename(): Error - file $filename does not exist");
    245                 }
    246 
    247                 return $filename;
    248         }
    249 
    250 
    251         /**
    252          * If not already done, load the file for the given handle and populate
    253          * the uncompiled_code[] hash with its code. Do not compile.
    254          */
    255         function loadfile($handle)
    256         {
    257                 // If the file for this handle is already loaded and compiled, do nothing.
    258                 if (isset($this->uncompiled_code[$handle]) && !empty($this->uncompiled_code[$handle]))
    259                 {
    260                         return true;
    261                 }
    262 
    263                 // If we don't have a file assigned to this handle, die.
    264                 if (!isset($this->files[$handle]))
    265                 {
    266                         die("Template->loadfile(): No file specified for handle $handle");
    267                 }
    268 
    269                 $filename = $this->files[$handle];
    270 
    271                 $str = implode("", @file($filename));
    272                 if (empty($str))
    273                 {
    274                         die("Template->loadfile(): File $filename for handle $handle is empty");
    275                 }
    276 
    277                 $this->uncompiled_code[$handle] = $str;
    278 
    279                 return true;
    280         }
    281 
    282 
    283 
    284         /**
    285          * Compiles the given string of code, and returns
    286          * the result in a string.
    287          * If "do_not_echo" is true, the returned code will not be directly
    288          * executable, but can be used as part of a variable assignment
    289          * for use in assign_code_from_handle().
    290          */
    291         function compile($code, $do_not_echo = false, $retvar = '')
    292         {
    293                 // replace \ with \\ and then ' with \'.
    294                 $code = str_replace('\\', '\\\\', $code);
    295                 $code = str_replace('\'', '\\\'', $code);
    296 
    297                 // change template varrefs into PHP varrefs
    298 
    299                 // This one will handle varrefs WITH namespaces
    300                 $varrefs = array();
    301                 preg_match_all('#\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}#is', $code, $varrefs);
    302                 $varcount = sizeof($varrefs[1]);
    303                 for ($i = 0; $i < $varcount; $i++)
    304                 {
    305                         $namespace = $varrefs[1][$i];
    306                         $varname = $varrefs[3][$i];
    307                         $new = $this->generate_block_varref($namespace, $varname);
    308 
    309                         $code = str_replace($varrefs[0][$i], $new, $code);
    310                 }
    311 
    312                 // This will handle the remaining root-level varrefs
    313                 $code = preg_replace('#\{([a-z0-9\-_]*?)\}#is', '\' . ( ( isset($this->_tpldata[\'.\'][0][\'\1\']) ) ? $this->_tpldata[\'.\'][0][\'\1\'] : \'\' ) . \'', $code);
    314 
    315                 // Break it up into lines.
    316                 $code_lines = explode("\n", $code);
    317 
    318                 $block_nesting_level = 0;
    319                 $block_names = array();
    320                 $block_names[0] = ".";
    321 
    322                 // Second: prepend echo ', append ' . "\n"; to each line.
    323                 $line_count = sizeof($code_lines);
    324                 for ($i = 0; $i < $line_count; $i++)
    325                 {
    326                         $code_lines[$i] = chop($code_lines[$i]);
    327                         if (preg_match('#<!-- BEGIN (.*?) -->#', $code_lines[$i], $m))
    328                         {
    329                                 $n[0] = $m[0];
    330                                 $n[1] = $m[1];
    331 
    332                                 // Added: dougk_ff7-Keeps templates from bombing if begin is on the same line as end.. I think. :)
    333                                 if ( preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $n) )
    334                                 {
    335                                         $block_nesting_level++;
    336                                         $block_names[$block_nesting_level] = $m[1];
    337                                         if ($block_nesting_level < 2)
    338                                         {
    339                                                 // Block is not nested.
    340                                                 $code_lines[$i] = '$_' . $n[1] . '_count = ( isset($this->_tpldata[\'' . $n[1] . '.\']) ) ?  sizeof($this->_tpldata[\'' . $n[1] . '.\']) : 0;';
    341                                                 $code_lines[$i] .= "\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
    342                                                 $code_lines[$i] .= "\n" . '{';
    343                                         }
    344                                         else
    345                                         {
    346                                                 // This block is nested.
    347 
    348                                                 // Generate a namespace string for this block.
    349                                                 $namespace = implode('.', $block_names);
    350                                                 // strip leading period from root level..
    351                                                 $namespace = substr($namespace, 2);
    352                                                 // Get a reference to the data array for this block that depends on the
    353                                                 // current indices of all parent blocks.
    354                                                 $varref = $this->generate_block_data_ref($namespace, false);
    355                                                 // Create the for loop code to iterate over this block.
    356                                                 $code_lines[$i] = '$_' . $n[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
    357                                                 $code_lines[$i] .= "\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
    358                                                 $code_lines[$i] .= "\n" . '{';
    359                                         }
    360 
    361                                         // We have the end of a block.
    362                                         unset($block_names[$block_nesting_level]);
    363                                         $block_nesting_level--;
    364                                         $code_lines[$i] .= '} // END ' . $n[1];
    365                                         $m[0] = $n[0];
    366                                         $m[1] = $n[1];
    367                                 }
    368                                 else
    369                                 {
    370                                         // We have the start of a block.
    371                                         $block_nesting_level++;
    372                                         $block_names[$block_nesting_level] = $m[1];
    373                                         if ($block_nesting_level < 2)
    374                                         {
    375                                                 // Block is not nested.
    376                                                 $code_lines[$i] = '$_' . $m[1] . '_count = ( isset($this->_tpldata[\'' . $m[1] . '.\']) ) ? sizeof($this->_tpldata[\'' . $m[1] . '.\']) : 0;';
    377                                                 $code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
    378                                                 $code_lines[$i] .= "\n" . '{';
    379                                         }
    380                                         else
    381                                         {
    382                                                 // This block is nested.
    383 
    384                                                 // Generate a namespace string for this block.
    385                                                 $namespace = implode('.', $block_names);
    386                                                 // strip leading period from root level..
    387                                                 $namespace = substr($namespace, 2);
    388                                                 // Get a reference to the data array for this block that depends on the
    389                                                 // current indices of all parent blocks.
    390                                                 $varref = $this->generate_block_data_ref($namespace, false);
    391                                                 // Create the for loop code to iterate over this block.
    392                                                 $code_lines[$i] = '$_' . $m[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
    393                                                 $code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
    394                                                 $code_lines[$i] .= "\n" . '{';
    395                                         }
    396                                 }
    397                         }
    398                         else if (preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $m))
    399                         {
    400                                 // We have the end of a block.
    401                                 unset($block_names[$block_nesting_level]);
    402                                 $block_nesting_level--;
    403                                 $code_lines[$i] = '} // END ' . $m[1];
    404                         }
    405                         else
    406                         {
    407                                 // We have an ordinary line of code.
    408                                 if (!$do_not_echo)
    409                                 {
    410                                         $code_lines[$i] = 'echo \'' . $code_lines[$i] . '\' . "\\n";';
    411                                 }
    412                                 else
    413                                 {
    414                                         $code_lines[$i] = '$' . $retvar . '.= \'' . $code_lines[$i] . '\' . "\\n";';
    415                                 }
    416                         }
    417                 }
    418 
    419                 // Bring it back into a single string of lines of code.
    420                 $code = implode("\n", $code_lines);
    421                 return $code    ;
    422 
    423         }
    424 
    425 
    426         /**
    427          * Generates a reference to the given variable inside the given (possibly nested)
    428          * block namespace. This is a string of the form:
    429          * ' . $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname'] . '
    430          * It's ready to be inserted into an "echo" line in one of the templates.
    431          * NOTE: expects a trailing "." on the namespace.
    432          */
    433         function generate_block_varref($namespace, $varname)
    434         {
    435                 // Strip the trailing period.
    436                 $namespace = substr($namespace, 0, strlen($namespace) - 1);
    437 
    438                 // Get a reference to the data block for this namespace.
    439                 $varref = $this->generate_block_data_ref($namespace, true);
    440                 // Prepend the necessary code to stick this in an echo line.
    441 
    442                 // Append the variable reference.
    443                 $varref .= '[\'' . $varname . '\']';
    444 
    445                 $varref = '\' . ( ( isset(' . $varref . ') ) ? ' . $varref . ' : \'\' ) . \'';
    446 
    447                 return $varref;
    448 
    449         }
    450 
    451 
    452         /**
    453          * Generates a reference to the array of data values for the given
    454          * (possibly nested) block namespace. This is a string of the form:
    455          * $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN']
    456          *
    457          * If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above.
    458          * NOTE: does not expect a trailing "." on the blockname.
    459          */
    460         function generate_block_data_ref($blockname, $include_last_iterator)
    461         {
    462                 // Get an array of the blocks involved.
    463                 $blocks = explode(".", $blockname);
    464                 $blockcount = sizeof($blocks) - 1;
    465                 $varref = '$this->_tpldata';
    466                 // Build up the string with everything but the last child.
    467                 for ($i = 0; $i < $blockcount; $i++)
    468                 {
    469                         $varref .= '[\'' . $blocks[$i] . '.\'][$_' . $blocks[$i] . '_i]';
    470                 }
    471                 // Add the block reference for the last child.
    472                 $varref .= '[\'' . $blocks[$blockcount] . '.\']';
    473                 // Add the iterator for the last child if requried.
    474                 if ($include_last_iterator)
    475                 {
    476                         $varref .= '[$_' . $blocks[$blockcount] . '_i]';
    477                 }
    478 
    479                 return $varref;
    480         }
    481 
     35
     36  var $classname = "Template";
     37 
     38  // variable that holds all the data we'll be substituting into
     39  // the compiled templates.
     40  // ...
     41  // This will end up being a multi-dimensional array like this :
     42  // $this->_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value
     43  // if it's a root-level variable, it'll be like this:
     44  // $this->_tpldata[.][0][varname] == value
     45  var $_tpldata = array();
     46 
     47  // Hash of filenames for each template handle.
     48  var $files = array();
     49 
     50  // Root template directory.
     51  var $root = "";
     52
     53  // this will hash handle names to the compiled code for that handle.
     54  var $compiled_code = array();
     55 
     56  // This will hold the uncompiled code for that handle.
     57  var $uncompiled_code = array();
     58 
     59  /**
     60   * Constructor. Simply sets the root dir.
     61   *
     62   */
     63  function Template($root = ".")
     64    {
     65      $this->set_rootdir($root);
     66    }
     67 
     68  /**
     69   * Destroys this template object. Should be called when you're done with
     70   * it, in order to clear out the template data so you can load/parse a new
     71   * template set.
     72   */
     73  function destroy()
     74    {
     75      $this->_tpldata = array();
     76    }
     77
     78  /**
     79   * Sets the template root directory for this Template object.
     80   */
     81  function set_rootdir($dir)
     82    {
     83      if (!is_dir($dir))
     84      {
     85        return false;
     86      }
     87     
     88      $this->root = $dir;
     89      return true;
     90    }
     91 
     92  /**
     93   * Sets the template filenames for handles. $filename_array should be a
     94   * hash of handle => filename pairs.
     95   */
     96  function set_filenames($filename_array)
     97    {
     98      if (!is_array($filename_array))
     99      {
     100        return false;
     101      }
     102     
     103      reset($filename_array);
     104      while(list($handle, $filename) = each($filename_array))
     105      {
     106        $this->files[$handle] = $this->make_filename($filename);
     107      }
     108     
     109      return true;
     110    }
     111 
     112 
     113  /**
     114   * Load the file for the handle, compile the file, and run the compiled
     115   * code. This will print out the results of executing the template.
     116   */
     117  function pparse($handle)
     118    {
     119      if (!$this->loadfile($handle))
     120      {
     121        die("Template->pparse(): Couldn't load template file for handle $handle");
     122      }
     123     
     124      // actually compile the template now.
     125      if (!isset($this->compiled_code[$handle]) || empty($this->compiled_code[$handle]))
     126      {
     127        // Actually compile the code now.
     128        $this->compiled_code[$handle] = $this->compile($this->uncompiled_code[$handle]);
     129      }
     130
     131      // Run the compiled code.
     132      //echo ("<!-- ".$this->compiled_code[$handle]." -->");
     133      eval($this->compiled_code[$handle]);
     134      return true;
     135    }
     136 
     137  /**
     138   * Inserts the uncompiled code for $handle as the value of $varname in the
     139   * root-level. This can be used to effectively include a template in the
     140   * middle of another template.
     141   *
     142   * Note that all desired assignments to the variables in $handle should be
     143   * done BEFORE calling this function.
     144   */
     145  function assign_var_from_handle($varname, $handle)
     146    {
     147      if (!$this->loadfile($handle))
     148      {
     149        die("Template->assign_var_from_handle(): Couldn't load template file for handle $handle");
     150      }
     151     
     152      // Compile it, with the "no echo statements" option on.
     153      $_str = "";
     154      $code = $this->compile($this->uncompiled_code[$handle], true, '_str');
     155     
     156      // evaluate the variable assignment.
     157      eval($code);
     158      // assign the value of the generated variable to the given varname.
     159      $this->assign_var($varname, $_str);
     160     
     161      return true;
     162    }
     163 
     164  /**
     165   * Block-level variable assignment. Adds a new block iteration with the
     166   * given variable assignments. Note that this should only be called once
     167   * per block iteration.
     168   */
     169  function assign_block_vars($blockname, $vararray)
     170    {
     171      if (strstr($blockname, '.'))
     172      {
     173        // Nested block.
     174        $blocks = explode('.', $blockname);
     175        $blockcount = sizeof($blocks) - 1;
     176        $str = '$this->_tpldata';
     177        for ($i = 0; $i < $blockcount; $i++)
     178        {
     179          $str .= '[\'' . $blocks[$i] . '.\']';
     180          eval('$lastiteration = sizeof(' . $str . ') - 1;');
     181          $str .= '[' . $lastiteration . ']';
     182        }
     183        // Now we add the block that we're actually assigning to.
     184        // We're adding a new iteration to this block with the given
     185        // variable assignments.
     186        $str .= '[\'' . $blocks[$blockcount] . '.\'][] = $vararray;';
     187       
     188        // Now we evaluate this assignment we've built up.
     189        eval($str);
     190      }
     191      else
     192      {
     193        // Top-level block. Add a new iteration to this block with the
     194        // variable assignments we were given.
     195        $this->_tpldata[$blockname . '.'][] = $vararray;
     196      }
     197     
     198      return true;
     199    }
     200 
     201  /**
     202   * Root-level variable assignment. Adds to current assignments, overriding
     203   * any existing variable assignment with the same name.
     204   */
     205  function assign_vars($vararray)
     206    {
     207      reset ($vararray);
     208      while (list($key, $val) = each($vararray))
     209      {
     210        $this->_tpldata['.'][0][$key] = $val;
     211      }
     212     
     213      return true;
     214    }
     215 
     216  /**
     217   * Root-level variable assignment. Adds to current assignments, overriding
     218   * any existing variable assignment with the same name.
     219   */
     220  function assign_var($varname, $varval)
     221    {
     222      $this->_tpldata['.'][0][$varname] = $varval;
     223     
     224      return true;
     225    }
     226 
     227 
     228  /**
     229   * Generates a full path+filename for the given filename, which can either
     230   * be an absolute name, or a name relative to the rootdir for this
     231   * Template object.
     232   */
     233  function make_filename($filename)
     234    {
     235      // Check if it's an absolute or relative path.
     236      if (substr($filename, 0, 1) != '/')
     237      {
     238        $filename = realpath($this->root . '/' . $filename);
     239      }
     240     
     241      if (!file_exists($filename))
     242      {
     243        die("Template->make_filename(): Error - file $filename does not exist");
     244      }
     245     
     246      return $filename;
     247    }
     248 
     249 
     250  /**
     251   * If not already done, load the file for the given handle and populate
     252   * the uncompiled_code[] hash with its code. Do not compile.
     253   */
     254  function loadfile($handle)
     255    {
     256      // If the file for this handle is already loaded and compiled, do
     257      // nothing.
     258      if (isset($this->uncompiled_code[$handle])
     259          and !empty($this->uncompiled_code[$handle]))
     260      {
     261        return true;
     262      }
     263     
     264      // If we don't have a file assigned to this handle, die.
     265      if (!isset($this->files[$handle]))
     266      {
     267        die("Template->loadfile(): No file specified for handle $handle");
     268      }
     269     
     270      $filename = $this->files[$handle];
     271     
     272      $str = implode("", @file($filename));
     273      if (empty($str))
     274      {
     275        die("Template->loadfile(): File $filename for handle $handle is empty");
     276      }
     277     
     278      $this->uncompiled_code[$handle] = $str;
     279     
     280      return true;
     281    }
     282 
     283 
     284 
     285  /**
     286   * Compiles the given string of code, and returns the result in a string.
     287   *
     288   * If "do_not_echo" is true, the returned code will not be directly
     289   * executable, but can be used as part of a variable assignment for use in
     290   * assign_code_from_handle().
     291   */
     292  function compile($code, $do_not_echo = false, $retvar = '')
     293    {
     294      // replace \ with \\ and then ' with \'.
     295      $code = str_replace('\\', '\\\\', $code);
     296      $code = str_replace('\'', '\\\'', $code);
     297     
     298      // change template varrefs into PHP varrefs
     299     
     300      // This one will handle varrefs WITH namespaces
     301      $varrefs = array();
     302      preg_match_all('#\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}#is', $code, $varrefs);
     303      $varcount = sizeof($varrefs[1]);
     304      for ($i = 0; $i < $varcount; $i++)
     305      {
     306        $namespace = $varrefs[1][$i];
     307        $varname = $varrefs[3][$i];
     308        $new = $this->generate_block_varref($namespace, $varname);
     309       
     310        $code = str_replace($varrefs[0][$i], $new, $code);
     311      }
     312     
     313      // This will handle the remaining root-level varrefs
     314      $code = preg_replace('#\{([a-z0-9\-_]*?)\}#is', '\' . ( ( isset($this->_tpldata[\'.\'][0][\'\1\']) ) ? $this->_tpldata[\'.\'][0][\'\1\'] : \'\' ) . \'', $code);
     315     
     316      // Break it up into lines.
     317      $code_lines = explode("\n", $code);
     318     
     319      $block_nesting_level = 0;
     320      $block_names = array();
     321      $block_names[0] = ".";
     322     
     323      // Second: prepend echo ', append ' . "\n"; to each line.
     324      $line_count = sizeof($code_lines);
     325      for ($i = 0; $i < $line_count; $i++)
     326      {
     327        $code_lines[$i] = chop($code_lines[$i]);
     328        if (preg_match('#<!-- BEGIN (.*?) -->#', $code_lines[$i], $m))
     329        {
     330          $n[0] = $m[0];
     331          $n[1] = $m[1];
     332         
     333          // Added: dougk_ff7-Keeps templates from bombing if begin is on
     334          // the same line as end.. I think. :)
     335          if ( preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $n) )
     336          {
     337            $block_nesting_level++;
     338            $block_names[$block_nesting_level] = $m[1];
     339            if ($block_nesting_level < 2)
     340            {
     341              // Block is not nested.
     342              $code_lines[$i] = '$_' . $n[1] . '_count = ( isset($this->_tpldata[\'' . $n[1] . '.\']) ) ?  sizeof($this->_tpldata[\'' . $n[1] . '.\']) : 0;';
     343              $code_lines[$i] .= "\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
     344              $code_lines[$i] .= "\n" . '{';
     345            }
     346            else
     347            {
     348              // This block is nested.
     349             
     350              // Generate a namespace string for this block.
     351              $namespace = implode('.', $block_names);
     352              // strip leading period from root level..
     353              $namespace = substr($namespace, 2);
     354              // Get a reference to the data array for this block that depends on the
     355              // current indices of all parent blocks.
     356              $varref = $this->generate_block_data_ref($namespace, false);
     357              // Create the for loop code to iterate over this block.
     358              $code_lines[$i] = '$_' . $n[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
     359              $code_lines[$i] .= "\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
     360              $code_lines[$i] .= "\n" . '{';
     361            }
     362           
     363            // We have the end of a block.
     364            unset($block_names[$block_nesting_level]);
     365            $block_nesting_level--;
     366            $code_lines[$i] .= '} // END ' . $n[1];
     367            $m[0] = $n[0];
     368            $m[1] = $n[1];
     369          }
     370          else
     371          {
     372            // We have the start of a block.
     373            $block_nesting_level++;
     374            $block_names[$block_nesting_level] = $m[1];
     375            if ($block_nesting_level < 2)
     376            {
     377              // Block is not nested.
     378              $code_lines[$i] = '$_' . $m[1] . '_count = ( isset($this->_tpldata[\'' . $m[1] . '.\']) ) ? sizeof($this->_tpldata[\'' . $m[1] . '.\']) : 0;';
     379              $code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
     380              $code_lines[$i] .= "\n" . '{';
     381            }
     382            else
     383            {
     384              // This block is nested.
     385             
     386              // Generate a namespace string for this block.
     387              $namespace = implode('.', $block_names);
     388              // strip leading period from root level..
     389              $namespace = substr($namespace, 2);
     390              // Get a reference to the data array for this block that
     391              // depends on the current indices of all parent blocks.
     392              $varref = $this->generate_block_data_ref($namespace, false);
     393              // Create the for loop code to iterate over this block.
     394              $code_lines[$i] = '$_' . $m[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
     395              $code_lines[$i] .= "\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
     396              $code_lines[$i] .= "\n" . '{';
     397            }
     398          }
     399        }
     400        else if (preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $m))
     401        {
     402          // We have the end of a block.
     403          unset($block_names[$block_nesting_level]);
     404          $block_nesting_level--;
     405          $code_lines[$i] = '} // END ' . $m[1];
     406        }
     407        else
     408        {
     409          // We have an ordinary line of code.
     410          if (!$do_not_echo)
     411          {
     412            $code_lines[$i] = 'echo \'' . $code_lines[$i] . '\' . "\\n";';
     413          }
     414          else
     415          {
     416            $code_lines[$i] = '$' . $retvar . '.= \'' . $code_lines[$i] . '\' . "\\n";';
     417          }
     418        }
     419      }
     420     
     421      // Bring it back into a single string of lines of code.
     422      $code = implode("\n", $code_lines);
     423      return $code      ;
     424     
     425    }
     426 
     427 
     428  /**
     429   * Generates a reference to the given variable inside the given (possibly
     430   * nested) block namespace. This is a string of the form: '
     431   * . $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname']
     432   * . ' It's ready to be inserted into an "echo" line in one of the
     433   * templates.  NOTE: expects a trailing "." on the namespace.
     434   */
     435  function generate_block_varref($namespace, $varname)
     436    {
     437      // Strip the trailing period.
     438      $namespace = substr($namespace, 0, strlen($namespace) - 1);
     439     
     440      // Get a reference to the data block for this namespace.
     441      $varref = $this->generate_block_data_ref($namespace, true);
     442      // Prepend the necessary code to stick this in an echo line.
     443     
     444      // Append the variable reference.
     445      $varref .= '[\'' . $varname . '\']';
     446     
     447      $varref = '\' . ( ( isset(' . $varref . ') ) ? ' . $varref . ' : \'\' ) . \'';
     448     
     449      return $varref;
     450     
     451    }
     452 
     453 
     454  /**
     455   * Generates a reference to the array of data values for the given
     456   * (possibly nested) block namespace. This is a string of the form:
     457   * $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN']
     458   *
     459   * If $include_last_iterator is true, then [$_childN_i] will be appended
     460   * to the form shown above.  NOTE: does not expect a trailing "." on the
     461   * blockname.
     462   */
     463  function generate_block_data_ref($blockname, $include_last_iterator)
     464    {
     465      // Get an array of the blocks involved.
     466      $blocks = explode(".", $blockname);
     467      $blockcount = sizeof($blocks) - 1;
     468      $varref = '$this->_tpldata';
     469      // Build up the string with everything but the last child.
     470      for ($i = 0; $i < $blockcount; $i++)
     471      {
     472        $varref .= '[\'' . $blocks[$i] . '.\'][$_' . $blocks[$i] . '_i]';
     473      }
     474      // Add the block reference for the last child.
     475      $varref .= '[\'' . $blocks[$blockcount] . '.\']';
     476      // Add the iterator for the last child if requried.
     477      if ($include_last_iterator)
     478      {
     479              $varref .= '[$_' . $blocks[$blockcount] . '_i]';
     480      }
     481     
     482      return $varref;
     483    }
     484 
    482485}
    483486
  • trunk/picture.php

    r394 r402  
    7070}
    7171
    72 //---------------------------------------- prev, current & next picture management
    73 $picture=array();
    74 $picture['prev']['name']='';
    75 $picture['next']['name']='';
    76 $picture['prev']['thumbnail']='';
    77 $picture['next']['thumbnail']='';
    78 $picture['prev']['url']='';
    79 $picture['next']['url']='';
     72//------------------------------------- prev, current & next picture management
     73$picture = array();
     74$picture['prev']['name'] = '';
     75$picture['next']['name'] = '';
     76$picture['prev']['thumbnail'] = '';
     77$picture['next']['thumbnail'] = '';
     78$picture['prev']['url'] = '';
     79$picture['next']['url'] = '';
    8080
    8181$next = $page['num'] + 1;
    8282$prev = $page['num'] - 1;
    8383
    84 if ( $page['num'] == $page['cat_nb_images']-1)
     84if ( $page['num'] == $page['cat_nb_images'] - 1 )
    8585{
    8686  $next = 0;
    8787}
    8888
    89 $query = 'SELECT * FROM '.IMAGES_TABLE;
     89$query = 'SELECT *';
     90$query.= ' FROM '.IMAGES_TABLE;
    9091$query.= ' INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic';
    9192$query.= ' ON id=ic.image_id';
     
    9394$query.= $conf['order_by'];
    9495
    95 if ($prev <0)
     96if ( $prev < 0 )
     97{
    9698  $query.= ' LIMIT 0,2';
     99}
    97100else
     101{
    98102  $query.= ' LIMIT '.$prev.',3';
    99  
     103}
    100104$query.= ';';
    101105
    102106$result = mysql_query( $query );
    103 $nb_row = mysql_num_rows($result);
     107$nb_row = mysql_num_rows( $result );
    104108$index = array('prev','current','next');
    105 for ($i=0; $i<$nb_row;$i++)
     109
     110for ( $i = 0; $i < $nb_row; $i++ )
    106111{
    107112  $j=($prev<0)?$index[$i+1]:$index[$i];
     
    116121  $cat_directory = $array_cat_directories[$row['storage_category_id']];
    117122  $file = substr ( $row['file'], 0, strrpos ( $row['file'], ".") );
     123
    118124  $picture[$j]['src'] = $cat_directory.$row['file'];
     125
    119126  $picture[$j]['thumbnail'] = $cat_directory.'thumbnail/';
    120   $picture[$j]['thumbnail'].= $conf['prefix_thumbnail'].$file.".".$row['tn_ext'];
    121  
    122   if (!empty($row['name']))
     127  $picture[$j]['thumbnail'].= $conf['prefix_thumbnail'].$file;
     128  $picture[$j]['thumbnail'].= '.'.$row['tn_ext'];
     129 
     130  if ( !empty( $row['name'] ) )
    123131  {
    124132    $picture[$j]['name'] = $row['name'];
     
    126134  else
    127135  {
    128     $picture[$j]['name'] = str_replace( "_", " ",$file);
     136    $picture[$j]['name'] = str_replace( '_', ' ', $file );
    129137  }
    130138
     
    133141  if ( $page['cat'] == 'search' )
    134142  {
    135     $picture[$j]['url'].= "&amp;search=".$_GET['search'].'&amp;mode='.$_GET['mode'];
     143    $picture[$j]['url'].= '&amp;search='.$_GET['search'];
     144    $picture[$j]['url'].= '&amp;mode='.$_GET['mode'];
    136145  }
    137146}
     
    144153}
    145154
    146 $url_admin = PHPWG_ROOT_PATH.'admin.php?page=picture_modify&amp;cat_id='.$page['cat'];
     155$url_admin = PHPWG_ROOT_PATH.'admin.php?page=picture_modify';
     156$url_admin.= '&amp;cat_id='.$page['cat'];
    147157$url_admin.= '&amp;image_id='.$_GET['image_id'];
    148158 
     
    150160if ( isset( $_GET['add_fav'] ) )
    151161{
    152   $query = 'DELETE FROM '.FAVORITES_TABLE.' WHERE user_id = '.$user['id'];
    153   $query.= ' AND image_id = '.$picture['current']['id'].';';
     162  $query = 'DELETE FROM '.FAVORITES_TABLE;
     163  $query.= ' WHERE user_id = '.$user['id'];
     164  $query.= ' AND image_id = '.$picture['current']['id'];
     165  $query.= ';';
    154166  $result = mysql_query( $query );
    155167 
    156168  if ( $_GET['add_fav'] == 1 )
    157169  {
    158     $query = 'INSERT INTO '.FAVORITES_TABLE.' (image_id,user_id) VALUES';
    159     $query.= ' ('.$picture['current']['id'].','.$user['id'].');';
    160         $result = mysql_query( $query );
    161   }
    162   if ( !$_GET['add_fav'] && $page['cat']=='fav')
    163   {
    164     if ( $prev < 0 && $nb_row==1 )
    165     {
    166       // there is no favorite picture anymore
    167       // we redirect the user to the category page
     170    $query = 'INSERT INTO '.FAVORITES_TABLE;
     171    $query.= ' (image_id,user_id) VALUES';
     172    $query.= ' ('.$picture['current']['id'].','.$user['id'].')';
     173    $query.= ';';
     174    $result = mysql_query( $query );
     175  }
     176  if ( !$_GET['add_fav'] and $page['cat'] == 'fav' )
     177  {
     178    if ( $prev < 0 and $nb_row == 1 )
     179    {
     180      // there is no favorite picture anymore we redirect the user to the
     181      // category page
    168182      $url = add_session_id( $url_home );
    169183      header( 'Request-URI: '.$url );
     
    172186      exit();
    173187    }
    174         else if ( $prev < 0 )
    175         {
    176           $url = add_session_id( str_replace('&amp;','&',$picture['next']['url']), true);
    177         }
    178         else
    179         {
    180           $url = add_session_id( str_replace('&amp;','&',$picture['prev']['url']), true);
    181         }
    182         header( 'Request-URI: '.$url );
    183         header( 'Content-Location: '.$url ); 
    184         header( 'Location: '.$url );
    185         exit();
    186   }
    187 }
    188 
    189 //---------------------------------------------------------  comment registeration
    190   if ( isset( $_POST['content'] ) && !empty($_POST['content']) )
    191   {
    192     $register_comment = true;
    193         $author = !empty($_POST['author'])?$_POST['author']:$lang['guest'];
    194     // if a guest try to use the name of an already existing user, he must
    195     // be rejected
    196     if ( $author != $user['username'] )
    197     {
    198       $query = 'SELECT COUNT(*) AS user_exists';
    199       $query.= ' FROM '.USERS_TABLE;
    200       $query.= " WHERE username = '".$author."'";
    201       $query.= ';';
    202       $row = mysql_fetch_array( mysql_query( $query ) );
    203       if ( $row['user_exists'] == 1 )
    204       {
    205             $template->assign_block_vars('information', array('INFORMATION'=>$lang['comment_user_exists']));
    206         $register_comment = false;
    207       }
    208     }
    209 
    210     if ( $register_comment )
    211     {
    212       // anti-flood system
    213       $reference_date = time() - $conf['anti-flood_time'];
    214       $query = 'SELECT id FROM '.COMMENTS_TABLE;
    215       $query.= ' WHERE date > '.$reference_date;
    216       $query.= " AND author = '".$author."'";
    217       $query.= ';';
    218       if ( mysql_num_rows( mysql_query( $query ) ) == 0
    219            || $conf['anti-flood_time'] == 0 )
    220       {
    221         $query = 'INSERT INTO '.COMMENTS_TABLE;
    222         $query.= ' (author,date,image_id,content,validated) VALUES (';
    223                 $query.= "'".$author."'";
    224         $query.= ','.time().','.$_GET['image_id'];
    225         $query.= ",'".htmlspecialchars( $_POST['content'], ENT_QUOTES)."'";
    226         if ( !$conf['comments_validation'] || $user['status'] == 'admin' )
    227           $query.= ",'true'";
    228         else
    229           $query.= ",'false'";
    230         $query.= ');';
    231         mysql_query( $query );
    232         // information message
    233         $message = $lang['comment_added'];
    234         if ( $conf['comments_validation'] and $user['status'] != 'admin' )
    235         {
    236           $message.= '<br />'.$lang['comment_to_validate'];
    237         }
    238         $template->assign_block_vars('information', array('INFORMATION'=>$message));
    239         // notification to the administrators
    240         if ( $conf['mail_notification'] )
    241         {
    242           $cat_name = get_cat_display_name( $page['cat_name'], ' > ', '' );
    243           $cat_name = strip_tags( $cat_name );
    244           notify( 'comment', $cat_name.' > '.$picture['current']['name']);
    245         }
     188    else if ( $prev < 0 )
     189    {
     190      $url = str_replace( '&amp;', '&', $picture['next']['url'] );
     191      $url = add_session_id( $url, true);
     192    }
     193    else
     194    {
     195      $url = str_replace('&amp;', '&', $picture['prev']['url'] );
     196      $url = add_session_id( $url, true);
     197    }
     198    header( 'Request-URI: '.$url );
     199    header( 'Content-Location: '.$url ); 
     200    header( 'Location: '.$url );
     201    exit();
     202  }
     203}
     204
     205//------------------------------------------------------  comment registeration
     206if ( isset( $_POST['content'] ) && !empty($_POST['content']) )
     207{
     208  $register_comment = true;
     209  $author = !empty($_POST['author'])?$_POST['author']:$lang['guest'];
     210  // if a guest try to use the name of an already existing user, he must be
     211  // rejected
     212  if ( $author != $user['username'] )
     213  {
     214    $query = 'SELECT COUNT(*) AS user_exists';
     215    $query.= ' FROM '.USERS_TABLE;
     216    $query.= " WHERE username = '".$author."'";
     217    $query.= ';';
     218    $row = mysql_fetch_array( mysql_query( $query ) );
     219    if ( $row['user_exists'] == 1 )
     220    {
     221      $template->assign_block_vars(
     222        'information',
     223        array('INFORMATION'=>$lang['comment_user_exists']));
     224      $register_comment = false;
     225    }
     226  }
     227 
     228  if ( $register_comment )
     229  {
     230    // anti-flood system
     231    $reference_date = time() - $conf['anti-flood_time'];
     232    $query = 'SELECT id FROM '.COMMENTS_TABLE;
     233    $query.= ' WHERE date > '.$reference_date;
     234    $query.= " AND author = '".$author."'";
     235    $query.= ';';
     236    if ( mysql_num_rows( mysql_query( $query ) ) == 0
     237         or $conf['anti-flood_time'] == 0 )
     238    {
     239      $query = 'INSERT INTO '.COMMENTS_TABLE;
     240      $query.= ' (author,date,image_id,content,validated) VALUES (';
     241      $query.= "'".$author."'";
     242      $query.= ','.time().','.$_GET['image_id'];
     243      $query.= ",'".htmlspecialchars( $_POST['content'], ENT_QUOTES)."'";
     244      if ( !$conf['comments_validation'] or $user['status'] == 'admin' )
     245      {       
     246        $query.= ",'true'";
    246247      }
    247248      else
    248249      {
    249         // information message
    250         $template->assign_block_vars('information', array('INFORMATION'=>$lang['comment_anti-flood']));
     250        $query.= ",'false'";
    251251      }
    252     }
    253   }
    254   // comment deletion
    255   if ( isset( $_GET['del'] )
    256        && is_numeric( $_GET['del'] )
    257        && $user['status'] == 'admin' )
    258   {
    259     $query = 'DELETE FROM '.COMMENTS_TABLE.' WHERE id = '.$_GET['del'].';';
    260     mysql_query( $query );
    261   }
     252      $query.= ');';
     253      mysql_query( $query );
     254      // information message
     255      $message = $lang['comment_added'];
     256      if ( $conf['comments_validation'] and $user['status'] != 'admin' )
     257      {
     258        $message.= '<br />'.$lang['comment_to_validate'];
     259      }
     260      $template->assign_block_vars('information',
     261                                   array('INFORMATION'=>$message));
     262      // notification to the administrators
     263      if ( $conf['mail_notification'] )
     264      {
     265        $cat_name = get_cat_display_name( $page['cat_name'], ' > ', '' );
     266        $cat_name = strip_tags( $cat_name );
     267        notify( 'comment', $cat_name.' > '.$picture['current']['name']);
     268      }
     269    }
     270    else
     271    {
     272      // information message
     273      $template->assign_block_vars(
     274        'information',
     275        array('INFORMATION'=>$lang['comment_anti-flood']));
     276    }
     277  }
     278}
     279// comment deletion
     280if ( isset( $_GET['del'] )
     281     and is_numeric( $_GET['del'] )
     282     and $user['status'] == 'admin' )
     283{
     284  $query = 'DELETE FROM '.COMMENTS_TABLE;
     285  $query.= ' WHERE id = '.$_GET['del'];
     286  $query.= ';';
     287  mysql_query( $query );
     288}
    262289
    263290//
     
    267294$title =  $picture['current']['name'];
    268295$refresh = 0;
    269 if ( isset( $_GET['slideshow'] ) && $next)
    270 {
    271         $refresh= $_GET['slideshow'];
    272         $url_link = $picture['next']['url'];
     296if ( isset( $_GET['slideshow'] ) and $next )
     297{
     298  $refresh= $_GET['slideshow'];
     299  $url_link = $picture['next']['url'];
    273300}
    274301
Note: See TracChangeset for help on using the changeset viewer.