Exemplo n.º 1
0
 /**
  * Parse the given DOMElement into containers and widgets and add them to the form
  *
  * @param DOMElement $element
  * @param One_Form_Container_Abstract $container
  */
 protected static function _parseToForm(DOMElement $element, One_Form_Container_Abstract $container)
 {
     $current = strtolower($element->localName);
     if ($current == 'constraints' || $current == 'constraint') {
         return NULL;
     }
     $widgetClass = self::identifyElement($current);
     if (is_null($widgetClass)) {
         return NULL;
     }
     if (is_object($widgetClass)) {
         $widgetClass = get_class($widgetClass);
     }
     if (preg_match('/^One_Form_Container/', $widgetClass) && $widgetClass != 'One_Form_Container_Form') {
         $attributes = array();
         $rawAttributes = $element->attributes;
         for ($i = 0; $i < $rawAttributes->length; $i++) {
             $attribute = $rawAttributes->item($i);
             $attributes[$attribute->localName] = $attribute->value;
         }
         if (false === isset($attributes['language'])) {
             $attributes['language'] = strtolower(One_Config::get('app.language'));
         }
         $subContainerId = isset($attributes['id']) ? $attributes['id'] : NULL;
         $subContainer = new $widgetClass($subContainerId, $attributes);
         // containers can contain other containers or widgets
         if ($element->hasChildNodes()) {
             foreach ($element->childNodes as $child) {
                 if ($child instanceof DOMElement) {
                     self::_parseToForm($child, $subContainer);
                 }
             }
         }
         $container->addContainer($subContainer);
     } else {
         if ($element->hasAttribute('role')) {
             // Get cache in preparation of possible option-caching
             $session = One_Repository::getSession();
             $parts = explode(':', $element->getAttribute('role'));
             if (count($parts) != 2) {
                 throw new One_Exception('You must define a valid role');
             }
             $relation = One_Repository::getRelation($parts[0]);
             $role = $relation->getRole($parts[1]);
             $relScheme = One_Repository::getScheme($role->schemeName);
             // set the name and id of the so it will be recognised as a related field
             $element->setAttribute('id', 'r__' . $element->getAttribute('role'));
             $element->setAttribute('name', 'r__' . $element->getAttribute('role'));
             if ($element->hasAttribute('optionsFrom')) {
                 $sessionCacheName = md5($relScheme->getName() . '#' . $element->getAttribute('optionsFrom'));
                 if (false === $element->hasAttribute('cacheOptions') || $element->hasAttribute('cacheOptions') && false === $session->varExists($sessionCacheName, 'One_Form_Cache')) {
                     $relView = new One_View($relScheme->getName(), $element->getAttribute('optionsFrom'));
                     $rawOptions = trim($relView->show());
                     $options = json_decode($rawOptions, 1);
                     if (false === is_array($options)) {
                         $options = array();
                     }
                     if ($element->hasAttribute('cacheOptions')) {
                         $session->set($sessionCacheName, $options, 'One_Form_Cache');
                     }
                 } else {
                     $options = $session->get($sessionCacheName, 'One_Form_Cache');
                 }
             } else {
                 if (!$element->hasAttribute('targetAttribute')) {
                     $targetAttr = $relScheme->getIdentityAttribute()->getName();
                 } else {
                     $targetAttr = $element->getAttribute('targetAttribute');
                 }
                 $sessionCacheName = md5($relScheme->getName() . '#' . $targetAttr . '#' . $element->getAttribute('publishedOnly'));
                 if (false === $element->hasAttribute('cacheOptions') || $element->hasAttribute('cacheOptions') && false === $session->varExists($sessionCacheName, 'One_Form_Cache')) {
                     $q = One_Repository::selectQuery($relScheme->getName());
                     $tparts = explode(':', $targetAttr);
                     foreach ($tparts as $tkey => $tval) {
                         if (in_array(substr($tval, 0, 1), array('(', '['))) {
                             $tparts[$tkey] = substr($tval, 1) . '+';
                         } else {
                             $tparts[$tkey] = $tval . '+';
                         }
                     }
                     $q->setOrder($tparts);
                     $results = $q->execute(false);
                     $options = array();
                     foreach ($results as $result) {
                         $idAttr = $relScheme->getIdentityAttribute()->getName();
                         $valAttr = $targetAttr;
                         $val = '';
                         foreach (explode(':', $targetAttr) as $tkey => $tval) {
                             switch (substr($tval, 0, 1)) {
                                 case '(':
                                     $tval = substr($tval, 1);
                                     $val .= '(' . $result->{$tval} . ') ';
                                     break;
                                 case '[':
                                     $tval = substr($tval, 1);
                                     $val .= '[' . $result->{$tval} . '] ';
                                     break;
                                 default:
                                     $val .= $result->{$tval} . ' ';
                                     break;
                             }
                         }
                         $options[$result->{$idAttr}] = trim($val);
                     }
                     if ($element->hasAttribute('cacheOptions')) {
                         $session->set($sessionCacheName, $options, 'One_Form_Cache');
                     }
                 } else {
                     $options = $session->get($sessionCacheName, 'One_Form_Cache');
                 }
             }
             $widget = self::determineWidget($container, $element, $widgetClass);
             if (method_exists($widget, 'setOptionsOnDetermination') && $widget->setOptionsOnDetermination()) {
                 $widget->setOptions($options);
             }
         } else {
             $widget = self::determineWidget($container, $element, $widgetClass);
         }
     }
 }
