Dotclear

source: inc/core/class.dc.store.php @ 2216:91f485a16187

Revision 2216:91f485a16187, 6.0 KB checked in by Denis Jean-Chirstian <contact@…>, 12 years ago (diff)

Rename dcRepository to dcStore because of dotAddict used this name

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 dcStore
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          $this->check();
48     }
49
50     /**
51      * Check repository.
52      *
53      * @param boolean   $force         Force query repository
54      * @return     boolean   True if get feed or cache
55      */
56     public function check($force=false)
57     {
58          if (!$this->xml_url) {
59               return false;
60          }
61          if (($parser = dcStoreReader::quickParse($this->xml_url, DC_TPL_CACHE, $force)) === false) {
62               return false;
63          }
64
65          $raw_datas = $parser->getModules();
66
67          uasort($raw_datas, array('self','sort'));
68
69          $skipped = array_keys($this->modules->getDisabledModules());
70          foreach ($skipped as $p_id) {
71               if (isset($raw_datas[$p_id])) {
72                    unset($raw_datas[$p_id]);
73               }
74          }
75
76          $updates = array();
77          $current = $this->modules->getModules();
78          foreach ($current as $p_id => $p_infos) {
79               if (isset($raw_datas[$p_id])) {
80                    if (self::compare($raw_datas[$p_id]['version'],$p_infos['version'],'>')) {
81                         $updates[$p_id] = $raw_datas[$p_id];
82                         $updates[$p_id]['root'] = $p_infos['root'];
83                         $updates[$p_id]['root_writable'] = $p_infos['root_writable'];
84                         $updates[$p_id]['current_version'] = $p_infos['version'];
85                    }
86                    unset($raw_datas[$p_id]);
87               }
88          }
89
90          $this->data = array(
91               'new'     => $raw_datas,
92               'update'  => $updates
93          );
94
95          return true;
96     }
97
98     /**
99      * Get a list of modules.
100      *
101      * @param boolean   $update   True to get update modules, false for new ones
102      * @return     array     List of update/new modules
103      */
104     public function get($update=false)
105     {
106          return $this->data[$update ? 'update' : 'new'];
107     }
108
109     /**
110      * Search a module.
111      *
112      * Search string is cleaned, split and compare to split:
113      * - module id and clean id,
114      * - module name, clean name,
115      * - module desccription.
116      *
117      * Every time a part of query is find on module,
118      * result accuracy grow. Result is sorted by accuracy.
119      *
120      * @param string    $pattern  String to search
121      * @return     array     Match modules
122      */
123     public function search($pattern)
124     {
125          $result = array();
126
127          # Split query into small clean words
128          $patterns = explode(' ', $pattern);
129          array_walk($patterns, array('dcStore','sanitize'));
130
131          # For each modules
132          foreach ($this->data['new'] as $id => $module) {
133
134               # Split modules infos into small clean word
135               $subjects = explode(' ', $id.' '.$module['name'].' '.$module['desc']);
136               array_walk($subjects, array('dcStore','sanitize'));
137
138               # Check contents
139               if (!($nb = preg_match_all('/('.implode('|', $patterns).')/', implode(' ', $subjects), $_))) {
140                    continue;
141               }
142
143               # Add module to result
144               if (!isset($sorter[$id])) {
145                    $sorter[$id] = 0;
146                    $result[$id] = $module;
147               }
148
149               # Increment matches count
150               $sorter[$id] += $nb;
151               $result[$id]['accuracy'] = $sorter[$id];
152          }
153          # Sort response by matches count
154          if (!empty($result)) {
155               array_multisort($sorter, SORT_DESC, $result);
156          }
157          return $result;
158     }
159
160     /**
161      * Quick download and install module.
162      *
163      * @param string    $url Module package URL
164      * @param string    $dest     Path to install module
165      * @return     integer        1 = installed, 2 = update
166      */
167     public function process($url, $dest)
168     {
169          $this->download($url, $dest);
170          return $this->install($dest);
171     }
172
173     /**
174      * Download a module.
175      *
176      * @param string    $url Module package URL
177      * @param string    $dest     Path to put module package
178      */
179     public function download($url, $dest)
180     {
181          try {
182               $client = netHttp::initClient($url, $path);
183               $client->setUserAgent(self::agent());
184               $client->useGzip(false);
185               $client->setPersistReferers(false);
186               $client->setOutput($dest);
187               $client->get($path);
188               unset($client);
189          }
190          catch (Exception $e) {
191               unset($client);
192               throw new Exception(__('An error occurred while downloading the file.'));
193          }
194     }
195
196     /**
197      * Install a previously downloaded module.
198      *
199      * @param string    $path     Module package URL
200      * @param string    $path     Path to module package
201      * @return     integer        1 = installed, 2 = update
202      */
203     public function install($path)
204     {
205          return dcModules::installPackage($path, $this->modules);
206     }
207
208     /**
209      * User Agent String.
210      *
211      * @param string    $str      User agent string
212      */
213     public function agent($str)
214     {
215          $this->user_agent = $str;
216     }
217
218     /**
219      * Sanitize string.
220      *
221      * @param string    $str      String to sanitize
222      * @param null $_        Unused    param
223      */
224     public static function sanitize(&$str, $_)
225     {
226          $str = strtolower(preg_replace('/[^A-Za-z0-9]/', '', $str));
227     }
228
229     /**
230      * Compare version.
231      *
232      * @param string    $v1       Version
233      * @param string    $v2       Version
234      * @param string    $op       Comparison operator
235      * @return     boolean   True is comparison is true, dude!
236      */
237     private static function compare($v1, $v2, $op)
238     {
239          return version_compare(
240               preg_replace('!-r(\d+)$!', '-p$1', $v1), 
241               preg_replace('!-r(\d+)$!', '-p$1', $v2), 
242               $op
243          );
244     }
245
246     /**
247      * Sort modules list.
248      *
249      * @param array     $a        A module
250      * @param array     $b        A module
251      * @return     integer
252      */
253     private static function sort($a,$b)
254     {
255          $c = strtolower($a['id']); 
256          $d = strtolower($b['id']); 
257          if ($c == $d) { 
258               return 0; 
259          } 
260          return ($c < $d) ? -1 : 1; 
261     }
262}
Note: See TracBrowser for help on using the repository browser.

Sites map