| 1 | <?php | 
|---|
| 2 |  | 
|---|
| 3 | class dcRepository | 
|---|
| 4 | { | 
|---|
| 5 |      public $core; | 
|---|
| 6 |      public $modules; | 
|---|
| 7 |  | 
|---|
| 8 |      protected $xml_url; | 
|---|
| 9 |      protected $data; | 
|---|
| 10 |  | 
|---|
| 11 |      public function __construct(dcModules $modules, $xml_url) | 
|---|
| 12 |      { | 
|---|
| 13 |           $this->core = $modules->core; | 
|---|
| 14 |           $this->modules = $modules; | 
|---|
| 15 |           $this->xml_url = $xml_url; | 
|---|
| 16 |      } | 
|---|
| 17 |  | 
|---|
| 18 |      public function check($force=false) | 
|---|
| 19 |      { | 
|---|
| 20 |           if (!$this->xml_url) { | 
|---|
| 21 |                return false; | 
|---|
| 22 |           } | 
|---|
| 23 |           if (($parser = dcRepositoryReader::quickParse($this->xml_url, DC_TPL_CACHE, $force)) === false) { | 
|---|
| 24 |                return false; | 
|---|
| 25 |           } | 
|---|
| 26 |  | 
|---|
| 27 |           $raw_datas = $parser->getModules(); | 
|---|
| 28 |  | 
|---|
| 29 |           uasort($raw_datas, array('self','sort')); | 
|---|
| 30 |  | 
|---|
| 31 |           $skipped = array_keys($this->modules->getDisabledModules()); | 
|---|
| 32 |           foreach ($skipped as $p_id) { | 
|---|
| 33 |                if (isset($raw_datas[$p_id])) { | 
|---|
| 34 |                     unset($raw_datas[$p_id]); | 
|---|
| 35 |                } | 
|---|
| 36 |           } | 
|---|
| 37 |  | 
|---|
| 38 |           $updates = array(); | 
|---|
| 39 |           $current = $this->modules->getModules(); | 
|---|
| 40 |           foreach ($current as $p_id => $p_infos) { | 
|---|
| 41 |                if (isset($raw_datas[$p_id])) { | 
|---|
| 42 |                     if (self::compare($raw_datas[$p_id]['version'],$p_infos['version'],'>')) { | 
|---|
| 43 |                          $updates[$p_id] = $raw_datas[$p_id]; | 
|---|
| 44 |                          $updates[$p_id]['root'] = $p_infos['root']; | 
|---|
| 45 |                          $updates[$p_id]['root_writable'] = $p_infos['root_writable']; | 
|---|
| 46 |                          $updates[$p_id]['current_version'] = $p_infos['version']; | 
|---|
| 47 |                     } | 
|---|
| 48 |                     unset($raw_datas[$p_id]); | 
|---|
| 49 |                } | 
|---|
| 50 |           } | 
|---|
| 51 |  | 
|---|
| 52 |           $this->data = array( | 
|---|
| 53 |                'new'     => $raw_datas, | 
|---|
| 54 |                'update'  => $updates | 
|---|
| 55 |           ); | 
|---|
| 56 |  | 
|---|
| 57 |           return true; | 
|---|
| 58 |      } | 
|---|
| 59 |  | 
|---|
| 60 |      public function get($update=false) | 
|---|
| 61 |      { | 
|---|
| 62 |           return $this->data[$update ? 'update' : 'new']; | 
|---|
| 63 |      } | 
|---|
| 64 |  | 
|---|
| 65 |      public function search($pattern) | 
|---|
| 66 |      { | 
|---|
| 67 |           $result = array(); | 
|---|
| 68 |  | 
|---|
| 69 |           # Split query into small clean words | 
|---|
| 70 |           $patterns = explode(' ', $pattern); | 
|---|
| 71 |           array_walk($patterns, array('dcRepository','sanitize')); | 
|---|
| 72 |  | 
|---|
| 73 |           # For each modules | 
|---|
| 74 |           foreach ($this->data['new'] as $id => $module) { | 
|---|
| 75 |  | 
|---|
| 76 |                # Split modules infos into small clean word | 
|---|
| 77 |                $subjects = explode(' ', $id.' '.$module['name'].' '.$module['desc']); | 
|---|
| 78 |                array_walk($subjects, array('dcRepository','sanitize')); | 
|---|
| 79 |  | 
|---|
| 80 |                # Check contents | 
|---|
| 81 |                if (!($nb = preg_match_all('/('.implode('|', $patterns).')/', implode(' ', $subjects)))) { | 
|---|
| 82 |                     continue; | 
|---|
| 83 |                } | 
|---|
| 84 |  | 
|---|
| 85 |                # Add module to result | 
|---|
| 86 |                if (!isset($sorter[$id])) { | 
|---|
| 87 |                     $sorter[$id] = 0; | 
|---|
| 88 |                     $result[$id] = $module; | 
|---|
| 89 |                } | 
|---|
| 90 |  | 
|---|
| 91 |                # Increment matches count | 
|---|
| 92 |                $sorter[$id] += $nb; | 
|---|
| 93 |                $result[$id]['accuracy'] = $sorter[$id]; | 
|---|
| 94 |           } | 
|---|
| 95 |           # Sort response by matches count | 
|---|
| 96 |           if (!empty($result)) { | 
|---|
| 97 |                array_multisort($sorter, SORT_DESC, $result); | 
|---|
| 98 |           } | 
|---|
| 99 |           return $result; | 
|---|
| 100 |      } | 
|---|
| 101 |  | 
|---|
| 102 |      public function process($url, $dest) | 
|---|
| 103 |      { | 
|---|
| 104 |           $this->download($url, $dest); | 
|---|
| 105 |           return $this->install($dest); | 
|---|
| 106 |      } | 
|---|
| 107 |  | 
|---|
| 108 |      public function download($url, $dest) | 
|---|
| 109 |      { | 
|---|
| 110 |           try { | 
|---|
| 111 |                $client = netHttp::initClient($url, $path); | 
|---|
| 112 |                $client->setUserAgent(self::agent()); | 
|---|
| 113 |                $client->useGzip(false); | 
|---|
| 114 |                $client->setPersistReferers(false); | 
|---|
| 115 |                $client->setOutput($dest); | 
|---|
| 116 |                $client->get($path); | 
|---|
| 117 |                unset($client); | 
|---|
| 118 |           } | 
|---|
| 119 |           catch (Exception $e) { | 
|---|
| 120 |                unset($client); | 
|---|
| 121 |                throw new Exception(__('An error occurred while downloading the file.')); | 
|---|
| 122 |           } | 
|---|
| 123 |      } | 
|---|
| 124 |  | 
|---|
| 125 |      public function install($path) | 
|---|
| 126 |      { | 
|---|
| 127 |           return dcModules::installPackage($path, $this->modules); | 
|---|
| 128 |      } | 
|---|
| 129 |  | 
|---|
| 130 |      public static function agent() | 
|---|
| 131 |      { | 
|---|
| 132 |           return sprintf('Dotclear/%s)', DC_VERSION); | 
|---|
| 133 |      } | 
|---|
| 134 |  | 
|---|
| 135 |      public static function sanitize(&$str, $_) | 
|---|
| 136 |      { | 
|---|
| 137 |           $str = strtolower(preg_replace('/[^A-Za-z0-9]/', '', $str)); | 
|---|
| 138 |      } | 
|---|
| 139 |  | 
|---|
| 140 |      private static function compare($v1,$v2,$op) | 
|---|
| 141 |      { | 
|---|
| 142 |           $v1 = preg_replace('!-r(\d+)$!','-p$1',$v1); | 
|---|
| 143 |           $v2 = preg_replace('!-r(\d+)$!','-p$1',$v2); | 
|---|
| 144 |           return version_compare($v1,$v2,$op); | 
|---|
| 145 |      } | 
|---|
| 146 |  | 
|---|
| 147 |      private static function sort($a,$b) | 
|---|
| 148 |      { | 
|---|
| 149 |           $c = strtolower($a['id']);  | 
|---|
| 150 |           $d = strtolower($b['id']);  | 
|---|
| 151 |           if ($c == $d) {  | 
|---|
| 152 |                return 0;  | 
|---|
| 153 |           }  | 
|---|
| 154 |           return ($c < $d) ? -1 : 1;  | 
|---|
| 155 |      } | 
|---|
| 156 | } | 
|---|