| @@ -14,11 +14,11 @@ | ||
| 14 | 14 | require_once CJTOOLBOX_MVC_FRAMEWOK . '/model.inc.php'; |
| 15 | 15 | |
| 16 | 16 | /** |
| 17 | 17 | * Represent single block object. |
| 18 | -* | |
| 18 | +* | |
| 19 | 19 | * Provide simple access read or write to block properties. |
| 20 | -* | |
| 20 | +* | |
| 21 | 21 | * @author Ahmed Said |
| 22 | 22 | * @version 6 |
| 23 | 23 | */ |
| 24 | 24 | class CJTBlockModel extends CJTModel { |
| @@ -27,9 +27,9 @@ | ||
| 27 | 27 | * Global scope pins |
| 28 | 28 | */ |
| 29 | 29 | const PINS_FRONTEND = 0x01; |
| 30 | 30 | const PINS_BACKEND = 0x02; |
| 31 | - | |
| 31 | + | |
| 32 | 32 | /** |
| 33 | 33 | * Pages Pins. |
| 34 | 34 | */ |
| 35 | 35 | const PINS_PAGES_ALL_PAGES = 0x10; |
| @@ -34,23 +34,23 @@ | ||
| 34 | 34 | */ |
| 35 | 35 | const PINS_PAGES_ALL_PAGES = 0x10; |
| 36 | 36 | const PINS_PAGES_CUSTOM_PAGE = 0x20; |
| 37 | 37 | const PINS_PAGES_FRONT_PAGE = 0x40; |
| 38 | - | |
| 38 | + | |
| 39 | 39 | /** |
| 40 | 40 | * Posts Pins. |
| 41 | - */ | |
| 41 | + */ | |
| 42 | 42 | const PINS_POSTS_ALL_POSTS = 0x100; |
| 43 | 43 | const PINS_POSTS_CUSTOM_POST = 0x200; |
| 44 | 44 | const PINS_POSTS_RECENT = 0x400; |
| 45 | 45 | const PINS_POSTS_BLOG_INDEX = 0x800; |
| 46 | - | |
| 46 | + | |
| 47 | 47 | /** |
| 48 | 48 | * Categories Pins. |
| 49 | 49 | */ |
| 50 | 50 | const PINS_CATEGORIES_ALL_CATEGORIES = 0x1000; |
| 51 | 51 | const PINS_CATEGORIES_CUSTOM_CATEGORY = 0x2000; |
| 52 | - | |
| 52 | + | |
| 53 | 53 | /** |
| 54 | 54 | * Other general pages pins. |
| 55 | 55 | */ |
| 56 | 56 | const PINS_SEARCH = 0x10000; |
| @@ -58,142 +58,304 @@ | ||
| 58 | 58 | const PINS_TAG = 0x40000; |
| 59 | 59 | const PINS_AUTHOR = 0x80000; |
| 60 | 60 | const PINS_ATTACHMENT = 0x100000; |
| 61 | 61 | const PINS_404_ERROR = 0x200000; |
| 62 | - | |
| 62 | + | |
| 63 | 63 | /** |
| 64 | - * | |
| 64 | + * | |
| 65 | 65 | */ |
| 66 | 66 | const PINS_LINKS = 0x1000000; |
| 67 | 67 | const PINS_EXPRESSIONS = 0x2000000; |
| 68 | - | |
| 68 | + | |
| 69 | 69 | /** |
| 70 | - * | |
| 70 | + * | |
| 71 | 71 | */ |
| 72 | 72 | const PINS_LINK_EXPRESSION = 0x3000000; |
| 73 | - | |
| 73 | + | |
| 74 | 74 | /** |
| 75 | + * put your comment there... | |
| 76 | + * | |
| 77 | + * @var mixed | |
| 78 | + */ | |
| 79 | + private static $customPins; | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * put your comment there... | |
| 83 | + * | |
| 84 | + * @var mixed | |
| 85 | + */ | |
| 86 | + private $propertiesMeta = array | |
| 87 | + ( | |
| 88 | + 'name' => array(), | |
| 89 | + 'pinPoint' => array(), | |
| 90 | + 'state' => array(), | |
| 91 | + 'location' => array(), | |
| 92 | + 'code' => array(), | |
| 93 | + 'links' => array(), | |
| 94 | + 'expressions' => array(), | |
| 95 | + 'id' => array(), | |
| 96 | + ); | |
| 97 | + | |
| 98 | + /** | |
| 75 | 99 | * Create block object. |
| 76 | - * | |
| 100 | + * | |
| 77 | 101 | * @param integer Block id. |
| 78 | 102 | * @param array Block data array or null to use default data. |
| 79 | 103 | * @return void |
| 80 | 104 | */ |
| 81 | - public function __construct($values = array()) { | |
| 82 | - $this->properties = array( | |
| 83 | - 'name' => null, | |
| 84 | - 'pinPoint' => null, | |
| 85 | - 'state' => null, | |
| 86 | - 'location' => null, | |
| 87 | - 'code' => null, | |
| 88 | - 'pages' => null, | |
| 89 | - 'posts' => null, | |
| 90 | - 'categories' => null, | |
| 91 | - 'links' => null, | |
| 92 | - 'expressions' => null, | |
| 93 | - 'id' => null, | |
| 94 | - ); | |
| 105 | + public function __construct( $values = array() ) | |
| 106 | + { | |
| 107 | + // Allow pluggable custom pins | |
| 108 | + $customPins = self::getCustomPins(); | |
| 109 | + | |
| 110 | + // Allow pluggable fields | |
| 111 | + $this->propertiesMeta = apply_filters( CJTPluggableHelper::FILTER_BLOCK_MODEL_PROPERTIES_META, $this->propertiesMeta ); | |
| 112 | + | |
| 113 | + // Merge prpperties meta wioth custom pins to create one full propertiesMeta objetc | |
| 114 | + // that hold both fields and custom pins fields | |
| 115 | + $this->propertiesMeta = array_merge( $this->propertiesMeta, $customPins ); | |
| 116 | + | |
| 117 | + // Properties backward compatibolity to hold all available properties | |
| 118 | + $this->properties = array_combine( | |
| 119 | + | |
| 120 | + array_keys( $this->propertiesMeta ), | |
| 121 | + | |
| 122 | + array_fill( 0, count( $this->propertiesMeta ), null ) | |
| 123 | + | |
| 124 | + ); | |
| 125 | + | |
| 95 | 126 | // Set block properties. |
| 96 | - $this->setValues($values); | |
| 127 | + $this->setValues( $values ); | |
| 97 | 128 | } |
| 98 | - | |
| 129 | + | |
| 99 | 130 | /** |
| 100 | 131 | * Get block property value. |
| 101 | - * | |
| 132 | + * | |
| 102 | 133 | * @param string Property name. |
| 103 | 134 | * @return mixed Property value. |
| 104 | 135 | */ |
| 105 | - public function __get($property) { | |
| 106 | - switch ($property) { | |
| 107 | - case 'pages': | |
| 108 | - case 'posts': | |
| 109 | - case 'categories': | |
| 110 | - $value = ($this->properties[$property] !== null) ? $this->properties[$property] : array(); | |
| 111 | - break; | |
| 112 | - | |
| 113 | - default: | |
| 114 | - $value = $this->properties[$property]; | |
| 115 | - break; | |
| 116 | - } | |
| 136 | + public function __get( $property ) | |
| 137 | + { | |
| 138 | + // Return default values | |
| 139 | + $value = ( isset( $this->properties[ $property ] ) && ( $this->properties[ $property ] === null ) && | |
| 140 | + ( isset( $this->propertiesMeta[ $property ][ 'default' ] ) ) ) ? | |
| 141 | + | |
| 142 | + $this->propertiesMeta[ $property ][ 'default' ] : | |
| 143 | + ( isset( $this->properties[ $property ] ) ? $this->properties[ $property ] : null ); | |
| 144 | + | |
| 117 | 145 | return $value; |
| 118 | 146 | } |
| 119 | - | |
| 147 | + | |
| 120 | 148 | /** |
| 121 | 149 | * Set block proprty value. |
| 122 | - * | |
| 150 | + * | |
| 123 | 151 | * @param string Property name. |
| 124 | 152 | * @param mixed Property value. |
| 125 | 153 | * @return void |
| 126 | 154 | */ |
| 127 | - public function __set($property, $value) { | |
| 128 | - switch ($property) { | |
| 155 | + public function __set($property, $value) | |
| 156 | + { | |
| 157 | + switch ( $property ) | |
| 158 | + { | |
| 129 | 159 | case 'code': |
| 160 | + | |
| 130 | 161 | case 'links': |
| 162 | + | |
| 131 | 163 | case 'expressions': |
| 164 | + | |
| 132 | 165 | // New lines submitted to server as CRLF but displayed in browser as LF. |
| 133 | 166 | // PHP script and JS work on two different versions of texts. |
| 134 | 167 | // Replace CRLF with LF just as displayed in browsers. |
| 135 | - $value = preg_replace("/\x0D\x0A/", "\x0A", $value); | |
| 168 | + $value = preg_replace( "/\x0D\x0A/", "\x0A", $value ); | |
| 169 | + | |
| 136 | 170 | break; |
| 137 | 171 | } |
| 138 | - $this->properties[$property] = $value; | |
| 172 | + | |
| 173 | + $this->properties[ $property ] = $value; | |
| 139 | 174 | } |
| 140 | - | |
| 175 | + | |
| 141 | 176 | /** |
| 142 | 177 | * put your comment there... |
| 143 | - * | |
| 178 | + * | |
| 179 | + * @param mixed $blockData | |
| 180 | + */ | |
| 181 | + public static function arrangePins( & $blockData ) | |
| 182 | + { | |
| 183 | + | |
| 184 | + $pinsGroupNames = array_flip( array_merge( array_keys( self::getCustomPins() ), array( 'pinPoint' ) ) ); | |
| 185 | + $dbDriver = cssJSToolbox::getInstance()->getDBDriver(); | |
| 186 | + $mdlBlock = new CJTBlocksModel(); | |
| 187 | + $block = $mdlBlock->getBlock( $blockData->id, array(), array( 'id', 'pinPoint' ) ); | |
| 188 | + $submittedPins = array_intersect_key( ( ( array ) $blockData ), $pinsGroupNames ); | |
| 189 | + $assignedPins = array_intersect_key( ( ( array ) $block ), $pinsGroupNames ); | |
| 190 | + | |
| 191 | + // Transfer assigned PinPoint from "FLAGGED INTEGER" TO "ARRAY" like | |
| 192 | + // the other pins. | |
| 193 | + $assignedPins[ 'pinPoint' ] = array_keys( CJT_Models_Block_Assignmentpanel_Helpers_Auxiliary | |
| 194 | + ::getInstance() | |
| 195 | + ->getPinsArray( $assignedPins[ 'pinPoint' ] ) ); | |
| 196 | + | |
| 197 | + // Walk through all assigned pins. | |
| 198 | + // Unassigned any item with 'value=false'. | |
| 199 | + // Whenever an item is found on the submitted | |
| 200 | + // pins it should be removed from the submitted list | |
| 201 | + foreach ( $submittedPins as $groupName => $submittedGroup ) | |
| 202 | + { | |
| 203 | + // Get assigned pins group if found | |
| 204 | + if ( ! isset( $assignedPins[ $groupName ] ) ) | |
| 205 | + { | |
| 206 | + // Initialize new assigned group array. | |
| 207 | + $assignedPins[ $groupName ] = array(); | |
| 208 | + } | |
| 209 | + | |
| 210 | + $assignedGroup =& $assignedPins[ $groupName ]; | |
| 211 | + | |
| 212 | + // For every submitted item there is three types. | |
| 213 | + // 1. Already assigned :WHEN: (sync == true and value == true) | |
| 214 | + // 2. Unassigned :WHEN: (value == false) | |
| 215 | + // 3. Newly assigned :WHEN: (sync = false). | |
| 216 | + foreach ( $submittedGroup as $submittedPinId => $submittedPin ) | |
| 217 | + { | |
| 218 | + // Unassigned pin | |
| 219 | + if ( ! $submittedPin[ 'value' ] ) | |
| 220 | + { | |
| 221 | + // Find the submittedPinId AssignedPins index. | |
| 222 | + $assignedIndex = array_search( $submittedPinId, $assignedGroup ); | |
| 223 | + // Unassigned it :REMOVE FROM ARRAY: | |
| 224 | + unset( $assignedGroup[ $assignedIndex ] ); | |
| 225 | + } | |
| 226 | + else if ( ! $submittedPin[ 'sync' ] ) | |
| 227 | + { | |
| 228 | + // Add newly assigned item. | |
| 229 | + $assignedGroup[] = $submittedPinId; | |
| 230 | + } | |
| 231 | + | |
| 232 | + } | |
| 233 | + | |
| 234 | + } | |
| 235 | + | |
| 236 | + // Copy all assigned pins back to the block object. | |
| 237 | + foreach ( $assignedPins as $groupName => $finalGroupAssigns ) | |
| 238 | + { | |
| 239 | + $blockData->{$groupName} = $finalGroupAssigns; | |
| 240 | + } | |
| 241 | + | |
| 242 | + // Important for caller short-circle condition. | |
| 243 | + return true; | |
| 244 | + } | |
| 245 | + | |
| 246 | + /** | |
| 247 | + * put your comment there... | |
| 248 | + * | |
| 144 | 249 | * @deprecated Use calculatePinpoint |
| 145 | 250 | */ |
| 146 | - public static function calculateBlockPinPoint(&$block) { | |
| 251 | + public static function calculateBlockPinPoint( & $block ) | |
| 252 | + { | |
| 253 | + | |
| 147 | 254 | // Generate PinPoint Value. |
| 148 | - if (is_array($block->pinPoint)) { | |
| 255 | + if ( isset( $block->pinPoint ) && is_array( $block->pinPoint ) ) | |
| 256 | + { | |
| 149 | 257 | $pinPoint = 0; |
| 258 | + | |
| 150 | 259 | // Each item is a bit flag. |
| 151 | - foreach ($block->pinPoint as $pin) { | |
| 260 | + foreach ( $block->pinPoint as $pin ) | |
| 261 | + { | |
| 152 | 262 | $pinPoint |= hexdec($pin); |
| 153 | 263 | } |
| 264 | + | |
| 154 | 265 | } |
| 155 | - else { | |
| 156 | - // If provided as integer. | |
| 266 | + else | |
| 267 | + { | |
| 268 | + // Provided as integer or not even provided! | |
| 269 | + if ( ! isset( $block->pinPoint ) ) | |
| 270 | + { | |
| 271 | + $block->pinPoint = 0; | |
| 272 | + } | |
| 273 | + | |
| 157 | 274 | $pinPoint = (int) $block->pinPoint; |
| 158 | 275 | } |
| 276 | + | |
| 159 | 277 | // Pin should be set only for not empty properties. |
| 160 | - // This help us retreiving only needed blocks when outputing blocks code. | |
| 161 | - $pins = array( | |
| 162 | - self::PINS_PAGES_CUSTOM_PAGE => 'pages', | |
| 163 | - self::PINS_POSTS_CUSTOM_POST => 'posts', | |
| 164 | - self::PINS_CATEGORIES_CUSTOM_CATEGORY => 'categories', | |
| 278 | + // This help us retreiving only needed blocks when querying blocks code. | |
| 279 | + $pins = array | |
| 280 | + ( | |
| 165 | 281 | self::PINS_LINKS => 'links', |
| 166 | 282 | self::PINS_EXPRESSIONS => 'expressions', |
| 167 | 283 | ); |
| 168 | - foreach ($pins as $flag => $pin) { | |
| 169 | - $pinPoint |= abs((int) (!empty($block->{$pin}))) * $flag; | |
| 284 | + | |
| 285 | + $customPins = self::getCustomPins(); | |
| 286 | + | |
| 287 | + // Add Custom Pins to pins to be calculated below | |
| 288 | + foreach ( $customPins as $customPinName => $customPin ) | |
| 289 | + { | |
| 290 | + $pins[ $customPin[ 'pinValue' ] ] = $customPinName; | |
| 170 | 291 | } |
| 171 | - // Set new pin point. | |
| 172 | - $block->pinPoint = $pinPoint; | |
| 292 | + | |
| 293 | + foreach ( $pins as $flag => $pin ) | |
| 294 | + { | |
| 295 | + $pinPoint |= abs( ( int ) ( ! empty( $block->{$pin} ) ) ) * $flag; | |
| 296 | + } | |
| 297 | + | |
| 298 | + $block->pinPoint = $pinPoint; | |
| 299 | + | |
| 173 | 300 | return $block; |
| 174 | 301 | } |
| 175 | - | |
| 302 | + | |
| 176 | 303 | /** |
| 177 | 304 | * put your comment there... |
| 178 | - * | |
| 305 | + * | |
| 179 | 306 | * @param mixed $block |
| 180 | 307 | * @param mixed $pins |
| 181 | 308 | */ |
| 182 | - public static function calculatePinPoint($block, $pins) { | |
| 309 | + public static function calculatePinPoint( $block, $pins ) | |
| 310 | + { | |
| 183 | 311 | // Add pins to Block object so that calculateBlockPinPoint can calculate PinPoint value! |
| 184 | - $block = (object) array_merge($block, $pins); | |
| 185 | - $pinPoint = self::calculateBlockPinPoint($block)->pinPoint; | |
| 186 | - // Return only pinPoint. | |
| 312 | + $block = ( object ) array_merge( $block, $pins ); | |
| 313 | + | |
| 314 | + $pinPoint = self::calculateBlockPinPoint( $block )->pinPoint; | |
| 315 | + | |
| 187 | 316 | return $pinPoint; |
| 188 | 317 | } |
| 189 | - | |
| 318 | + | |
| 190 | 319 | /** |
| 191 | 320 | * put your comment there... |
| 192 | - * | |
| 193 | - * @param mixed $values | |
| 321 | + * | |
| 194 | 322 | */ |
| 195 | - public static function getInstance($values) { | |
| 196 | - return new CJTBlockModel($values); | |
| 323 | + public static function getCustomPins() | |
| 324 | + { | |
| 325 | + static $pins = array | |
| 326 | + ( | |
| 327 | + 'pages' => array | |
| 328 | + ( | |
| 329 | + | |
| 330 | + 'default' => array(), | |
| 331 | + 'pinValue' => self::PINS_PAGES_CUSTOM_PAGE | |
| 332 | + | |
| 333 | + ), | |
| 334 | + | |
| 335 | + 'posts' => array | |
| 336 | + ( | |
| 337 | + | |
| 338 | + 'default' => array(), | |
| 339 | + 'pinValue' => self::PINS_POSTS_CUSTOM_POST | |
| 340 | + | |
| 341 | + ), | |
| 342 | + | |
| 343 | + 'categories' => array | |
| 344 | + ( | |
| 345 | + | |
| 346 | + 'default' => array(), | |
| 347 | + 'pinValue' => self::PINS_CATEGORIES_CUSTOM_CATEGORY | |
| 348 | + | |
| 349 | + ), | |
| 350 | + ); | |
| 351 | + | |
| 352 | + // Cache custom pins | |
| 353 | + if ( ! self::$customPins ) | |
| 354 | + { | |
| 355 | + self::$customPins = apply_filters( CJTPluggableHelper::FILTER_BLOCK_MODEL_CUSTOM_PINS, $pins ); | |
| 356 | + } | |
| 357 | + | |
| 358 | + return self::$customPins; | |
| 197 | 359 | } |
| 198 | - | |
| 360 | + | |
| 199 | 361 | } // End class. |