1<?php 2 3 4namespace dokuwiki\plugin\extension; 5 6class Notice 7{ 8 const INFO = 'info'; 9 const WARNING = 'warning'; 10 const ERROR = 'error'; 11 const SECURITY = 'security'; 12 13 public const ICONS = [ 14 self::INFO => 'ⓘ', 15 self::WARNING => '↯', 16 self::ERROR => '⚠', 17 self::SECURITY => '☠', 18 ]; 19 20 protected $notices = [ 21 self::INFO => [], 22 self::WARNING => [], 23 self::ERROR => [], 24 self::SECURITY => [], 25 ]; 26 27 /** @var \helper_plugin_extension */ 28 protected $helper; 29 30 /** @var Extension */ 31 protected Extension $extension; 32 33 /** 34 * Not public, use list() instead 35 * @param Extension $extension 36 */ 37 protected function __construct(Extension $extension) 38 { 39 $this->helper = plugin_load('helper', 'extension'); 40 $this->extension = $extension; 41 42 $this->checkDependencies(); 43 $this->checkConflicts(); 44 $this->checkSecurity(); 45 $this->checkFolder(); 46 $this->checkPHPVersion(); 47 $this->checkUpdateMessage(); 48 $this->checkURLChange(); 49 } 50 51 /** 52 * Get all notices for the extension 53 * 54 * @return string[][] array of notices grouped by type 55 */ 56 public static function list(Extension $extension): array 57 { 58 $self = new self($extension); 59 return $self->notices; 60 } 61 62 /** 63 * Access a language string 64 * 65 * @param string $msg 66 * @return string 67 */ 68 protected function getLang($msg) 69 { 70 return strip_tags($this->helper->getLang($msg)); // FIXME existing strings should be adjusted 71 } 72 73 /** 74 * Check that all dependencies are met 75 * @return void 76 */ 77 protected function checkDependencies() 78 { 79 if (!$this->extension->isInstalled()) return; 80 81 $dependencies = $this->extension->getDependencyList(); 82 $missing = []; 83 foreach ($dependencies as $dependency) { 84 $dep = Extension::createFromId($dependency); 85 if (!$dep->isInstalled()) $missing[] = $dep; 86 } 87 if(!$missing) return; 88 89 $this->notices[self::ERROR][] = sprintf( 90 $this->getLang('missing_dependency'), 91 join(', ', array_map(static fn(Extension $dep) => $dep->getId(true), $missing)) 92 ); 93 } 94 95 /** 96 * Check if installed dependencies are conflicting 97 * @return void 98 */ 99 protected function checkConflicts() 100 { 101 $conflicts = $this->extension->getConflictList(); 102 $found = []; 103 foreach ($conflicts as $conflict) { 104 $dep = Extension::createFromId($conflict); 105 if ($dep->isInstalled()) $found[] = $dep; 106 } 107 if(!$found) return; 108 109 $this->notices[self::WARNING][] = sprintf( 110 $this->getLang('found_conflict'), 111 join(', ', array_map(static fn(Extension $dep) => $dep->getId(true), $found)) 112 ); 113 } 114 115 /** 116 * Check for security issues 117 * @return void 118 */ 119 protected function checkSecurity() 120 { 121 if ($issue = $this->extension->getSecurityIssue()) { 122 $this->notices[self::SECURITY][] = sprintf($this->getLang('security_issue'), $issue); 123 } 124 if ($issue = $this->extension->getSecurityWarning()) { 125 $this->notices[self::SECURITY][] = sprintf($this->getLang('security_issue'), $issue); 126 } 127 } 128 129 /** 130 * Check if the extension is installed in correct folder 131 * @return void 132 */ 133 protected function checkFolder() 134 { 135 if (!$this->extension->isInWrongFolder()) return; 136 137 $this->notices[self::ERROR][] = sprintf( 138 $this->getLang('wrong_folder'), 139 basename($this->extension->getCurrentDir()), 140 basename($this->extension->getInstallDir()) 141 ); 142 } 143 144 /** 145 * Check PHP requirements 146 * @return void 147 */ 148 protected function checkPHPVersion() 149 { 150 try { 151 Installer::ensurePhpCompatibility($this->extension); 152 } catch (\Exception $e) { 153 $this->notices[self::ERROR][] = $e->getMessage(); 154 } 155 } 156 157 /** 158 * Check for update message 159 * @return void 160 */ 161 protected function checkUpdateMessage() 162 { 163 // FIXME should we only display this for installed extensions? 164 if ($msg = $this->extension->getUpdateMessage()) { 165 $this->notices[self::WARNING][] = sprintf($this->getLang('update_message'), $msg); 166 } 167 } 168 169 /** 170 * Check for URL changes 171 * @return void 172 */ 173 protected function checkURLChange() 174 { 175 if (!$this->extension->hasChangedURL()) return; 176 $this->notices[self::WARNING][] = sprintf( 177 $this->getLang('url_change'), 178 $this->extension->getDownloadURL(), 179 $this->extension->getManager()->getDownloadURL() 180 ); 181 } 182 183} 184