1<?php 2/** 3 * PHP_UML 4 * 5 * PHP version 5 6 * 7 * @category PHP 8 * @package PHP_UML 9 * @author Baptiste Autin <ohlesbeauxjours@yahoo.fr> 10 * @license http://www.gnu.org/licenses/lgpl.html LGPL License 3 11 * @version SVN: $Revision: 180 $ 12 * @link http://pear.php.net/package/PHP_UML 13 * @since $Date: 2012-05-12 19:33:59 +0200 (sam., 12 mai 2012) $ 14 */ 15 16/** 17 * General class for an renderer in the HtmlNew implementation 18 * 19 * @category PHP 20 * @package PHP_UML 21 * @subpackage Output 22 * @subpackage HtmlNew 23 * @author Baptiste Autin <ohlesbeauxjours@yahoo.fr> 24 * @license http://www.gnu.org/licenses/lgpl.html LGPL License 3 25 */ 26abstract class PHP_UML_Output_HtmlNew_DocElement extends PHP_UML_Output_ApiRenderer 27{ 28 const FILE_EXT = 'htm'; 29 30 const RESOURCES_DIRNAME = '$resources'; 31 const HELP_FILENAME = 'help'; 32 const INDEX_FILENAME = 'index'; 33 const INDEXALL_FILENAME = 'index-all'; 34 const MENU_FILENAME = 'menu'; 35 const JS_MAIN_NAME = 'MainList'; 36 const TEMPLATES_DIRNAME = 'templates'; 37 38 /** 39 * Constructor 40 * 41 * @param PHP_UML_Output_ExporterAPI $exporter Reference to an exporter 42 */ 43 public function __construct(PHP_UML_Output_ExporterAPI $exporter) 44 { 45 parent::__construct($exporter); 46 $this->mainTpl = $this->getTemplate('main.htm'); 47 } 48 49 protected function getDescription(PHP_UML_Metamodel_Stereotype $s, $annotatedElement='') 50 { 51 $tag = PHP_UML_Metamodel_Helper::getStereotypeTag($s, 'description'); 52 if (!is_null($tag)) 53 return nl2br(htmlspecialchars($tag->value)); 54 else 55 return ''; 56 } 57 58 /** 59 * Renders the operation's parameters, as a comma-sep list, between brackets 60 * 61 * @param PHP_UML_Metamodel_Operation $operation The operation 62 * @param bool $withType If true, adds an hyperlink 63 * 64 * @return string 65 */ 66 protected function getParameterList(PHP_UML_Metamodel_Operation $operation, $withType = false) 67 { 68 $n = count($operation->ownedParameter); 69 $pieces = array(); 70 for ($i=0; $i<$n; $i++) { 71 $parameter = $operation->ownedParameter[$i]; 72 if (substr($parameter->direction, 0, 2)=='in') { 73 $str = ''; 74 if ($withType && isset($parameter->type)) { 75 if (is_object($parameter->type)) 76 $str .= $this->getLinkTo($parameter->type).' '; 77 else 78 $str .= $this->displayUnresolved($parameter->type); 79 } 80 if ($parameter->direction=='inout') { 81 $str .= '&'; 82 } 83 $str .= $parameter->name; 84 $str .= $this->getDefaultValue($parameter); 85 $pieces[] = $str; 86 } 87 } 88 return '('.implode(', ', $pieces).')'; 89 } 90 91 protected function getDefaultValue(PHP_UML_Metamodel_TypedElement $obj) 92 { 93 if ($obj->default!='') 94 return '<span class="defVal"> = '.htmlentities($obj->default, ENT_QUOTES).'</span>'; 95 else 96 return ''; 97 } 98 99 /** 100 * Renders a HTML hyperlink towards a given element 101 * (since datatypes don't own to a "package", we suppose they are located in 102 * the top package) 103 * 104 * @param PHP_UML_Metamodel_Classifier $t The element 105 * @param string $cssStyle CSS style to use 106 * 107 * @return string 108 */ 109 protected function getLinkTo(PHP_UML_Metamodel_Classifier $t, $cssStyle='link') 110 { 111 $loc = ''; 112 $ns = ''; 113 if (isset($t->package)) { 114 $loc = $this->getAbsPath($t->package); 115 $ns = $this->getAbsPath($t->package, self::T_NAMESPACE); 116 } 117 return '<a href="'.$this->getContextPackage()->rpt.$loc.self::getObjPrefix($t).$t->name.'.'. 118 self::FILE_EXT.'" class="'.$cssStyle.'">'.$ns.$t->name.'</a>'; 119 } 120 121 /** 122 * Renders an unresolved type as an HTML span 123 * 124 * @param string $type Type, provided as a string 125 * 126 * @return string 127 */ 128 protected function displayUnresolved($type) 129 { 130 return '<span class="link">'.$type.'</span> '; 131 } 132 133 134 /** 135 * Renders the properties of a given stereotype as an HTML list (LI tags). 136 * Docblocks in $ignoredTag are not shown, as well as "return" tag with only a type 137 * 138 * @param PHP_UML_Metamodel_Stereotype $s A stereotype 139 * 140 * @return string 141 */ 142 protected function getTagsAsList(PHP_UML_Metamodel_Stereotype $s) 143 { 144 $str = ''; 145 foreach ($s->ownedAttribute as $tag) { 146 if (!(in_array($tag->name, $this->ignoredTag) || ($tag->name=='return' && strpos($tag->value, ' ')===false))) { 147 if ($tag->name!='description') { 148 $str .= '<li class="smaller">'; 149 $str .= '@'.$tag->name.' '; 150 } else { 151 $str .= '<li>'; 152 } 153 if (strlen($tag->value)>0) 154 $str .= nl2br(htmlspecialchars($tag->value)); 155 $str .= '</li>'; 156 } 157 } 158 return $str; 159 } 160 161 162 /** 163 * Renders the block "Properties" of a package or a class as HTML 164 * 165 * @param PHP_UML_Metamodel_NamedElement $p A classifier/a package 166 * 167 * @return string 168 */ 169 protected function getPropertyBlock(PHP_UML_Metamodel_NamedElement $p) 170 { 171 if (empty($p->ownedAttribute)) 172 return ''; 173 174 $str = '<h2>Properties</h2>'; 175 $str .= '<ul class="summary">'; 176 foreach ($p->ownedAttribute as $o) { 177 $str .= '<li class="Collapsed" id="'.$this->generatePropertyId($o).'">'; 178 $str .= '<a href="javascript:void(0);" class="'. 179 $this->getPropertyStyle($o->visibility).'" target="main">'. 180 $o->name.'</a>'; 181 182 $str .= '<ul class="description"><li>'; 183 $str .= ucfirst($o->visibility).' '; 184 if (!$o->isInstantiable) 185 $str .= 'static '; 186 if ($o->isReadOnly) 187 $str .= 'const '; 188 if (is_object($o->type)) 189 $str .= $this->getLinkTo($o->type).' '; 190 else 191 $str .= $this->displayUnresolved($o->type); 192 $str .= '<span class="smallTitle">'.$o->name.'</span>'.$this->getDefaultValue($o).'</li>'; 193 if (!is_null($o->description)) { 194 $str .= $this->getTagsAsList($o->description); 195 } 196 $str .= $this->getFileInfo($o); 197 $str .= '</ul>'; 198 199 $str .= '</li>'; 200 } 201 $str .= '</ul>'; 202 return $str; 203 } 204 205 /** 206 * Renders the block "Function" of a package or a classifier as HTML 207 * 208 * @param PHP_UML_Metamodel_NamedElement $p A classifier or a package 209 * 210 * @return string 211 */ 212 protected function getFunctionBlock(PHP_UML_Metamodel_NamedElement $p) 213 { 214 if (empty($p->ownedOperation)) 215 return''; 216 217 $str = '<h2>Functions</h2>'; 218 $str .= '<ul class="summary">'; 219 foreach ($p->ownedOperation as $o) { 220 $fullName = $this->getParameterList($o, true); 221 222 $str .= '<li class="Collapsed" id="'.$this->generateFunctionId($o).'">'; 223 $str .= '<a href="javascript:void(0);" class="'.$this->getFunctionStyle($o->visibility); 224 if ($o->isAbstract) 225 $str .= ' abstract'; 226 $str .= '" target="main">'.$o->name.'</a>'.$fullName; 227 228 $str .= '<ul class="description"><li>'; 229 $str .= ucfirst($o->visibility).' '; 230 if (!$o->isInstantiable) 231 $str .= 'static '; 232 if ($o->isAbstract) 233 $str .= 'abstract '; 234 $return = $this->getReturnParam($o); 235 if (!empty($return)) { 236 if (is_object($return->type)) 237 $str .= $this->getLinkTo($return->type).' '; 238 else 239 $str .= $this->displayUnresolved($return->type); 240 } 241 $str .= '<span class="smallTitle">'.$o->name.'</span>'.$fullName.'</li>'; 242 243 if (!is_null($o->description)) { 244 $str .= $this->getTagsAsList($o->description); 245 } 246 foreach ($this->getAllImplemented($p) as $ai) { 247 foreach ($ai->ownedOperation as $aiO) { 248 if ($aiO->name == $o->name && !empty($aiO->description)) { 249 $txt = $this->getDescription($aiO->description, $aiO->id); 250 if ($txt!='') 251 $str .= '<li>'.$txt.'<br/><span class="note">(copied from interface '.$this->getLinkTo($ai).')</span></li>'; 252 } 253 } 254 } 255 foreach ($this->getAllInherited($p) as $ai) { 256 foreach ($ai->ownedOperation as $aiO) { 257 if ($aiO->name == $o->name && !empty($aiO->description)) { 258 $txt = $this->getDescription($aiO->description, $aiO->id); 259 if ($txt!='') 260 $str .= '<li>'.$txt.'<br/><span class="note">(copied from class '.$this->getLinkTo($ai).')</span></li>'; 261 } 262 } 263 } 264 $str .= $this->getFileInfo($o); 265 $str .= '</ul>'; 266 267 $str .= '</li>'; 268 } 269 $str .= '</ul>'; 270 return $str; 271 } 272 273 /** 274 * Returns the HTML for the link "Package" in the navigation bar 275 * 276 * @param string $rel A prefix to add to the hyperlink (eg: ../) 277 * 278 * @return string 279 */ 280 protected function getNavigParentPackage($rel='') 281 { 282 return '<li><a href="'.$rel.self::PACKAGE_FILENAME.'.'.self::FILE_EXT.'" class="top">Package</a></li>'; 283 } 284 285 /** 286 * Returns the HTML code for the common items of the navigation bar 287 * 288 * @return string 289 */ 290 protected function getCommonLinks() 291 { 292 return '<li><a href="javascript:toggler.toggleAll(\''.self::JS_MAIN_NAME.'\', \'btnToggle\')" class="expandAllBtn" id="btnToggle">Expand all</a></li>'. 293 '<li><a href="'.$this->getContextPackage()->rpt.self::HELP_FILENAME.'.'.self::FILE_EXT.'" class="helpBtn">Help</a></li>'. 294 '<li><a href="'.$this->getContextPackage()->rpt.self::INDEXALL_FILENAME.'.'.self::FILE_EXT.'" class="indexAllBtn">Index</a></li>'; 295 } 296 297 /** 298 * Returns the HTML code for the "File" information tag 299 * 300 * @param PHP_UML_Metamodel_NamedElement $p An element 301 * 302 * @return string 303 */ 304 protected function getFileInfo(PHP_UML_Metamodel_NamedElement $p) 305 { 306 if (!empty($p->file->package)) 307 return '<li>File: '.$this->getAbsPath($p->file->package).$p->file->name.'</li>'; 308 else 309 return ''; 310 } 311 312 protected function getPropertyStyle($visibility) 313 { 314 return 'property-'.substr($visibility, 0, 3); 315 } 316 317 protected function getFunctionStyle($visibility) 318 { 319 return 'method-'.substr($visibility, 0, 3); 320 } 321 322 /** 323 * Replace the template's placeholders with their value 324 * 325 * @param string $main Main HTML content (generated by PHP_UML) 326 * @param string $nav Navigation HTML content (navig bar) 327 * @param string $tit Title content 328 * @param string $name Element name 329 * 330 * @return string 331 */ 332 protected function replaceInTpl($main, $nav, $tit, $name) 333 { 334 $str = str_replace('#NAVIG', $nav, $this->mainTpl); 335 $str = str_replace('#TITLE', $tit, $str); 336 $str = str_replace('#DETAIL', $main, $str); 337 $str = str_replace('#RELPATHTOP', $this->getContextPackage()->rpt, $str); 338 $str = str_replace('#NAME', $this->getTypeName().' '.$name, $str); 339 $str = str_replace('#CURDATE', date("M j, Y, G:i:s O"), $str); 340 return $str; 341 } 342 343 protected function getTemplateDirectory() 344 { 345 return dirname(__FILE__).DIRECTORY_SEPARATOR.self::TEMPLATES_DIRNAME; 346 } 347 348 protected function save($elementName, $str) 349 { 350 $fic = $this->getContextPackage()->dir.$elementName.'.'.self::FILE_EXT; 351 file_put_contents($fic, $str); 352 } 353} 354?> 355