/** * This function performs the cancellation and returns to the proper page */ public function execute() { if (!is_null($this->getVariable('cancelToOne'))) { parse_str(base64_decode($this->getVariable('cancelToOne')), $returnVals); $this->controller->setRedirect($returnVals); } else { $formFile = $this->getVariable('formFile', 'form'); $form = One_Form_Factory::createForm($this->scheme, $formFile, $this->getVariable('lang'), 'oneForm', ''); $flow = One_Controller_Flow::getInstance($this->scheme)->getRedirects(); $redirects = array_merge($flow, $form->getRedirects()); $todo = 'cancel'; if (isset($this->options['flow'])) { $todo = $this->options['flow']; } $redirect = $redirects['default']; if (isset($redirects[$todo])) { $redirect = $redirects[$todo]; } if (isset($redirect['id']) && strtoupper(trim($redirect['id'])) == '::ID::') { $redirect['id'] = $this->id; } $redirect = $this->replaceOtherVariables($redirect); $this->controller->setRedirect($redirect); } }
public function get($formFile, One_Model $model, array $options = array()) { $cx = new One_Context(); $formName = 'oneForm'; $action = ''; $task = 'edit'; $scheme = $model->getScheme(); if (isset($options['action'])) { $action = $options['action']; } if (isset($options['formName'])) { $formName = $options['formName']; } if (is_null($model->task) || trim($model->task) == '') { if (!is_null($cx->get('task'))) { $task = $cx->get('task'); } if (isset($options['task'])) { $task = $options['task']; } } else { $task = $model->task; } $form = One_Form_Factory::createForm($scheme, $formFile, NULL, $formName, $action); return $form; }
/** * This method composes the form and returns the output * * @return string Output of the form */ public function execute() { // Fetch the model needed for this form. We will need it because authorization can depend on the model itself if ($this->id) { $factory = One_Repository::getFactory($this->scheme->getName()); $model = $factory->selectOne($this->id); } else { $model = One::make($this->scheme->getName()); } if (is_null($model)) { throw new One_Exception('Could not generate a form for scheme "' . $this->scheme->getName() . '" with id ' . $this->id); } $this->authorize($this->scheme->getName(), $model->id); $session = One_Repository::getSession(); $formFile = $this->getVariable('formFile', 'form'); $form = One_Form_Factory::createForm($this->scheme, $formFile, $this->getVariable('lang'), 'oneForm', ''); // Create a DOM and render the form in it $dom = One_Repository::createDom(); $form->render($model, $dom); // print_r($dom); $this->view->setModel($model); $this->view->set('scheme', $this->scheme); $this->view->set('form', $form); $this->view->set('dom', $dom); $this->view->set('errors', $session->get('errors', 'OneFormErrors')); $vForm = $this->view->show(); $session->remove('errors', 'OneFormErrors'); $session->remove('posted', 'OneFormErrors'); return $vForm; }
/** * Render the output of the widget and add it to the DOM * * @param One_Model $model * @param One_Dom $dom * @final */ public final function render($model, One_Dom $dom) { $id = $this->getID(); $condition = $this->getCfg('condition'); if (!is_null($condition)) { $args = array('model' => $model); if (!One_Form_Factory::authorize($condition, $args)) { return; } } $this->_render($model, $dom); }
/** * Apply filters to the queryscheme * * @param One_Query $q */ public function affect(One_Query $query) { $filters = $this->filters(); $searchform = $filters['searchform']; $cx = new One_Context(); $scheme = $query->getScheme(); $idAttr = $scheme->getIdentityAttribute()->getName(); $form = One_Form_Factory::createForm($scheme, $searchform); $widgets = $this->getWidgets($form, $scheme); foreach ($widgets as $widget) { $widget->affectQuery($query); } // for searchresults, results can always be grouped by id, since we only want to show a same result once $query->setGroup($idAttr); }
/** * Identifies whether the passed name is a widget or a container and pass it's classname * * @param string $name * @return string */ protected static function identifyElement($name) { // echo $name; $availableCW = One_Form_Factory::getAvailable(); // print_r($availableCW); $className = NULL; if (in_array($name, $availableCW['containers'])) { $className = 'One_Form_Container_' . ucfirst($name); } elseif (in_array($name, $availableCW['widgets'])) { $single = array('submit', 'label', 'button', 'nscript', 'inline', 'defaultactions'); if (in_array($name, $single)) { $className = 'One_Form_Widget_' . ucfirst($name); } else { $parts = explode('-', $name); $className = 'One_Form_Widget_' . ucfirst($parts[0]) . '_' . ucfirst($parts[1]); } return new $className(); } elseif (in_array(self::$_defaultWidget . '-' . $name, $availableCW['widgets'])) { $className = 'One_Form_Widget_' . ucfirst(self::$_defaultWidget) . '_' . ucfirst($name); } // echo $className; return $className; }
/** * Get all available containers and widgets * * @return array */ public static function getAvailable() { if (is_null(self::$availableCW)) { $containers = array(); $places = One_Locator::locateAllUsing('*.php', '%ROOT%/form/container/'); $ignore = array('abstract', 'index', 'factory'); foreach ($places as $container) { $container = preg_replace('/_tbd.php$/', '.php', $container); //TODO: replace tmp fix if (preg_match('|([^/]*).php$|', $container, $match)) { if (in_array($match[1], $ignore) || strpos($match[1], '.') !== false) { unset($containers[$container]); } else { $containers[$container] = strtolower($match[1]); } } else { unset($containers[$container]); } } sort($containers); $widgets = array(); $places = One_Locator::locateAllUsing('*.php', '%ROOT%/form/widget/{joomla,multi,scalar,select,search}/'); foreach ($places as $widget) { $widget = preg_replace('/_tbd.php$/', '.php', $widget); //TODO: replace tmp fix if (preg_match('|([^/]*)/([^/]*).php$|', $widget, $match)) { if (!in_array($match[2], $ignore)) { $widgets[] = $match[1] . '-' . strtolower($match[2]); } } } $widgets[] = 'defaultactions'; $widgets[] = 'button'; $widgets[] = 'file'; $widgets[] = 'submit'; $widgets[] = 'label'; $widgets[] = 'button'; $widgets[] = 'nscript'; $widgets[] = 'inline'; //TODO: adding a widget here should not be necessary !! sort($widgets); self::$availableCW = array('containers' => $containers, 'widgets' => $widgets); } return self::$availableCW; }
/** * This method validates a submitted form and returns to the proper page according to whether the submission * contained errors or whether the form was saved or applied */ public function execute() { $session = One_Repository::getSession(); $isNew = false; if ($this->id) { // update existing $factory = One_Repository::getFactory($this->scheme->getName()); $model = $factory->selectOne($this->id); if (is_null($model) && !$factory->getScheme()->getIdentityAttribute()->isAutoInc()) { $model = One::make($this->scheme->getName()); $isNew = true; } } else { $model = One::make($this->scheme->getName()); } $idAttrName = $model->getScheme()->getIdentityAttribute()->getName(); $this->authorize($this->scheme->getName(), $model->{$idAttrName}); $formFile = $this->getVariable('formFile', 'form'); $form = One_Form_Factory::createForm($this->scheme, $formFile, $this->getVariable('lang'), 'oneForm', ''); $flow = One_Controller_Flow::getInstance($this->scheme)->getRedirects(); $noErrors = $form->validate(); if ($noErrors || is_array($noErrors) && count($noErrors) == 0) { $form->bindModel($model); if ($this->id && !$isNew) { $model->update(); $id = $this->id; } else { $model->insert(); $idAttr = $this->scheme->getIdentityAttribute()->getName(); $id = $model->{$idAttr}; } $this->model = $model; // handle redirects // @TODO this code can use some cleanup $redirects = array_merge($flow, $form->getRedirects()); $todo = is_null($this->getVariable('action')) ? $this->getVariable('task') : $this->getVariable('action'); if (isset($this->options['flow'])) { $todo = $this->options['flow']; } $redirect = $redirects['default']; if (isset($redirects[$todo])) { $redirect = $redirects[$todo]; } if (isset($redirect['id']) && strtoupper(trim($redirect['id'])) == '::ID::') { $redirect['id'] = $model->{$idAttrName}; } $redirect = $this->replaceOtherVariables($redirect); $this->controller->setRedirect($redirect); } else { $errors = base64_encode(serialize($form->getErrors())); $session->set('executedReturn', $model, 'executedForm'); $session->set('errors', $form->getErrors(), 'OneFormErrors'); $session->set('posted', $_REQUEST, 'OneFormErrors'); $id = $this->id; $toView = 'edit'; if (!is_null($this->getVariable('returnToOne'))) { parse_str(base64_decode($this->getVariable('returnToOne')), $returnVals); $this->controller->setRedirect($returnVals); } else { $redirects = array_merge($flow, $form->getRedirects()); $todo = 'default'; if (isset($this->options['flowerror'])) { $todo = $this->options['flowerror']; } elseif (isset($redirects['formerror'])) { $todo = 'formerror'; } $redirect = $redirects[$todo]; if (isset($redirect['id']) && strtoupper(trim($redirect['id'])) == '::ID::') { $redirect['id'] = $model->{$idAttrName}; } $redirect = $this->replaceOtherVariables($redirect); $this->controller->setRedirect($redirect); } return false; } }
/** * 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; }