source: extensions/pbase2piwigo/include/functions.inc.php @ 28833

Last change on this file since 28833 was 26201, checked in by mistic100, 11 years ago

update for 2.6

File size: 11.5 KB
Line 
1<?php
2defined('PBASE_PATH') or die('Hacking attempt!');
3
4/**
5 * get the content of web-page, with cache management
6 * @param: string url
7 * @return: string
8 */
9function get_file_cached($url)
10{
11  // html files are cached 10000 seconds
12  $cache_id_prefix = str_replace('http://www.pbase.com/', null, $url);
13  $cache_id_prefix = preg_replace('#([^a-z0-9-_]+)#i', null, $cache_id_prefix);
14  $cache_id = $cache_id_prefix.'-'.substr(time(), 0, -4);
15 
16  if (!file_exists(PBASE_FS_CACHE.$cache_id))
17  {
18    $files = glob(PBASE_FS_CACHE.$cache_id_prefix.'-*');
19    foreach ($files as $file) unlink($file);
20   
21    if (($result = download_remote_file($url, PBASE_FS_CACHE.$cache_id)) !== true)
22    {
23      return $result;
24    }
25  }
26 
27  $html = file_get_contents(PBASE_FS_CACHE.$cache_id);
28 
29  return utf8_encode($html);
30}
31
32/**
33 * helper to navigate throught the tree
34 * @param: &array tree
35 * @param: string path
36 * @return: reference to a branch of the tree
37 */
38function &get_current_cat(&$tree, $path)
39{
40  if (empty($path)) return $tree;
41 
42  $path = ltrim($path, '/');
43  $path = explode('/', $path);
44  $current = &$tree[ $path[0] ];
45  array_shift($path);
46 
47  foreach ($path as $folder)
48  {
49    $current = &$current['categories'][$folder];
50  }
51 
52  return $current;
53}
54
55/**
56 * check if give account (http://pbase.com/login/root) exists
57 * @param: string url
58 * @return: bool
59 */
60function check_account($url)
61{
62  $html = get_file_cached($url);
63  return !(bool)preg_match('#<h2>Unknown Account</h2>#i', $html);
64}
65
66/**
67 * parse a category page
68 * @param: string category url
69 * @param: bool parse only sub-categories
70 * @param: bool parse only one level
71 * @return: array category
72 */
73function parse_category($url, $path, $cats_only=false, $one_level=false)
74{
75  $url = str_replace('&page=all', null, $url);
76 
77  $current = array(
78    'url' => $url,
79    'path' => null,
80    'id' => null,
81    );
82   
83  // id
84  $temp = parse_url($url);
85  $temp = explode('/', $temp['path']);
86  $current['id'] = $temp[ count($temp)-1 ];
87  $current['path'] = $path.'/'.$current['id'];
88 
89  if ($one_level === 'stop')
90  {
91    return $current;
92  }
93   
94  $current = array_merge($current, array(
95    'title' => null,
96    'description' => null,
97    'pictures' => array(),
98    'categories' => array(),
99    'nb_pictures' => 0,
100    'nb_categories' => 0, 
101    ));
102   
103 
104  $url.= '&page=all'; // seriously... (should be ? not &)
105 
106 
107  $html = get_file_cached($url);
108  if ($html == 'file_error')
109  {
110    return $current;
111  }
112 
113  preg_match('#<body>(.*)</body>#is', $html, $matches);
114  $body = $matches[1];
115 
116  // content
117  // if (preg_match('#<CENTER>(.*)</CENTER>#is', $body, $matches) === 0) return 'null1';
118  if (preg_match_all('#<A HREF="([^">]*)" class="thumbnail">#i', $body, $matches) === 0) return $current;
119  $links = $matches[1];
120 
121  // title
122  if (preg_match('#<h2>(.*?)</h2>#i', $body, $matches))
123  {
124    $current['title'] = trim($matches[1]);
125  }
126  else
127  {
128    $current['title'] = $current['id'];
129  }
130 
131  // description
132  if (preg_match('#<!-- BEGIN user desc -->(.*?)<!-- END user desc -->#s', $body, $matches))
133  {
134    $current['description'] = trim($matches[1]);
135  }
136 
137  // sub-cats and pictures
138  foreach ($links as $link)
139  {
140    if (strpos($link, '/image/') !== false)
141    {
142      if (($image = parse_image($link, $cats_only)) !== null)
143      {
144        $current['pictures'][ $image['id'] ] = $image;
145      }
146      $current['nb_pictures']++;
147    }
148    else
149    {
150      $next_level = ($one_level === true) ? 'stop' : false;
151      if (($category = parse_category($link, $current['path'], $cats_only, $next_level)) !== null)
152      {
153        $current['categories'][ $category['id'] ] = $category;
154      }
155      $current['nb_categories']++;
156    }
157  }
158 
159  return $current;
160}
161
162/**
163 * parse a picture page
164 * @param: string picture url
165 * @param: bool return only url and id
166 * @return: array picture
167 */
168function parse_image($url, $light=false)
169{
170  $url = preg_replace('#/(small|medium|large|original)$#', null, $url);
171 
172  $current = array(
173    'url' => $url,
174    'id' => null,
175    );
176   
177  // id
178  $temp = parse_url($url);
179  $temp = explode('/', $temp['path']);
180  $current['id'] = $temp[ count($temp)-1 ];
181 
182  if ($light)
183  {
184    return $current;
185  }
186 
187  $current = array_merge($current, array(
188    'title' => null,
189    'path' => null,
190    'description' => null,
191    'date' => null,
192    'author' => null,
193    'keywords' => array(),
194    ));
195   
196  $url.= '/original';
197 
198 
199  $html = get_file_cached($url);
200  if ($html == 'file_error')
201  {
202    return $current;
203  }
204 
205  preg_match('#<body>(.*)</body>#is', $html, $matches);
206  $body = $matches[1];
207 
208  // path
209  if (preg_match('#<IMG ([^>]*)class="display" src="([^">]*)"#i', $body, $matches) ===0) return null;
210  $current['path'] = $matches[2];
211 
212  // title
213  preg_match('#<span class="title">(.*?)</span>#i', $body, $matches);
214  if (!empty($matches[1]))
215  {
216    $current['title'] = trim($matches[1]);
217    $current['title'] = get_filename_wo_extension($current['title']);
218  }
219  else
220  {
221    $current['title'] = $current['id'];
222  }
223 
224  // description
225  if (preg_match('#<p class="caption">(.*?)</p>#is', $body, $matches))
226  {
227    $current['description'] = trim($matches[1]);
228  }
229 
230  // date
231  if (preg_match('#<span class=date>(.*?)</span>#i', $body, $matches))
232  {
233    $current['date'] = trim($matches[1]);
234  }
235 
236  // author
237  if (preg_match('#<span class=artist>(.*?)</span>#i', $body, $matches))
238  {
239    $current['author'] = trim($matches[1]);
240  }
241 
242 
243  preg_match('#<head>(.*)</head>#is', $html, $matches);
244  $head = $matches[1];
245 
246  // keywords
247  if (preg_match('#<meta name="keywords" content="([^">]*)">#i', $head, $matches))
248  {
249    $words = explode(',', $matches[1]);
250    foreach ($words as $word)
251    {
252      if (!empty($word)) $current['keywords'][] = trim($word);
253    }
254  }
255 
256  return $current;
257}
258
259/**
260 * print categories tree (list or select)
261 * @param: array tree
262 * @param: int level
263 * @param: string tree type (list|select)
264 * @return: string
265 */
266function print_tree(&$tree, $level=0, $type='list')
267{
268  $out = '';
269 
270  if ($type == 'list')
271  {
272    $out.= '<ul>';
273    foreach ($tree as $item)
274    {
275      $out.= '<li>';
276      $out.= '<a href="'.$item['url'].'">'.$item['title'].'</a> ['.$item['nb_pictures'].']';
277      if (!empty($item['categories']))
278        $out.= print_tree($item['categories'], $level+1, 'list');
279      $out.= '</li>';
280    }
281    $out.= '</ul>';
282  }
283  else if ($type == 'select')
284  {
285    $i=0;
286    foreach ($tree as $item)
287    {
288      $out.= '<option value="'.$item['path'].'"';
289      if ($level==0 and $i==0) $out.= ' selected="selected"';
290      $out.= '>';
291     
292      $out.= str_repeat('&nbsp;', $level*4);
293      $out.= '- '.$item['title'].' ['.$item['nb_pictures'].']';
294     
295      $out.= '</option>';
296     
297      if (!empty($item['categories']))
298        $out.= print_tree($item['categories'], $level+1, 'select');
299       
300      $i++;
301    }
302  }
303 
304  return $out;
305}
306
307/**
308 * count pictures and cats in the selected cat
309 * @param: &array tree
310 * @param: string $path
311 * @param: &int nb pictures
312 * @param: &int nb categories
313 * @param: bool recursive
314 * @return: void
315 */
316function count_pictures_cats(&$tree, $path, &$nb_pictures, &$nb_categories, $recursive=true)
317{
318  $current = &get_current_cat($tree, $path);
319  $nb_pictures+= $current['nb_pictures'];
320  $nb_categories++;
321 
322  if ( $recursive and !empty($current['categories']) )
323  {
324    foreach ($current['categories'] as $cat)
325    {
326      count_pictures_cats($tree, $cat['path'], $nb_pictures, $nb_categories, $recursive);
327    }
328  }
329}
330
331/**
332 * test if a download method is available
333 * @return: bool
334 */
335if (!function_exists('test_remote_download'))
336{
337  function test_remote_download()
338  {
339    return function_exists('curl_init') || ini_get('allow_url_fopen');
340  }
341}
342
343/**
344 * download a remote file
345 *  - needs cURL or allow_url_fopen
346 *  - take care of SSL urls
347 *
348 * @param: string source url
349 * @param: mixed destination file (if true, file content is returned)
350 */
351if (!function_exists('download_remote_file'))
352{
353  function download_remote_file($src, $dest)
354  {
355    if (empty($src))
356    {
357      return false;
358    }
359   
360    $return = ($dest === true) ? true : false;
361   
362    /* curl */
363    if (function_exists('curl_init'))
364    {
365      if (!$return)
366      {
367        $newf = fopen($dest, "wb");
368      }
369      $ch = curl_init();
370     
371      curl_setopt($ch, CURLOPT_URL, $src);
372      curl_setopt($ch, CURLOPT_HEADER, false);
373      curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept-language: en"));
374      curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)');
375      curl_setopt($ch, CURLOPT_TIMEOUT, 30);
376      if (!ini_get('safe_mode'))
377      {
378        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
379        curl_setopt($ch, CURLOPT_MAXREDIRS, 1);
380      }
381      if (strpos($src, 'https://') !== false)
382      {
383        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
384        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
385      }
386      if (!$return)
387      {
388        curl_setopt($ch, CURLOPT_FILE, $newf);
389      }
390      else
391      {
392        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
393      }
394     
395      $out = curl_exec($ch);
396      curl_close($ch);
397     
398      if ($out === false)
399      {
400        return 'file_error';
401      }
402      else if (!$return)
403      {
404        fclose($newf);
405        return true;
406      }
407      else
408      {
409        return $out;
410      }
411    }
412    /* file get content */
413    else if (ini_get('allow_url_fopen'))
414    {
415      if (strpos($src, 'https://') !== false and !extension_loaded('openssl'))
416      {
417        return false;
418      }
419     
420      $opts = array(
421        'http' => array(
422          'method' => "GET",
423          'user_agent' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
424          'header' => "Accept-language: en",
425        )
426      );
427
428      $context = stream_context_create($opts);
429     
430      if (($file = file_get_contents($src, false, $context)) === false)
431      {
432        return 'file_error';
433      }
434     
435      if (!$return)
436      {
437        file_put_contents($dest, $file);
438        return true;
439      }
440      else
441      {
442        return $file;
443      }
444    }
445   
446    return false;
447  }
448}
449
450/**
451 * extract unique values of the specified key in a two dimensional array
452 * @param: array
453 * @param: mixed key name
454 * @return: array
455 */
456if (!function_exists('array_unique_deep'))
457{
458  function array_unique_deep(&$array, $key)
459  {
460    $values = array();
461    foreach ($array as $k1 => $row)
462    {
463      foreach ($row as $k2 => $v)
464      {
465        if ($k2 == $key)
466        {
467          $values[ $k1 ] = $v;
468          continue;
469        }
470      }
471    }
472    return array_unique($values);
473  }
474}
475
476/**
477 * search a string in array values
478 * // http://www.strangeplanet.fr/blog/dev/php-une-fonction-pour-rechercher-dans-un-tableau
479 * @param string needle
480 * @param array haystack
481 * @param bool return all instances
482 * @param bool search in PCRE mode
483 * @return key or array of keys
484 */
485if (!function_exists('array_pos'))
486{
487  function array_pos($needle, &$haystack, $match_all=false, $preg_mode=false)
488  {
489    if ($match_all) $matches = array();
490   
491    foreach ($haystack as $i => $row)
492    {
493      if (!is_array($row))
494      {
495        if (!$preg_mode)
496        {
497          if (strpos($row, $needle) !== false)
498          {
499            if (!$match_all) return $i;
500            else array_push($matches, $i);
501          }
502        }
503        else
504        {
505          if (preg_match($needle, $row) === 1)
506          {
507            if (!$match_all) return $i;
508            else array_push($matches, $i);
509          }
510        }
511      }
512    }
513   
514    if ( !$match_all or !count($matches) ) return false;
515    return $matches;
516  }
517}
Note: See TracBrowser for help on using the repository browser.