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

Last change on this file since 17225 was 17225, checked in by ddtddt, 12 years ago

[extensions] - pbase2piwigo - new extension by mistic - first release

File size: 10.0 KB
Line 
1<?php
2if (!defined('PBASE_PATH')) 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 * test if a download method is available
309 * @return: bool
310 */
311function test_remote_download()
312{
313  return function_exists('curl_init') || ini_get('allow_url_fopen');
314}
315
316/**
317 * download a remote file
318 * @param: string source
319 * @param: string destination
320 * @return: bool
321 */
322function download_remote_file($src, $dest)
323{
324  if (function_exists('curl_init'))
325  {
326    $newf = fopen($dest, "wb");
327    $ch = curl_init();
328   
329    curl_setopt($ch, CURLOPT_URL, $src);
330    curl_setopt($ch, CURLOPT_HEADER, 0);
331    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept-language: en"));
332    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)');
333    curl_setopt($ch, CURLOPT_FILE, $newf);
334   
335    if (curl_exec($ch) === false)
336    {
337      return 'file_error';
338    }
339   
340    curl_close($ch);
341    fclose($newf);
342   
343    return true;
344  }
345  else if (ini_get('allow_url_fopen'))
346  {
347    $opts = array(
348      'http' => array(
349        'method' => "GET",
350        'user_agent' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
351        'header' => "Accept-language: en",
352      )
353    );
354
355    $context = stream_context_create($opts);
356   
357    if (($file = file_get_contents($src, false, $context)) === false)
358    {
359      return 'file_error';
360    }
361    file_put_contents($dest, $file);
362   
363    return true;
364  }
365 
366  return false;
367}
368
369/**
370 * count pictures and cats in the selected cat
371 * @param: &array tree
372 * @param: string $path
373 * @param: &int nb pictures
374 * @param: &int nb categories
375 * @param: bool recursive
376 * @return: void
377 */
378function count_pictures_cats(&$tree, $path, &$nb_pictures, &$nb_categories, $recursive=true)
379{
380  $current = &get_current_cat($tree, $path);
381  $nb_pictures+= $current['nb_pictures'];
382  $nb_categories++;
383 
384  if ( $recursive and !empty($current['categories']) )
385  {
386    foreach ($current['categories'] as $cat)
387    {
388      count_pictures_cats($tree, $cat['path'], $nb_pictures, $nb_categories, $recursive);
389    }
390  }
391}
392
393/**
394 * extract unique values of the specified key in a two dimensional array
395 * @param: array
396 * @param: mixed key name
397 * @return: array
398 */
399function array_unique_deep(&$array, $key)
400{
401  $values = array();
402  foreach ($array as $k1 => $row)
403  {
404    foreach ($row as $k2 => $v)
405    {
406      if ($k2 == $key)
407      {
408        $values[ $k1 ] = $v;
409        continue;
410      }
411    }
412  }
413  return array_unique($values);
414}
415
416/**
417 * search a string in array values
418 * // http://www.strangeplanet.fr/blog/dev/php-une-fonction-pour-rechercher-dans-un-tableau
419 * @param string needle
420 * @param array haystack
421 * @param bool return all instances
422 * @param bool search in PCRE mode
423 * @return key or array of keys
424 */
425function array_pos($needle, &$haystack, $match_all=false, $preg_mode=false)
426{
427  if ($match_all) $matches = array();
428 
429  foreach ($haystack as $i => $row)
430  {
431    if (!is_array($row))
432    {
433      if (!$preg_mode)
434      {
435        if (strpos($row, $needle) !== false)
436        {
437          if (!$match_all) return $i;
438          else array_push($matches, $i);
439        }
440      }
441      else
442      {
443        if (preg_match($needle, $row) === 1)
444        {
445          if (!$match_all) return $i;
446          else array_push($matches, $i);
447        }
448      }
449    }
450  }
451 
452  if ( !$match_all or !count($matches) ) return false;
453  return $matches;
454}
455
456?>
Note: See TracBrowser for help on using the repository browser.