Beispiel #1
0
 /**
  * Helper function which detects if given widget is matching with 
  * the attributes, described in the splitted part of the selector.
  *
  * For example for selector 
  * <pre><code>
  * ->f("#text")->....
  * </code></pre>
  *
  * each widget will be checked if it's ID is exactly equals to "text".
  *
  * Such as {@link matched} method it returns _CACHE , _NOCACHE
  * values, which are easily converting to bool.
  *
  * @param WComponent widget to be checked by the attributes list
  * @param array of parsed selector's parameters
  * @return mixed values, casting to bool
  */
 protected static function matchAttributes(WComponent $widget, $parsed_selector)
 {
     if (empty($parsed_selector)) {
         return false;
     }
     $controller = Controller::getInstance();
     //id, quick
     if (isset($parsed_selector['id']) && $widget->getIdLower() != $parsed_selector['id']) {
         return self::FALSE_CACHE;
     }
     //id starts with
     if (isset($parsed_selector['starts_with']) && substr($widget->getIdLower(), 0, strlen($parsed_selector['starts_with'])) != $parsed_selector['starts_with']) {
         return self::FALSE_CACHE;
     }
     // tag
     if (isset($parsed_selector['tag']) && $parsed_selector['tag'] !== "*" && $widget->getClassLower() !== $parsed_selector['tag']) {
         return self::FALSE_CACHE;
     }
     // .class
     if (isset($parsed_selector['class']) && !in_array(strtolower($parsed_selector['class']), array_map('strtolower', preg_split("/\\s+/", $widget->getStyleClass())), true)) {
         return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
     }
     // [attribute]
     if (isset($parsed_selector['attr'])) {
         if (!isset($parsed_selector['attr_value'])) {
             if (!method_exists($widget, "get" . $parsed_selector['attr']) || $widget->{"get" . $parsed_selector['attr']}() === null) {
                 return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
             }
         } elseif (isset($parsed_selector['attr_value']) && isset($parsed_selector['attr_quant'])) {
             // [attr=val]
             if ($parsed_selector['attr_quant'] === "=") {
                 if (!method_exists($widget, "get" . $parsed_selector['attr']) || trim($widget->{"get" . $parsed_selector['attr']}()) != strtolower($parsed_selector['attr_value'])) {
                     return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
                 }
             } elseif ($parsed_selector['attr_quant'] === "~=") {
                 if (!method_exists($widget, "get" . $parsed_selector['attr']) || !in_array(strtolower($parsed_selector['attr_value']), array_map('strtolower', preg_split("/\\s+/", trim($widget->{"get" . $parsed_selector['attr']}()))), true)) {
                     return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
                 }
             } elseif ($parsed_selector['attr_quant'] === "!=") {
                 if (!method_exists($widget, "get" . $parsed_selector['attr']) || trim($widget->{"get" . $parsed_selector['attr']}()) == strtolower($parsed_selector['attr_value'])) {
                     return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
                 }
             } elseif ($parsed_selector['attr_quant'] === "^=") {
                 if (!method_exists($widget, "get" . $parsed_selector['attr']) || stripos(trim($widget->{"get" . $parsed_selector['attr']}()), $parsed_selector['attr_value']) !== 0) {
                     return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
                 }
             } elseif ($parsed_selector['attr_quant'] === "\$=") {
                 if (!method_exists($widget, "get" . $parsed_selector['attr']) || stripos($_s = trim($widget->{"get" . $parsed_selector['attr']}()), $parsed_selector['attr_value']) !== strlen($_s) - strlen($parsed_selector['attr_value'])) {
                     return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
                 }
             } elseif ($parsed_selector['attr_quant'] === "*=") {
                 if (!method_exists($widget, "get" . $parsed_selector['attr']) || stripos(trim($widget->{"get" . $parsed_selector['attr']}()), $parsed_selector['attr_value']) === false) {
                     return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
                 }
             } elseif ($parsed_selector['attr_quant'] === "|=") {
                 if (!method_exists($widget, "get" . $parsed_selector['attr']) || !in_array(strtolower($parsed_selector['attr_value']), array_map('strtolower', preg_split("/\\s*-\\s*/", trim($widget->{"get" . $parsed_selector['attr']}()))), true)) {
                     return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
                 }
             } else {
                 return self::FALSE_CACHE;
             }
         }
     }
     //pseudo
     if (isset($parsed_selector['pseudo'])) {
         // :contains(text) for ->getText() and ->getValue()
         if ($parsed_selector['pseudo'] == "contains" && isset($parsed_selector['pseudo_value'])) {
             if (method_exists($widget, "getText") && $widget->getText() != $parsed_selector['pseudo_value']) {
                 return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
             }
             if ($widget instanceof WControl && $widget->getValue() != $parsed_selector['pseudo_value']) {
                 return $widget->isInsideRoll() ? self::FALSE_NOCACHE : FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "hidden") {
             if ($widget->getVisible()) {
                 return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "visible") {
             if (!$widget->getVisible()) {
                 return $widget->isInsideRoll() ? self::FALSE_NOCACHE : self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "disable") {
             if ($widget->getState()) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "input") {
             if (!$widget instanceof WControl) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "text") {
             if (!$widget instanceof WEdit || !$widget->getType() != "text") {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "password") {
             if (!$widget instanceof WEdit || !$widget->getType() != "password") {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "radio") {
             if (!$widget instanceof WRadio) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "checkbox") {
             if (!$widget instanceof WCheckbox) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "submit") {
             if (!$widget instanceof WButton || $widget->getType() != "submit") {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "image") {
             if (!$widget instanceof WButton || $widget->getType() != "image") {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "reset") {
             if (!$widget instanceof WButton || !$widget->getType() != "reset") {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "button") {
             if (!$widget instanceof WButton || !$widget->getType() != "button") {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "hidden") {
             if (!$widget instanceof WHidden) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "disabled") {
             if (!$widget instanceof WContol || !$widget->getDisabled()) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "enabled") {
             if (!$widget instanceof WContol || $widget->getDisabled()) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "checked") {
             if (!$widget instanceof WCheckbox || !$widget->getChecked()) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "first-child") {
             if (($parent = $controller->getAdjacencyList()->getParentForId($widget->getId())) === null) {
                 return self::FALSE_CACHE;
             }
             if (($list = $controller->getAdjacencyList()->getChildren($parent)) && $controller->getAdjacencyList()->checkIndex($list, $widget->getId()) !== 0) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "last-child") {
             if (($parent = $controller->getAdjacencyList()->getParentForId($widget->getId())) === null) {
                 return self::FALSE_CACHE;
             }
             if (($list = $controller->getAdjacencyList()->getChildren($parent)) && $controller->getAdjacencyList()->checkIndex($list, $widget->getId()) !== count($list) - 1) {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "nth-child") {
             if (($parent = $controller->getAdjacencyList()->getParentForId($widget->getId())) === null || !isset($parsed_selector['pseudo_value'])) {
                 return self::FALSE_CACHE;
             }
             $ind = ($list = $controller->getAdjacencyList()->getChildren($parent)) ? $controller->getAdjacencyList()->checkIndex($list, $widget->getId()) : -2;
             if (is_numeric($parsed_selector['pseudo_value'])) {
                 return $ind !== abs($parsed_selector['pseudo_value']) - 1 ? self::FALSE_CACHE : self::TRUE_CACHE;
             } elseif ($parsed_selector['pseudo_value'] == "odd") {
                 return $ind % 2 ? self::FALSE_CACHE : self::TRUE_CACHE;
             } elseif ($parsed_selector['pseudo_value'] == "even") {
                 return !$ind % 2 ? self::FALSE_CACHE : self::TRUE_CACHE;
             } else {
                 return self::FALSE_CACHE;
             }
         } elseif ($parsed_selector['pseudo'] === "index" && $widget->isInsideRoll()) {
             if (!isset($parsed_selector['pseudo_value'])) {
                 return self::FALSE_CACHE;
             }
             $w2 = $widget;
             $parent = null;
             // inconvinient in case of nested rolls
             // to select odd rows, for example, "wroll > wtablerow:odd" syntax should be used
             if (($parent = $controller->getAdjacencyList()->getParentIterableForId($w2->getId())) === null) {
                 while ($w2 && ($p = $controller->getAdjacencyList()->getParentForId($w2->getId())) !== null) {
                     if ($controller->getWidget($p) instanceof iIterableContainer) {
                         $parent = $p;
                         break;
                     } else {
                         $w2 = $controller->getWidget($p);
                     }
                 }
                 if ($parent == null) {
                     return self::FALSE_CACHE;
                 }
                 $controller->getAdjacencyList()->setParentIterableForIdCache($widget->getId(), $parent);
             }
             if (!is_array($parsed_selector['pseudo_value'])) {
                 if (strpos($parsed_selector['pseudo_value'], ":") !== false) {
                     list($parsed_selector['pseudo_value'], $parsed_selector['scope']) = explode(":", $parsed_selector['pseudo_value']);
                 }
                 if (!isset($parsed_selector['scope'])) {
                     $parsed_selector['scope'] = "global";
                 }
                 $current = $controller->getDisplayModeParams()->getCurrent($parent, $parsed_selector['scope']);
                 if (is_numeric($parsed_selector['pseudo_value']) && $parsed_selector['pseudo_value'] != $current) {
                     return self::FALSE_NOCACHE;
                 }
                 if ($parsed_selector['pseudo_value'] === "odd" && $current % 2 !== 1) {
                     return self::FALSE_NOCACHE;
                 }
                 if ($parsed_selector['pseudo_value'] === "even" && $current % 2 !== 0) {
                     return self::FALSE_NOCACHE;
                 }
                 if ($parsed_selector['pseudo_value'] === "first" && !$controller->getDisplayModeParams()->isFirst($parent, $parsed_selector['scope'])) {
                     return self::FALSE_NOCACHE;
                 }
                 if ($parsed_selector['pseudo_value'] === "last" && !$controller->getDisplayModeParams()->isLast($parent, $parsed_selector['scope'])) {
                     return self::FALSE_NOCACHE;
                 }
             } elseif (!count($parsed_selector['pseudo_value'])) {
                 return self::FALSE_CACHE;
             } else {
                 $controller->getDisplayModeParams()->setMatchedIndex(-1);
                 $cur_scope = array_shift($parsed_selector['scope']);
                 $matched = $current = $controller->getDisplayModeParams()->getCurrent($parent, $cur_scope);
                 foreach ($parsed_selector['pseudo_value'] as $k => $v) {
                     if (is_numeric($k) && $k != $current) {
                         continue;
                     } elseif ($current != RSIndexer::getLastIndex($k)) {
                         continue;
                     } else {
                         $_w3 = $_w2 = $controller->getWidget($parent);
                         $flag = true;
                         $_parent = null;
                         foreach (RSIndexer::toArray($k) as $next_index) {
                             if (($_parent = $controller->getAdjacencyList()->getParentIterableForId($_w2->getId())) === null) {
                                 while ($_w2 && ($_p = $controller->getAdjacencyList()->getParentForId($_w2->getId())) !== null) {
                                     if ($controller->getWidget($_p) instanceof iIterableContainer) {
                                         $_parent = $_p;
                                         break;
                                     } else {
                                         $_w2 = $controller->getWidget($_p);
                                     }
                                 }
                                 $controller->getAdjacencyList()->setParentIterableForIdCache($_w3->getId(), $_parent);
                             }
                             if ($_parent && $controller->getDisplayModeParams()->getCurrent($_parent, $cur_scope) != $next_index) {
                                 $flag = false;
                                 break;
                             }
                         }
                         if ($flag) {
                             $controller->getDisplayModeParams()->setMatchedIndex($k);
                             return self::TRUE_NOCACHE;
                         }
                     }
                 }
                 return self::FALSE_NOCACHE;
             }
         } else {
             return self::FALSE_CACHE;
         }
     }
     return self::TRUE_NOCACHE;
 }