source: branches/1.7/include/functions_url.inc.php @ 4636

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