1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8/** 9 * Tiki_Profile_List 10 * 11 */ 12class Tiki_Profile_List 13{ 14 function getSources() 15 { 16 global $prefs; 17 $raw = explode("\n", $prefs['profile_sources']); 18 $raw = array_map('trim', $raw); 19 $sources = []; 20 21 foreach ($raw as $source) { 22 if (! empty($source)) { 23 $file = $this->getCacheLocation($source); 24 $last = $this->getCacheLastUpdate($source); 25 $short = dirname($source); 26 $sources[] = [ 27 'url' => $source, 28 'domain' => (0 === strpos($short, 'http://')) ? substr($short, 7) : $short, 29 'short' => $short, 30 'status' => ($last && filesize($file)) ? 'open' : 'closed', 31 'lastupdate' => $last, 32 'formatted' => $last ? date('Y-m-d H:i:s', $last) : '' ]; 33 } 34 } 35 36 return $sources; 37 } 38 39 function refreshCache($path) 40 { 41 global $tikilib; 42 $file = $this->getCacheLocation($path); 43 44 // Replace existing with blank file 45 if (file_exists($file)) { 46 unlink($file); 47 } 48 touch($file); 49 50 $content = $tikilib->httprequest($path); 51 52 $parts = explode("\n", $content); 53 $parts = array_map('trim', $parts); 54 $good = false; 55 56 foreach ($parts as $line) { 57 // All lines contain 3 entries 58 if (empty($line)) { 59 continue; 60 } 61 if (substr_count($line, "\t") != 2) { 62 return false; 63 } 64 65 $good = true; 66 } 67 68 // A valid file has at least one profile 69 if (! $good) { 70 return false; 71 } 72 73 file_put_contents($file, $content . "\n"); 74 75 return true; 76 } 77 78 function getCategoryList($source = '') 79 { 80 $category_list = []; 81 82 $sources = $this->getSources(); 83 84 foreach ($sources as $s) { 85 if ($source && $s['url'] != $source) { 86 continue; 87 } 88 89 if (! $s['lastupdate']) { 90 continue; 91 } 92 93 $fp = fopen($this->getCacheLocation($s['url']), 'r'); 94 95 while (false !== $row = fgetcsv($fp, 200, "\t")) { 96 $c = $row[0]; 97 if ($c) { 98 $category_list[] = $c; 99 } 100 } 101 } 102 103 natsort($category_list); 104 return(array_unique($category_list)); 105 } 106 107 function getList($source = '', $categories = [], $profilename = '') 108 { 109 $installer = new Tiki_Profile_Installer; 110 $list = []; 111 112 $sources = $this->getSources(); 113 114 foreach ($sources as $s) { 115 if ($source && $s['url'] != $source) { 116 continue; 117 } 118 119 if (! $s['lastupdate']) { 120 continue; 121 } 122 123 $fp = fopen($this->getCacheLocation($s['url']), 'r'); 124 125 while (false !== $row = fgetcsv($fp, 200, "\t")) { 126 if (count($row) != 3) { 127 continue; 128 } 129 130 list($c, $t, $i) = $row; 131 132 $key = "{$s['url']}#{$i}"; 133 134 if ($profilename && stripos($i, $profilename) === false) { 135 continue; 136 } 137 138 if (array_key_exists($key, $list)) { 139 $list[$key]['categories'][] = $c; 140 } else { 141 $list[$key] = [ 142 'domain' => $s['domain'], 143 'categories' => [$c], 144 'name' => $i, 145 'installed' => $installer->isKeyInstalled($s['domain'], $i), 146 ]; 147 } 148 } 149 150 fclose($fp); 151 152 // Apply category filter 153 foreach ($list as $pkey => $profile) { 154 $in = true; // If there are no required categories, don't filter anything. 155 if (! empty($categories)) { 156 foreach ($categories as $category) { 157 $in = false; // Start assuming this required category isn't in this profile's categories 158 foreach ($profile['categories'] as $pcategory) { 159 if ($category == $pcategory) { 160 $in = true; 161 break; 162 } 163 } 164 if (! $in) { 165 break; 166 } 167 } 168 } 169 if (! $in) { 170 unset($list[$pkey]); 171 } 172 } 173 } 174 175 return array_values($list); 176 } 177 178 private function getCacheLocation($path) 179 { 180 $hash = md5($path); 181 return "temp/cache/profile$hash"; 182 } 183 184 private function getCacheLastUpdate($path) 185 { 186 $file = $this->getCacheLocation($path); 187 if (! file_exists($file)) { 188 return 0; 189 } 190 191 return filemtime($file); 192 } 193} 194