Exemplo n.º 2
0
 /**
  * Perform weighted search that returns the results according to matching compatibility
  * @return array
  */
 protected function performWeightSearch()
 {
     $session = One_Repository::getSession();
     $allSearchValues = array();
     $results = array('count' => 0, 'all' => array(), 'most' => array(), 'some' => array());
     // Get all used widgets
     $form = One_Form_Factory::createForm($this->scheme, $this->searchform);
     $widgets = $this->getWidgets($form, $this->scheme);
     $idAttr = $this->scheme->getIdentityAttribute()->getName();
     $searchOptions = $this->scheme->get('behaviorOptions.searchable');
     $conditions = 0;
     $weights = array();
     $conditionByModel = array();
     $specificWeights = array();
     foreach ($widgets as $widget) {
         $widgetData = $widget->getWidgetData();
         // Get the widget's name, value and operator
         // Check whether a widget is a specifier or not
         $specifier = false;
         if ($widget->getCfg('specifier')) {
             $specifier = true;
         }
         if (null !== $widgetData['value']) {
             $allSearchValues[$widgetData['name']] = $widgetData['value'];
             if (false !== strpos($widgetData['name'], ':')) {
                 $parts = explode(':', $widgetData['name'], 2);
                 $relation = One_Repository::getRelation($parts[0]);
                 // get the used relation
                 $link = $this->scheme->getLink($parts[1]);
                 $targetScheme = One_Repository::getScheme($link->getTarget());
                 // get the scheme of the related field
                 $tidAttr = $targetScheme->getIdentityAttribute()->getName();
                 $tSearchOptions = $this->scheme->get('behaviorOptions.searchable');
                 $wOptions = null;
                 if (method_exists($widget, 'getOptions')) {
                     $wOptions = $widget->getOptions();
                 }
                 // Get the role of the current scheme as seen from the relation from the target's side
                 $otherRole = null;
                 foreach ($relation->getRoles() as $role) {
                     if ($parts[1] != $role->name) {
                         $otherRole = $role;
                     }
                 }
                 if (null !== $otherRole) {
                     // Dirty trick to enforce the value(s) as an array so they are easier manageable
                     $values = $widgetData['value'];
                     if (!is_array($widgetData['value'])) {
                         $values = array($widgetData['value']);
                     }
                     if (null !== $widgetData['operator']) {
                         $tmpValues = array();
                         $op = $widgetData['operator'];
                         $allowed = $op->getAllowed();
                         $opVal = $op->getValue();
                         if (!is_null($opVal)) {
                             if (in_array($opVal, $allowed)) {
                                 $op = $opVal;
                             } else {
                                 $op = $allowed['default'];
                             }
                         } else {
                             $op = $allowed['default'];
                         }
                         // Perform special operators
                         foreach ($values as $value) {
                             $tQ = One_Repository::selectQuery($targetScheme->getName());
                             $tQ->setSelect(array($tidAttr));
                             $tQ->where($tidAttr, $op, $value);
                             $tmpResults = $tQ->execute(false);
                             foreach ($tmpResults as $tmpResult) {
                                 $tmpValues[$tmpResult->{$tidAttr}] = $tmpResult->{$tidAttr};
                             }
                         }
                         $values = $tmpValues;
                     }
                     // Get all related data // @TODO in the future it could be possible that you don't always get ID's of the related fields, but works for now
                     foreach ($values as $value) {
                         $current = One_Repository::selectOne($targetScheme->getName(), $value);
                         if (!is_null($current)) {
                             if (isset($tSearchOptions['publishField'])) {
                                 $tPubField = $searchOptions['publishField'];
                                 if (0 == $current->{$tPubField}) {
                                     continue;
                                 }
                             }
                             $conditions++;
                             $relateds = $current->getRelated($otherRole->name);
                             if (null === $relateds) {
                                 continue;
                             }
                             if (!is_array($relateds)) {
                                 $relateds = array($relateds);
                             }
                             foreach ($relateds as $related) {
                                 if (!isset($weights[$related->{$idAttr}])) {
                                     if (false === $specifier) {
                                         $weights[$related->{$idAttr}] = 0;
                                     }
                                     $conditionByModel[$related->{$idAttr}] = array();
                                 }
                                 if (!isset($conditionByModel[$related->{$idAttr}][$widgetData['name']])) {
                                     $conditionByModel[$related->{$idAttr}][$widgetData['name']] = array();
                                 }
                                 if (isset($wOptions[$value])) {
                                     $conditionByModel[$related->{$idAttr}][$widgetData['name']][] = $wOptions[$value];
                                 } else {
                                     $conditionByModel[$related->{$idAttr}][$widgetData['name']][] = $value;
                                 }
                                 // if the current widget is a specifier, maintain the data in a separate array to perform an array_intersect to
                                 if (true == $specifier) {
                                     if (!isset($specificWeights[$related->{$idAttr}])) {
                                         $specificWeights[$related->{$idAttr}] = 0;
                                     }
                                     $specificWeights[$related->{$idAttr}]++;
                                     continue;
                                 }
                                 $weights[$related->{$idAttr}]++;
                             }
                         }
                     }
                 }
             } else {
                 $values = $widgetData['value'];
                 if (!is_array($widgetData['value'])) {
                     $values = array($widgetData['value']);
                 }
                 if (null !== $widgetData['operator']) {
                     $op = $widgetData['operator'];
                     $allowed = $op->getAllowed();
                     $opVal = $op->getValue();
                     if (!is_null($opVal)) {
                         if (in_array($opVal, $allowed)) {
                             $op = $opVal;
                         } else {
                             $op = $allowed['default'];
                         }
                     } else {
                         $op = $allowed['default'];
                     }
                 } else {
                     $op = 'eq';
                 }
                 foreach ($values as $value) {
                     if ('' != trim($value)) {
                         $conditions++;
                         $cQ = One_Repository::selectQuery($this->scheme->getName());
                         $cQ->setSelect(array($idAttr));
                         $cQ->where($widgetData['name'], $op, $value);
                         $tmpResults = $cQ->execute(false);
                         foreach ($tmpResults as $tmpResult) {
                             if (!isset($weights[$tmpResult->{$idAttr}])) {
                                 if (false === $specifier) {
                                     $weights[$tmpResult->{$idAttr}] = 0;
                                 }
                                 $conditionByModel[$tmpResult->{$idAttr}] = array();
                             }
                             if (!isset($conditionByModel[$tmpResult->{$idAttr}][$widgetData['name']])) {
                                 $conditionByModel[$tmpResult->{$idAttr}][$widgetData['name']] = array();
                             }
                             $conditionByModel[$tmpResult->{$idAttr}][$widgetData['name']][] = $value;
                             // if the current widget is a specifier, maintain the data in a separate array to perform an array_intersect to
                             if (true == $specifier) {
                                 if (!isset($specificWeights[$tmpResult->{$idAttr}])) {
                                     $specificWeights[$tmpResult->{$idAttr}] = 0;
                                 }
                                 $specificWeights[$tmpResult->{$idAttr}]++;
                                 continue;
                             }
                             $weights[$tmpResult->{$idAttr}]++;
                         }
                     }
                 }
             }
         }
     }
     $tilt = $this->getSearchTilt($conditions);
     foreach ($weights as $id => $weight) {
         if (0 < count($specificWeights)) {
             if (false === array_key_exists($id, $specificWeights)) {
                 unset($weights[$id]);
                 unset($conditionByModel[$id]);
                 continue;
             } else {
                 $weight += $specificWeights[$id];
             }
         }
         $model = One_Repository::selectOne($this->scheme->getName(), $id);
         // using selectOne as the models needed here are already in cache, a global search by there id would take more resources
         $model->One_Search_Weight = round($weight / $conditions * 100, 2);
         $model->One_Search_Weight_Conditions = $conditions;
         $model->One_Search_Weight_ConditionsMet = $weight;
         $model->One_Search_Weight_ConditionObject = $conditionByModel[$id];
         $type = 'some';
         if ($conditions == $weight) {
             $type = 'all';
         } elseif ($conditions >= $tilt) {
             $type = 'most';
         }
         $results[$type][] = $model;
         $results['count']++;
     }
     foreach (array('all', 'most', 'some') as $type) {
         usort($results[$type], array($this, 'sortResultsByWeight'));
     }
     $session->set('results', $results, 'one_search');
     return $results;
 }
