source: extensions/piclens/functions_url.inc.php @ 26552

Last change on this file since 26552 was 3636, checked in by tiico, 15 years ago

Correct name and description of pictures with extendedDescriotion plugin

File size: 17.7 KB
RevLine 
[3636]1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based picture gallery                                  |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
23
24
25/**
26 * returns a prefix for each url link on displayed page
27 * and return an empty string for current path
28 * @return string
29 */
30function get_root_url()
31{
32  global $page;
33  if ( isset($page['root_path']) )
34  {
35    $root_url = $page['root_path'];
36  }
37  else
38  {// TODO - add HERE the possibility to call PWG functions from external scripts
39    $root_url = PHPWG_ROOT_PATH;
40  }
41  if ( strncmp($root_url, './', 2) != 0 )
42  {
43    return $root_url;
44  }
45  else
46  {
47    return (string)substr($root_url, 2);
48  }
49}
50
51/**
52 * returns the absolute url to the root of PWG
53 * @param boolean with_scheme if false - does not add http://toto.com
54 */
55function get_absolute_root_url($with_scheme=true)
56{
57  // TODO - add HERE the possibility to call PWG functions from external scripts
58  $url = '';
59  if ($with_scheme)
60  {
61/*
62        if (empty($_SERVER['HTTPS']))
63    {
64      $url .= 'http://';
65    }
66    else
67    {
68      $url .= 'https://';
69    }
70*/
71    if ((!isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) != 'on' ))
72    {
73      $url .= 'http://';
74    }
75    else
76    {
77      $url .= 'https://';
78    }
79    $url .= $_SERVER['HTTP_HOST'];
80    if ($_SERVER['SERVER_PORT'] != 80)
81    {
82      $url_port = ':'.$_SERVER['SERVER_PORT'];
83      if (strrchr($url, ':') != $url_port)
84      {
85        $url .= $url_port;
86      }
87    }
88  }
89  $url .= cookie_path();
90  return $url;
91}
92
93/**
94 * adds one or more _GET style parameters to an url
95 * example: add_url_params('/x', array('a'=>'b')) returns /x?a=b
96 * add_url_params('/x?cat_id=10', array('a'=>'b')) returns /x?cat_id=10&amp;a=b
97 * @param string url
98 * @param array params
99 * @return string
100 */
101function add_url_params($url, $params)
102{
103  if ( !empty($params) )
104  {
105    assert( is_array($params) );
106    $is_first = true;
107    foreach($params as $param=>$val)
108    {
109      if ($is_first)
110      {
111        $is_first = false;
112        $url .= ( strpos($url, '?')===false ) ? '?' :'&amp;';
113      }
114      else
115      {
116        $url .= '&amp;';
117      }
118      $url .= $param;
119      if (isset($val))
120      {
121        $url .= '='.$val;
122      }
123    }
124  }
125  return $url;
126}
127
128/**
129 * build an index URL for a specific section
130 *
131 * @param array
132 * @return string
133 */
134function make_index_url($params = array())
135{
136  global $conf;
137  $url = get_root_url().'index';
138  if ($conf['php_extension_in_urls'])
139  {
140    $url .= '.php';
141  }
142  if ($conf['question_mark_in_urls'])
143  {
144    $url .= '?';
145  }
146  $url.= make_section_in_url($params);
147  $url = add_well_known_params_in_url($url, $params);
148  return $url;
149}
150
151/**
152 * build an index URL with current page parameters, but with redefinitions
153 * and removes.
154 *
155 * duplicate_index_url( array(
156 *   'category' => array('id'=>12, 'name'=>'toto'),
157 *   array('start')
158 * ) will create an index URL on the current section (categories), but on
159 * a redefined category and without the start URL parameter.
160 *
161 * @param array redefined keys
162 * @param array removed keys
163 * @return string
164 */
165function duplicate_index_url($redefined = array(), $removed = array())
166{
167  return make_index_url(
168    params_for_duplication($redefined, $removed)
169    );
170}
171
172/**
173 * returns $page global array with key redefined and key removed
174 *
175 * @param array redefined keys
176 * @param array removed keys
177 * @return array
178 */
179function params_for_duplication($redefined, $removed)
180{
181  global $page;
182
183  $params = $page;
184
185  foreach ($removed as $param_key)
186  {
187    unset($params[$param_key]);
188  }
189
190  foreach ($redefined as $redefined_param => $redefined_value)
191  {
192    $params[$redefined_param] = $redefined_value;
193  }
194
195  return $params;
196}
197
198/**
199 * create a picture URL with current page parameters, but with redefinitions
200 * and removes. See duplicate_index_url.
201 *
202 * @param array redefined keys
203 * @param array removed keys
204 * @return string
205 */
206function duplicate_picture_url($redefined = array(), $removed = array())
207{
208  return make_picture_url(
209    params_for_duplication($redefined, $removed)
210    );
211}
212
213/**
214 * create a picture URL on a specific section for a specific picture
215 *
216 * @param array
217 * @return string
218 */
219function make_picture_url($params)
220{
221  global $conf;
222
223  isset($params['image_id']) or fatal_error('make_picture_url: image_id is a required parameter');
224
225  $url = get_root_url().'picture';
226  if ($conf['php_extension_in_urls'])
227  {
228    $url .= '.php';
229  }
230  if ($conf['question_mark_in_urls'])
231  {
232    $url .= '?';
233  }
234  $url.= '/';
235  switch ( $conf['picture_url_style'] )
236  {
237    case 'id-file':
238      $url .= $params['image_id'];
239      if ( isset($params['image_file']) )
240      {
241        $url .= '-'.get_filename_wo_extension($params['image_file']);
242      }
243      break;
244    case 'file':
245      if ( isset($params['image_file']) )
246      {
247        $fname_wo_ext = get_filename_wo_extension($params['image_file']);
248        if ( ord($fname_wo_ext)>ord('9') or !preg_match('/^\d+(-|$)/', $fname_wo_ext) )
249        {
250          $url .= $fname_wo_ext;
251          break;
252        }
253      }
254    default:
255      $url .= $params['image_id'];
256  }
257  if ( !isset($params['category'] ) )
258  {// make urls shorter ...
259    unset( $params['flat'] );
260  }
261  $url .= make_section_in_url($params);
262  $url = add_well_known_params_in_url($url, $params);
263  return $url;
264}
265
266/**
267 *adds to the url the chronology and start parameters
268*/
269function add_well_known_params_in_url($url, $params)
270{
271  if ( isset($params['chronology_field']) )
272  {
273    $url .= '/'. $params['chronology_field'];
274    $url .= '-'. $params['chronology_style'];
275    if ( isset($params['chronology_view']) )
276    {
277      $url .= '-'. $params['chronology_view'];
278    }
279    if ( !empty($params['chronology_date']) )
280    {
281      $url .= '-'. implode('-', $params['chronology_date'] );
282    }
283  }
284
285  if (isset($params['flat']))
286  {
287    $url.= '/flat';
288  }
289
290  if (isset($params['start']) and $params['start'] > 0)
291  {
292    $url.= '/start-'.$params['start'];
293  }
294  return $url;
295}
296
297/**
298 * return the section token of an index or picture URL.
299 *
300 * Depending on section, other parameters are required (see function code
301 * for details)
302 *
303 * @param array
304 * @return string
305 */
306function make_section_in_url($params)
307{
308  global $conf;
309  $section_string = '';
310
311  $section_of = array(
312    'category' => 'categories',
313    'tags'     => 'tags',
314    'list'     => 'list',
315    'search'   => 'search',
316    );
317
318  foreach ($section_of as $param => $section)
319  {
320    if (isset($params[$param]))
321    {
322      $params['section'] = $section;
323    }
324  }
325
326  if (!isset($params['section']))
327  {
328    $params['section'] = 'none';
329  }
330
331  switch($params['section'])
332  {
333    case 'categories' :
334    {
335      if (!isset($params['category']))
336      {
337        $section_string.= '/categories';
338      }
339      else
340      {
341        is_array($params['category']) or trigger_error(
342            'make_section_in_url wrong type for category', E_USER_WARNING
343            );
344        is_numeric($params['category']['id']) or trigger_error(
345            'make_section_in_url category id not numeric', E_USER_WARNING
346            );
347        isset($params['category']['name']) or trigger_error(
348            'make_section_in_url category name not set', E_USER_WARNING
349            );
350
351        array_key_exists('permalink', $params['category']) or trigger_error(
352            'make_section_in_url category permalink not set', E_USER_WARNING
353            );
354
355        $section_string.= '/category/';
356        if ( empty($params['category']['permalink']) )
357        {
358          $section_string.= $params['category']['id'];
359          if ( $conf['category_url_style']=='id-name' )
360          {
361            $section_string.= '-'.str2url($params['category']['name']);
362          }
363        }
364        else
365        {
366          $section_string.= $params['category']['permalink'];
367        }
368      }
369
370      break;
371    }
372    case 'tags' :
373    {
374      if (!isset($params['tags']) or count($params['tags']) == 0)
375      {
376        fatal_error('make_section_in_url: require at least one tag');
377      }
378
379      $section_string.= '/tags';
380
381      foreach ($params['tags'] as $tag)
382      {
383        switch ( $conf['tag_url_style'] )
384        {
385          case 'id':
386            $section_string.= '/'.$tag['id'];
387            break;
388          case 'tag':
389            if (isset($tag['url_name']) and !is_numeric($tag['url_name']) )
390            {
391              $section_string.= '/'.$tag['url_name'];
392              break;
393            }
394          default:
395            $section_string.= '/'.$tag['id'];
396            if (isset($tag['url_name']))
397            {
398              $section_string.= '-'.$tag['url_name'];
399            }
400        }
401      }
402
403      break;
404    }
405    case 'search' :
406    {
407      isset($params['search']) or fatal_error('make_section_in_url: require a search identifier');
408      $section_string.= '/search/'.$params['search'];
409      break;
410    }
411    case 'list' :
412    {
413      isset($params['list']) or fatal_error('make_section_in_url: require a list of items');
414      $section_string.= '/list/'.implode(',', $params['list']);
415      break;
416    }
417    case 'none' :
418    {
419      break;
420    }
421    default :
422    {
423      $section_string.= '/'.$params['section'];
424    }
425  }
426
427  return $section_string;
428}
429
430/**
431 * the reverse of make_section_in_url
432 * returns the 'section' (categories/tags/...) and the data associated with it
433 *
434 * Depending on section, other parameters are returned (category/tags/list/...)
435 *
436 * @param array of url tokens to parse
437 * @param int the index in the array of url tokens; in/out
438 * @return array
439 */
440function parse_section_url( $tokens, &$next_token)
441{
442  $page=array();
443  if (strncmp(@$tokens[$next_token], 'categor', 7)==0 )
444  {
445    $page['section'] = 'categories';
446    $next_token++;
447
448    if (isset($tokens[$next_token]) )
449    {
450      if (preg_match('/^(\d+)(?:-(.+))?$/', $tokens[$next_token], $matches))
451      {
452        if ( isset($matches[2]) )
453          $page['hit_by']['cat_url_name'] = $matches[2];
454        $page['category'] = $matches[1];
455        $next_token++;
456      }
457      else
458      {// try a permalink
459        $maybe_permalinks = array();
460        $current_token = $next_token;
461        while ( isset($tokens[$current_token])
462            and strpos($tokens[$current_token], 'created-')!==0
463            and strpos($tokens[$current_token], 'posted-')!==0
464            and strpos($tokens[$next_token], 'start-')!==0
465            and $tokens[$current_token] != 'flat')
466        {
467          if (empty($maybe_permalinks))
468          {
469            array_push($maybe_permalinks, $tokens[$current_token]);
470          }
471          else
472          {
473            array_push($maybe_permalinks,
474                $maybe_permalinks[count($maybe_permalinks)-1]
475                . '/' . $tokens[$current_token]
476              );
477          }
478          $current_token++;
479        }
480
481        if ( count($maybe_permalinks) )
482        {
483          $cat_id = get_cat_id_from_permalinks($maybe_permalinks, $perma_index);
484          if ( isset($cat_id) )
485          {
486            $next_token += $perma_index+1;
487            $page['category'] = $cat_id;
488            $page['hit_by']['cat_permalink'] = $maybe_permalinks[$perma_index];
489          }
490          else
491          {
492            page_not_found('Permalink for album not found');
493          }
494        }
495      }
496    }
497
498    if (isset($page['category']))
499    {
500      $result = get_cat_info($page['category']);
501      if (empty($result))
502      {
503        page_not_found('Requested category does not exist' );
504      }
505      $page['category']=$result;
506    }
507  }
508  elseif ( 'tags' == @$tokens[$next_token] )
509  {
510    $page['section'] = 'tags';
511    $page['tags'] = array();
512
513    $next_token++;
514    $i = $next_token;
515
516    $requested_tag_ids = array();
517    $requested_tag_url_names = array();
518
519    while (isset($tokens[$i]))
520    {
521      if (strpos($tokens[$i], 'created-')===0
522           or strpos($tokens[$i], 'posted-')===0
523           or strpos($tokens[$i], 'start-')===0 )
524        break;
525
526      if ( preg_match('/^(\d+)(?:-(.*))?/', $tokens[$i], $matches) )
527      {
528        array_push($requested_tag_ids, $matches[1]);
529      }
530      else
531      {
532        array_push($requested_tag_url_names, $tokens[$i]);
533      }
534      $i++;
535    }
536    $next_token = $i;
537
538    if ( empty($requested_tag_ids) && empty($requested_tag_url_names) )
539    {
540      bad_request('at least one tag required');
541    }
542
543    $page['tags'] = find_tags($requested_tag_ids, $requested_tag_url_names);
544    if ( empty($page['tags']) )
545    {
546      page_not_found('Requested tag does not exist', get_root_url().'tags.php' );
547    }
548  }
549  elseif ( 'favorites' == @$tokens[$next_token] )
550  {
551    $page['section'] = 'favorites';
552    $next_token++;
553  }
554  elseif ('most_visited' == @$tokens[$next_token])
555  {
556    $page['section'] = 'most_visited';
557    $next_token++;
558  }
559  elseif ('best_rated' == @$tokens[$next_token])
560  {
561    $page['section'] = 'best_rated';
562    $next_token++;
563  }
564  elseif ('recent_pics' == @$tokens[$next_token])
565  {
566    $page['section'] = 'recent_pics';
567    $next_token++;
568  }
569  elseif ('recent_cats' == @$tokens[$next_token])
570  {
571    $page['section'] = 'recent_cats';
572    $next_token++;
573  }
574  elseif ('search' == @$tokens[$next_token])
575  {
576    $page['section'] = 'search';
577    $next_token++;
578
579    preg_match('/(\d+)/', @$tokens[$next_token], $matches);
580    if (!isset($matches[1]))
581    {
582      bad_request('search identifier is missing');
583    }
584    $page['search'] = $matches[1];
585    $next_token++;
586  }
587  elseif ('list' == @$tokens[$next_token])
588  {
589    $page['section'] = 'list';
590    $next_token++;
591
592    $page['list'] = array();
593
594    // No pictures
595    if (empty($tokens[$next_token]))
596    {
597      // Add dummy element list
598      array_push($page['list'], -1);
599    }
600    // With pictures list
601    else
602    {
603      if (!preg_match('/^\d+(,\d+)*$/', $tokens[$next_token]))
604      {
605        bad_request('wrong format on list GET parameter');
606      }
607      foreach (explode(',', $tokens[$next_token]) as $image_id)
608      {
609        array_push($page['list'], $image_id);
610      }
611    }
612    $next_token++;
613  }
614  return $page;
615}
616
617/**
618 * the reverse of add_well_known_params_in_url
619 * parses start, flat and chronology from url tokens
620*/
621function parse_well_known_params_url($tokens, &$i)
622{
623  $page = array();
624  while (isset($tokens[$i]))
625  {
626    if ( 'flat' == $tokens[$i] )
627    {
628      // indicate a special list of images
629      $page['flat'] = true;
630    }
631    elseif (strpos($tokens[$i], 'created-')===0 or strpos($tokens[$i], 'posted-')===0)
632    {
633      $chronology_tokens = explode('-', $tokens[$i] );
634
635      $page['chronology_field'] = $chronology_tokens[0];
636
637      array_shift($chronology_tokens);
638      $page['chronology_style'] = $chronology_tokens[0];
639
640      array_shift($chronology_tokens);
641      if ( count($chronology_tokens)>0 )
642      {
643        if ('list'==$chronology_tokens[0] or
644            'calendar'==$chronology_tokens[0])
645        {
646          $page['chronology_view'] = $chronology_tokens[0];
647          array_shift($chronology_tokens);
648        }
649        $page['chronology_date'] = $chronology_tokens;
650      }
651    }
652    elseif (preg_match('/^start-(\d+)/', $tokens[$i], $matches))
653    {
654      $page['start'] = $matches[1];
655    }
656    $i++;
657  }
658  return $page;
659}
660
661/**
662 * Indicate to build url with full path
663 *
664 * @param null
665 * @return null
666 */
667function set_make_full_url()
668{
669  global $page;
670
671  if (!isset($page['save_root_path']))
672  {
673    if (isset($page['root_path']))
674    {
675      $page['save_root_path']['path'] = $page['root_path'];
676    }
677    $page['save_root_path']['count'] = 1;
678    $page['root_path'] = get_absolute_root_url();
679  }
680  else
681  {
682    $page['save_root_path']['count'] += 1;
683  }
684}
685
686/**
687 * Restore old parameter to build url with full path
688 *
689 * @param null
690 * @return null
691 */
692function unset_make_full_url()
693{
694  global $page;
695
696  if (isset($page['save_root_path']))
697  {
698    if ($page['save_root_path']['count'] == 1)
699    {
700      if (isset($page['save_root_path']['path']))
701      {
702        $page['root_path'] = $page['save_root_path']['path'];
703      }
704      else
705      {
706        unset($page['root_path']);
707      }
708      unset($page['save_root_path']);
709    }
710    else
711    {
712      $page['save_root_path']['count'] -= 1;
713    }
714  }
715}
716
717/**
718 * Embellish the url argument
719 *
720 * @param $url
721 * @return $url embellished
722 */
723function embellish_url($url)
724{
725  $url = str_replace('/./', '/', $url);
726  while ( ($dotdot = strpos($url, '/../', 1) ) !== false )
727  {
728    $before = strrpos($url, '/', -(strlen($url)-$dotdot+1) );
729    if ($before !== false)
730    {
731      $url = substr_replace($url, '', $before, $dotdot-$before+3);
732    }
733    else
734      break;
735  }
736  return $url;
737}
738
739?>
Note: See TracBrowser for help on using the repository browser.