source: trunk/include/functions_url.inc.php @ 19618

Last change on this file since 19618 was 18462, checked in by mistic100, 12 years ago

feature:2614 pagination on albums
return to old fashioned way (one query in category_cats), restoring recent_cats feature and "menubar optimization", rename "starta" into "startcat"

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