Exemplo n.º 3
0
 /**
  * Get the value
  *
  * @param One_Model $model
  * @return Mixed
  */
 public function getValue($model)
 {
     if (!$model) {
         return null;
     }
     // pick up vars entered entered from an invalidly filled in form
     $session = One_Repository::getSession();
     $posted = $session->get('posted', 'OneFormErrors');
     if (!in_array($this->getCfg('one'), array('one', 'yes', 'true', '1')) && isset($posted['oneForm'][$this->getName()])) {
         return $posted['oneForm'][$this->getName()];
     } else {
         if (isset($posted[$this->getName()])) {
             return $posted[$this->getName()];
         } else {
             $role = $this->getCfg('role');
             if (!is_null($role) && $model instanceof One_Model) {
                 $parts = explode(':', $role);
                 $related = $model->getRelated($parts[1]);
                 $relation = One_Repository::getRelation($parts[0]);
                 $role = $relation->getRole($parts[1]);
                 $relScheme = One_Repository::getScheme($role->schemeName);
                 if ($related instanceof One_Model) {
                     return $related[$relScheme->getIdentityAttribute()->getName()];
                 } elseif (is_array($related)) {
                     // $related is an array of One_Models
                     $returnValues = array();
                     foreach ($related as $r) {
                         $returnValues[] = $r[$relScheme->getIdentityAttribute()->getName()];
                     }
                     return $returnValues;
                 }
             } else {
                 //PD16FEB10 : add option to pick this up from request
                 if ($this->getCfg('from') != "") {
                     list($source, $key) = preg_split("/:/", $this->getCfg('from'));
                     switch ($source) {
                         case 'request':
                             $from = $_REQUEST;
                             if (!in_array($this->getCfg('one'), array('one', 'yes', 'true', '1'))) {
                                 $from = $_REQUEST['oneForm'];
                             }
                             if (isset($from[$key])) {
                                 return $from[$key];
                             }
                             break;
                     }
                 }
                 if ($this->getCfg('novalue') != "novalue") {
                     return $model[$this->getOriginalName()];
                 }
             }
         }
     }
 }
Exemplo n.º 4
0
 /**
  * Set links for the scheme when present
  *
  * @param One_Scheme $scheme
  * @param DOMXPath $xpath
  * @param DOMElement $meta
  */
 protected static function setRelationships(One_Scheme $scheme, DOMXPath $xpath, DOMElement $meta)
 {
     // 	create the link set for this scheme
     $relations = $xpath->query($meta->getNodePath() . '/relations/relation');
     for ($i = 0; $i < $relations->length; $i++) {
         $relationSpec = $relations->item($i);
         $relation = One_Repository::getRelation($relationSpec->getAttribute('name'));
         $relation->createLinks($scheme);
     }
 }