1<?php 2/** 3 * ODTStyle: base class for ODT styles. 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author LarsDW223 7 */ 8 9require_once 'ODTUnknownStyle.php'; 10require_once 'ODTStyleStyle.php'; 11require_once 'ODTTextOutlineStyle.php'; 12require_once 'ODTTextListStyle.php'; 13require_once 'ODTMasterPageStyle.php'; 14require_once 'ODTPageLayoutStyle.php'; 15require_once 'ODTTextStyle.php'; 16require_once 'ODTParagraphStyle.php'; 17require_once 'ODTTableStyle.php'; 18require_once 'ODTTableRowStyle.php'; 19require_once 'ODTTableColumnStyle.php'; 20require_once 'ODTTableCellStyle.php'; 21 22/** 23 * The ODTStyle class 24 */ 25abstract class ODTStyle 26{ 27 protected static $style_base_name = 'PluginODTAutoStyle_'; 28 protected static $style_count = 0; 29 protected $properties = array(); 30 31 /** 32 * Get the element name for the ODT XML encoding of the style. 33 * 34 * @param $properties Properties to be imported 35 * @param $disabled Properties to be ignored 36 */ 37 abstract public function getElementName(); 38 39 /** 40 * Set style properties by importing values from a properties array. 41 * Properties might be disabled by setting them in $disabled. 42 * The style must have been previously created. 43 * 44 * @param $properties Properties to be imported 45 * @param $disabled Properties to be ignored 46 */ 47 abstract public function importProperties($properties, $disabled); 48 49 /** 50 * Check if a style is a common style. 51 * 52 * @return bool Is common style 53 */ 54 abstract public function mustBeCommonStyle(); 55 56 /** 57 * Encode current style values in a string and return it. 58 * 59 * @return string ODT XML encoded style 60 */ 61 abstract public function toString(); 62 63 /** 64 * Set a property. 65 * 66 * @param $property The name of the property to set 67 * @param $value New value to set 68 */ 69 abstract public function setProperty($property, $value); 70 71 /** 72 * Get the value of a property. 73 * 74 * @param $property The property name 75 * @return string The current value of the property 76 */ 77 public function getProperty($property) { 78 return (isset($this->properties [$property]['value']) ? $this->properties [$property]['value'] : NULL); 79 } 80 81 /** 82 * Get the value of a property. 83 * 84 * @param $property The property name 85 * @param $properties Properties array to query the value from, 86 * or NULL for using ours. 87 * @return string The current value of the property 88 */ 89 public function getPropertyInternal($property, $properties=NULL) { 90 if ( !isset($properties) ) { 91 return $this->properties [$property]['value']; 92 } else { 93 return $properties [$property]['value']; 94 } 95 } 96 97 /** 98 * Get the value of a property. 99 * 100 * @param $property The property name 101 * @return string The current value of the property 102 */ 103 public function getPropertySection($property) { 104 return $this->properties [$property]['section']; 105 } 106 107 /** 108 * Create new style by importing ODT style definition. 109 * 110 * @param $xmlCode Style definition in ODT XML format 111 * @return ODTStyle New specific style 112 */ 113 static public function importODTStyle($xmlCode) { 114 $matches = array(); 115 $pattern = '/<(\w)+[^\s\/>]+/'; 116 if (preg_match ($pattern, $xmlCode, $matches) !== 1) { 117 return NULL; 118 } 119 $element = trim ($matches [0], '"<>'); 120 121 $style = NULL; 122 switch ($element) { 123 case 'style:style': 124 case 'style:default-style': 125 $style = ODTStyleStyle::importODTStyle($xmlCode); 126 break; 127 case 'text:outline-style': 128 $style = ODTTextOutlineStyle::importODTStyle($xmlCode); 129 break; 130 case 'text:list-style': 131 $style = ODTTextListStyle::importODTStyle($xmlCode); 132 break; 133 case 'style:master-page': 134 $style = ODTMasterPageStyle::importODTStyle($xmlCode); 135 break; 136 case 'style:page-layout': 137 $style = ODTPageLayoutStyle::importODTStyle($xmlCode); 138 break; 139 default: 140 break; 141 } 142 if ( isset($style) ) { 143 return $style; 144 } 145 146 // Unknown/not implemented style. 147 // Create generic style which can not be changed. 148 $unknown = ODTUnknownStyle::importODTStyle($xmlCode); 149 $unknown->setElementName($element); 150 return $unknown; 151 } 152 153 /** 154 * Set a property. 155 * 156 * @param $property The name of the property to set 157 * @param $value New value to set 158 */ 159 protected function setPropertyInternal($property, $odt_property, $value, $section, &$dest=NULL) { 160 if (isset($value)) { 161 if ( !isset($dest) ) { 162 $this->properties [$property] = array ('odt_property' => $odt_property, 163 'value' => $value, 164 'section' => $section); 165 } else { 166 $dest [$property] = array ('odt_property' => $odt_property, 167 'value' => $value, 168 'section' => $section); 169 } 170 } else { 171 if ( !isset($dest) ) { 172 unset ($this->properties [$property]); 173 } else { 174 unset ($dest [$property]); 175 } 176 } 177 } 178 179 /** 180 * Import ODT style definition according to given fields into given style. 181 * 182 * @param $style ODTStyle object for storing the properties 183 * @param $fields Properties accepted by the object/class 184 * @param $xmlCode Style definition in ODT XML format 185 * @return integer Number of meaningful properties found 186 */ 187 protected function importODTStyleInternal(array $fields, $xmlCode, &$properties=NULL) { 188 $attrs = 0; 189 foreach ($fields as $property => $field) { 190 // The pattern is specified in that way that it also reads in empty attributes. 191 // Sometimes an empty attribute is not the same as an not existing one. E.g. 192 // in ODT XML '<text:outline-level-style text:level="3" style:num-format="" >' 193 // has NOT the same meaning as '<text:outline-level-style text:level="3" >'!!! 194 // So DO NOT change the '*' in the pattern to '+'! 195 if (preg_match ('/'.$field[0].'="[^"]*"/', $xmlCode, $matches) === 1) { 196 $value = substr ($matches [0], strlen($field[0].'="')); 197 $value = trim ($value, '"<>'); 198 $this->setPropertyInternal($property, $field[0], $value, $field[1], $properties); 199 if ( $field[2] == true ) { 200 $attrs++; 201 } 202 } 203 } 204 return $attrs; 205 } 206 207 /** 208 * Set style properties by importing values from a properties array. 209 * Properties might be disabled by setting them in $disabled. 210 * The style must have been previously created. Only those properties 211 * will be accepted that are mentioned in the fields array. 212 * 213 * @param $style ODTStyle object for storing the properties 214 * @param $fields Properties accepted by the object/class 215 * @param $properties Properties to be imported 216 * @param $disabled Properties to be ignored 217 */ 218 protected function importPropertiesInternal(array $fields, $properties, $disabled, &$dest=NULL) { 219 foreach ($properties as $property => $value) { 220 if ($disabled [$property] == 0 && array_key_exists ($property, $fields)) { 221 $this->setPropertyInternal($property, $fields[$property][0], $value, $fields[$property][1], $dest); 222 } 223 } 224 } 225 226 /** 227 * Is this style a default style? 228 * Needs to be overwritten if a style could also be a default style. 229 * 230 * @return boolean Always false. 231 */ 232 public function isDefault() { 233 return false; 234 } 235 236 /** 237 * This function creates a new style name. All functions of this class which create a new 238 * style/style name shall use this function to create the style name. By doing so it is 239 * guaranteed that all style names created by this class are unique. 240 * 241 * The function returns the name of the new style or NULL if all relevant properties are empty. 242 */ 243 public static function getNewStylename ($type = '') { 244 self::$style_count++; 245 $style_name = self::$style_base_name.$type.'_'.self::$style_count; 246 return $style_name; 247 } 248} 249