Dotclear

source: inc/core/class.dc.repository.php @ 2214:6d7d4c3f60d9

Revision 2214:6d7d4c3f60d9, 6.0 KB checked in by Denis Jean-Chirstian <contact@…>, 12 years ago (diff)

Document and clean up dcRepository classes

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
6# Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14/**
15@ingroup DC_CORE
16@brief Repository modules XML feed reader
17
18Provides an object to parse XML feed of modules from repository.
19*/
20class dcRepository
21{
22     /** @var  object    dcCore instance */
23     public $core;
24     /** @var  object    dcModules instance */
25     public $modules;
26
27     /** @var  string    User agent used to query repository */
28     protected $user_agent = 'DotClear.org RepoBrowser/0.1';
29     /** @var  string    XML feed URL */
30     protected $xml_url;
31     /** @var  array     Array of new/update modules from repository */
32     protected $data;
33
34     /**
35      * Constructor.
36      *
37      * @param object    $modules       dcModules instance
38      * @param string    $xml_url       XML feed URL
39      */
40     public function __construct(dcModules $modules, $xml_url)
41     {
42          $this->core = $modules->core;
43          $this->modules = $modules;
44          $this->xml_url = $xml_url;
45          $this->user_agent = sprintf('Dotclear/%s)', DC_VERSION);
46     }
47
48     /**
49      * Check repository.
50      *
51      * @param boolean   $force         Force query repository
52      * @return     boolean   True if get feed or cache
53      */
54     public function check($force=false)
55     {
56          if (!$this->xml_url) {
57               return false;
58          }
59          if (($parser = dcRepositoryReader::quickParse($this->xml_url, DC_TPL_CACHE, $force)) === false) {
60               return false;
61          }
62
63          $raw_datas = $parser->getModules();
64
65          uasort($raw_datas, array('self','sort'));
66
67          $skipped = array_keys($this->modules->getDisabledModules());
68          foreach ($skipped as $p_id) {
69               if (isset($raw_datas[$p_id])) {
70                    unset($raw_datas[$p_id]);
71               }
72          }
73
74          $updates = array();
75          $current = $this->modules->getModules();
76          foreach ($current as $p_id => $p_infos) {
77               if (isset($raw_datas[$p_id])) {
78                    if (self::compare($raw_datas[$p_id]['version'],$p_infos['version'],'>')) {
79                         $updates[$p_id] = $raw_datas[$p_id];
80                         $updates[$p_id]['root'] = $p_infos['root'];
81                         $updates[$p_id]['root_writable'] = $p_infos['root_writable'];
82                         $updates[$p_id]['current_version'] = $p_infos['version'];
83                    }
84                    unset($raw_datas[$p_id]);
85               }
86          }
87
88          $this->data = array(
89               'new'     => $raw_datas,
90               'update'  => $updates
91          );
92
93          return true;
94     }
95
96     /**
97      * Get a list of modules.
98      *
99      * @param boolean   $update   True to get update modules, false for new ones
100      * @return     array     List of update/new modules
101      */
102     public function get($update=false)
103     {
104          return $this->data[$update ? 'update' : 'new'];
105     }
106
107     /**
108      * Search a module.
109      *
110      * Search string is cleaned, split and compare to split:
111      * - module id and clean id,
112      * - module name, clean name,
113      * - module desccription.
114      *
115      * Every time a part of query is find on module,
116      * result accuracy grow. Result is sorted by acuracy.
117      *
118      * @param string    $pattern  String to search
119      * @return     array     Match modules
120      */
121     public function search($pattern)
122     {
123          $result = array();
124
125          # Split query into small clean words
126          $patterns = explode(' ', $pattern);
127          array_walk($patterns, array('dcRepository','sanitize'));
128
129          # For each modules
130          foreach ($this->data['new'] as $id => $module) {
131
132               # Split modules infos into small clean word
133               $subjects = explode(' ', $id.' '.$module['name'].' '.$module['desc']);
134               array_walk($subjects, array('dcRepository','sanitize'));
135
136               # Check contents
137               if (!($nb = preg_match_all('/('.implode('|', $patterns).')/', implode(' ', $subjects), $_))) {
138                    continue;
139               }
140
141               # Add module to result
142               if (!isset($sorter[$id])) {
143                    $sorter[$id] = 0;
144                    $result[$id] = $module;
145               }
146
147               # Increment matches count
148               $sorter[$id] += $nb;
149               $result[$id]['accuracy'] = $sorter[$id];
150          }
151          # Sort response by matches count
152          if (!empty($result)) {
153               array_multisort($sorter, SORT_DESC, $result);
154          }
155          return $result;
156     }
157
158     /**
159      * Quick download and install module.
160      *
161      * @param string    $url Module package URL
162      * @param string    $dest     Path to install module
163      * @return     integer        1 = installed, 2 = update
164      */
165     public function process($url, $dest)
166     {
167          $this->download($url, $dest);
168          return $this->install($dest);
169     }
170
171     /**
172      * Download a module.
173      *
174      * @param string    $url Module package URL
175      * @param string    $dest     Path to put module package
176      */
177     public function download($url, $dest)
178     {
179          try {
180               $client = netHttp::initClient($url, $path);
181               $client->setUserAgent(self::agent());
182               $client->useGzip(false);
183               $client->setPersistReferers(false);
184               $client->setOutput($dest);
185               $client->get($path);
186               unset($client);
187          }
188          catch (Exception $e) {
189               unset($client);
190               throw new Exception(__('An error occurred while downloading the file.'));
191          }
192     }
193
194     /**
195      * Install a previously downloaded module.
196      *
197      * @param string    $path     Module package URL
198      * @param string    $path     Path to module package
199      * @return     integer        1 = installed, 2 = update
200      */
201     public function install($path)
202     {
203          return dcModules::installPackage($path, $this->modules);
204     }
205
206     /**
207      * User Agent String.
208      *
209      * @param string    $str      User agent string
210      */
211     public function agent($str)
212     {
213          $this->user_agent = $str;
214     }
215
216     /**
217      * Sanitize string.
218      *
219      * @param string    $str      String to sanitize
220      * @param null $_        Unused    param
221      */
222     public static function sanitize(&$str, $_)
223     {
224          $str = strtolower(preg_replace('/[^A-Za-z0-9]/', '', $str));
225     }
226
227     /**
228      * Compare version.
229      *
230      * @param string    $v1       Version
231      * @param string    $v2       Version
232      * @param string    $op       Comparison operator
233      * @return     boolean   True is comparison is true, dude!
234      */
235     private static function compare($v1, $v2, $op)
236     {
237          return version_compare(
238               preg_replace('!-r(\d+)$!', '-p$1', $v1), 
239               preg_replace('!-r(\d+)$!', '-p$1', $v2), 
240               $op
241          );
242     }
243
244     /**
245      * Sort modules list.
246      *
247      * @param array     $a        A module
248      * @param array     $b        A module
249      * @return     integer
250      */
251     private static function sort($a,$b)
252     {
253          $c = strtolower($a['id']); 
254          $d = strtolower($b['id']); 
255          if ($c == $d) { 
256               return 0; 
257          } 
258          return ($c < $d) ? -1 : 1; 
259     }
260}
Note: See TracBrowser for help on using the repository browser.

Sites map