/** * Initialize the named page. This will load the widget instances and prepare for manipulating the UI. * * Each page has two parts, the HTML template, and the page instances config file (also called the .yaml file). * On the filesystem, they are named <pageName>.tpl (the template file) and <pageName>.yaml (the config file). * * Once the instances are initialized and configured, the module will be given a chance to load default settings for the page via a callback. * This is the time to set up select lists, default values, etc. * The method name that will be called on the module is "<pageName>_PageDidLoad". Here is the prototype for that method: * void <pageName>_PageDidLoad($page, $parameters); * * The parameters argument is an associative array, with "name" => "value". The items that will be in the array are determined by the page's parameterList, * which is provided by the <pageName>_ParameterList() method, you can implement if your page needs parameters. This method should simply return a list of * strings, which will become the "names" passed into your _PageDidLoad method. * * Here's how the parameterization works... for each item in the array, first the PATH_INFO is mapped to the items. So, if your parameterList is: * * array('itemID', 'otherParameter') * * And the PATH_INFO is /12/moreData then the parameters passed in will be array('itemID' => '12', 'otherParameter' => 'moreData'). * Any data that cannot be matched up will be passed with a NULL value. * Also, if there is a form submitted, then the values for the parameters will be replaced by the "value" of the outlets of the same name. * Thus, if your form has an "itemID" hidden field, the value from the form will supercede the value from PATH_INFO. * * After the _PageDidLoad call, the UI state from the request will be applied on top of the defaults. * * @todo Something is goofy with the detection of isRequestPage surrounding the action processor... seems to be getting called on the response page too. investiage. * @todo Rename this to executePage or something... this actually runs the whole page infrastructure! */ function initPage($pageName) { WFLog::log("Initing page {$pageName}", WFLog::TRACE_LOG); if (!empty($this->pageName)) { throw new Exception("Page already inited with: {$this->pageName}. Cannot initPage twice."); } $this->pageName = $pageName; // look for page delegate $pageDelegateClassName = $this->module->moduleName() . '_' . $this->pageName; if (class_exists($pageDelegateClassName, false)) { $delegate = new $pageDelegateClassName(); // look for case mismatch b/w instantiated name and name in URL; php class names are case-insensitive, so class_exists() can kinda false-positive on us here // the mistmatch of cases means that downstream users of the name (loading yaml files, etc) will unexpectedly fail. if ($pageDelegateClassName !== get_class($delegate)) { throw new WFRequestController_NotFoundException("Page {$this->pageName} not found."); // $this->pageName = substr(get_class($delegate), strlen($this->module->moduleName() . '_')); // upgrade name to correct for case } $this->setDelegate($delegate); } // calculate various file paths $basePagePath = $this->module->pathToPage($this->pageName); $yamlFile = $basePagePath . '.yaml'; $instancesFile = $basePagePath . '.instances'; $configFile = $basePagePath . '.config'; if (file_exists($yamlFile)) { WFLog::log("Loading YAML config: {$pageName}.yaml", WFLog::TRACE_LOG); $yamlConfig = WFYaml::load($yamlFile); //print_r($yamlConfig); foreach ($yamlConfig as $id => $instanceManifest) { $this->initInstanceYAML($id, $instanceManifest); } // after all config info is loaded, certain widget types need to "update" things... // since we don't control the order of property loading (that would get way too complex) we just handle some things at the end of the loadConfig foreach ($this->instances as $viewId => $view) { $view->allConfigFinishedLoading(); } } else { // parse instances file and instantiate all objects be graceful -- no need to have fatal error if there are no instances if (file_exists($instancesFile)) { include $instancesFile; foreach ($__instances as $id => $instanceManifest) { $this->initInstancePHP($id, $instanceManifest); } // parse config file - for each instance, see if there is a config setup for that instance ID and apply it. // note: this will call allConfigFinishedLoading automatically $this->loadConfig($configFile); } } // let delegate know the page instances are ready $this->pageInstancesDidLoad(); // restore UI state, if this is the requestPage // must happen AFTER config is loaded b/c some config options may affect how the widgets interpret the form data. // must happen BEFORE _PageDidLoad callback because that callback may need to access widget data, before it's available via bindings. if ($this->isRequestPage()) { $this->restoreState(); } // the PARAMTERS are ONLY determined for the requestPage! // Calculate parameters $parameters = array(); $parameterList = $this->parameterList(); // get parameter definition from delegate if ($this->isRequestPage()) { WFLog::log("Parameterizing {$pageName}", WFLog::TRACE_LOG); if (count($parameterList) > 0) { // first map all items through from PATH_INFO // @todo Right now this doesn't allow DEFAULT parameter values (uses NULL). Would be nice if this supported assoc_array so we could have defaults. $invocationParameters = $this->module->invocation()->parameters(); $defaultOpts = array('defaultValue' => NULL, 'greedy' => false); $i = 0; $lastI = count($parameterList) - 1; foreach ($parameterList as $k => $v) { if (gettype($k) === 'integer') { $opts = $defaultOpts; $parameterKey = $v; } else { $parameterKey = $k; if (is_array($v)) { $opts = array_merge($defaultOpts, $v); } else { $opts = $defaultOpts; $opts['defaultValue'] = $v; } } if (isset($invocationParameters[$i])) { // handle greedy if ($i === $lastI and $opts['greedy'] === true and count($invocationParameters) > count($parameterList)) { $parameters[$parameterKey] = join('/', array_slice($invocationParameters, $i)); } else { $parameters[$parameterKey] = $invocationParameters[$i]; } } else { $parameters[$parameterKey] = isset($_REQUEST[$parameterKey]) ? $_REQUEST[$parameterKey] : $opts['defaultValue']; } $i++; } // then over-ride with from form, if one has been submitted if ($this->hasSubmittedForm()) { foreach ($parameterList as $id) { if (!$this->hasOutlet($id)) { continue; } // see if there is an instance of the same name in the submitted form $instance = $this->outlet($id); if ($instance instanceof WFWidget) { // walk up looking for parent $parent = $instance->parent(); do { if ($parent and $parent instanceof WFForm and $parent->name() == $this->submittedFormName()) { $parameters[$id] = $this->outlet($id)->value(); break; } if (!is_object($parent)) { throw new Exception("Error processing parameter overload for parameter id: '{$id}': found widget of same id, but cannot determine the form that it belongs to. Are you sure that widget id: '{$id}' is in a WFForm?"); } $parent = $parent->parent(); } while ($parent); } } } } } else { WFLog::log("Skipping Parameterization for {$pageName}", WFLog::TRACE_LOG); if (count($parameterList) > 0) { // NULL-ify all params for ($i = 0; $i < count($parameterList); $i++) { $parameters[$parameterList[$i]] = NULL; } } } // save completed parameters $this->parameters = $parameters; // inform delegate that params are ready $this->parametersDidLoad(); // parametersDidLoad may have affected the arrayControllers $this->createDynamicWidgets(); // restore UI state AGAIN so that any controls created dynamically can update their values based on the UI state. if ($this->isRequestPage()) { $this->restoreState(); } // now that the UI is set up (instantiated), it's time to propagate the values from widgets to bound objects if this is the requestPage! // then, once the values are propagated, we should call the action handler for the current event, if there is one. if ($this->isRequestPage()) { // let delegate know that we're about to push bindings - this is effectively a statement of "we're in 'postback', deal with it if you must" $this->willPushBindings(); // willPushBindings may have affected the arrayControllers $this->createDynamicWidgets(); // push values of bound properties back to their bound objects $this->module->requestPage()->pushBindings(); // Determine action: do we need to call the noAction handler? $rpc = NULL; if ($this->hasSubmittedForm()) { // look for action in the form data $rpc = WFRPC::rpcFromRequest($this->module()->invocation()->invocationPath()); if (!$rpc) { // look for the submit button; // look up the instance ID for the specified action... look for "action|<actionOutletID>" in $_REQUEST... // but need to skip the _x and _y fields submitted with image submit buttons $actionOutletID = NULL; foreach ($_REQUEST as $name => $value) { if (strncmp("action|", $name, 7) == 0 and !in_array(substr($name, -2, 2), array('_x', '_y'))) { list(, $actionOutletID) = explode('|', $name); break; } } // if there is no button found in the parameters, we ask the WFForm what the default submit button is if (!$actionOutletID) { $form = $this->outlet($this->submittedFormName()); $actionOutletID = $form->defaultSubmitID(); WFLog::log("Form submitted, but no action button detected. Using default button: {$actionOutletID}", WFLog::TRACE_LOG); } // call the ACTION handler for the page, if there is an action. if ($actionOutletID) { try { $action = $this->outlet($actionOutletID)->submitAction(); $action->rpc()->setArguments(array($actionOutletID, 'click')); $rpc = $action->rpc(); } catch (Exception $e) { throw new WFException("Could not find form button (outlet) for current action: {$actionOutletID}. Make sure that you don't have nested forms!"); } } else { WFLog::log("No action occurred (no action specified in form data)", WFLog::WARN_LOG); } } } else { // look for action in Params // new-school WFAction stuff; $rpc = WFRPC::rpcFromRequest($this->module()->invocation()->invocationPath()); } // deal with action if ($rpc) { $shouldRun = false; if ($this->hasSubmittedForm()) { if ($rpc->runsIfInvalid() or !$rpc->runsIfInvalid() and $this->formIsValid()) { if ($rpc->runsIfInvalid()) { $this->setIgnoreErrors(true); // runsIfInvalid by default implies ignoreErrors } $shouldRun = true; } else { if ($rpc->isAjax()) { $this->sendPageErrorsOverAjax(); } } if ($shouldRun === false) { $this->willNotRunAction(); } } else { $shouldRun = true; } if ($shouldRun) { try { $rpc->execute($this); } catch (WFErrorCollection $e) { // Automagically map all errors for keys to widgets with the same ID // note that propagateErrorsForKey* functions may prune errors // from the original WFErrorCollection before we get here. foreach ($this->instances as $id => $obj) { if ($e->hasErrorsForKey($id)) { $this->propagateErrorsForKeyToWidget($e, $id, $obj, true); } } // add all remaining errors to the general error display $this->addErrors($e->allErrors()); } if ($rpc->isAjax() and count($this->errors())) { $this->sendPageErrorsOverAjax(); } } } else { $this->noAction(); } // action/noAction may have affecting the arrayControllers $this->createDynamicWidgets(); } }
/** * Prepare any declared shared instances for the module. * * Shared Instances are objects that not WFView subclasses. Only WFView subclasses may be instantiated in the <pageName>.instances files. * The Shared Instances mechanism is used to instantiate any other objects that you want to use for your pages. Usually, these are things * like ObjectControllers or Formatters, which are typically "shared" across multiple pages. The Shared Instances mechanism makes it * easy to instantiate and configure the properties of objects without coding, and have these objects accessible for bindings or properties. * Of course, you can instantiate objects yourself and use them programmatically. This is just a best-practice for a common situation. * * The shared instances mechanism simply looks for a shared.instances and a shared.config file in your module's directory. The shared.instances * file should simply have a var $__instances that is an associative array of 'unique id' => 'className'. For each declared instance, the * module's instance var $this->$uniqueID will be set to a new instance of "className". * * <code> * $__instances = array( * 'instanceID' => 'WFObjectController', * 'instanceID2' => 'WFUnixDateFormatter' * ); * </code> * * To bind to a shared instance (or for that matter any object that's an instance var of the module), set the instanceID to "#module#, * leave the controllerKey blank, and set the modelKeyPath to "<instanceVarName>.rest.of.key.path". * * To use a shared instance as a property, .................... NOT YET IMPLEMENTED. * * * @todo Allow properties of page.config files to use shared instances. */ function prepareSharedInstances() { $app = WFWebApplication::sharedWebApplication(); $modDir = $this->invocation()->modulesDir(); $moduleInfo = new ReflectionObject($this); $yamlFile = $modDir . '/' . $this->invocation->modulePath() . '/shared.yaml'; if (file_exists($yamlFile)) { $yamlConfig = WFYaml::load($yamlFile); foreach ($yamlConfig as $id => $instInfo) { try { $moduleInfo->getProperty($id); } catch (Exception $e) { WFLog::log("shared.yaml:: Module '" . get_class($this) . "' does not have property '{$id}' declared.", WFLog::WARN_LOG); } // instantiate, keep reference in shared instances WFLog::log("instantiating shared instance id '{$id}'", WFLog::TRACE_LOG); $this->__sharedInstances[$id] = $this->{$id} = new $instInfo['class'](); WFLog::log("loading config for shared instance id '{$id}'", WFLog::TRACE_LOG); // get the instance to apply config to if (!isset($this->{$id})) { throw new WFException("Couldn't find shared instance with ID '{$id}' to configure."); } $configObject = $this->{$id}; // atrributes if (isset($instInfo['properties'])) { foreach ($instInfo['properties'] as $keyPath => $value) { switch (gettype($value)) { case "boolean": case "integer": case "double": case "string": case "NULL": // these are all OK, fall through break; default: throw new WFException("Config value for shared instance id::property '{$id}::{$keyPath}' is not a vaild type (" . gettype($value) . "). Only boolean, integer, double, string, or NULL allowed."); break; } WFLog::log("SharedConfig:: Setting '{$id}' property, {$keyPath} => {$value}", WFLog::TRACE_LOG); $configObject->setValueForKeyPath($value, $keyPath); } } } } else { $instancesFile = $modDir . '/' . $this->invocation->modulePath() . '/shared.instances'; $configFile = $modDir . '/' . $this->invocation->modulePath() . '/shared.config'; if (file_exists($instancesFile)) { include $instancesFile; foreach ($__instances as $id => $class) { // enforce that the instance variable exists try { $moduleInfo->getProperty($id); } catch (Exception $e) { WFLog::log("shared.instances:: Module '" . get_class($this) . "' does not have property '{$id}' declared.", WFLog::WARN_LOG); } // instantiate, keep reference in shared instances $this->__sharedInstances[$id] = $this->{$id} = new $class(); } // configure the new instances $this->loadConfigPHP($configFile); } } // call the sharedInstancesDidLoad() callback $this->sharedInstancesDidLoad(); }
require_once getenv('PHOCOA_PROJECT_CONF'); $modulePath = rtrim($argv[1], '/'); $dir = $modulePath; print "About to convert shared setup to YAML for module at: '{$modulePath}'\n"; $instancesFile = "{$dir}/shared.instances"; $configFile = "{$dir}/shared.config"; if (!file_exists($instancesFile)) { print "No instances file for module, thus no YAML conversion needed.\n"; exit(0); } include $instancesFile; if (file_exists($configFile)) { include $configFile; } else { $__config = array(); } $combined = array(); foreach ($__instances as $id => $class) { $combined[$id]['class'] = $class; if (isset($__config[$id])) { $combined[$id]['properties'] = $__config[$id]['properties']; } } $yaml = WFYaml::dump($combined); $bytes = file_put_contents("{$dir}/shared.yaml", $yaml); if ($bytes === false) { print "Failed saving yaml file: {$dir}/shared.yaml\n"; exit(1); } print "Saved YAML for module to file: {$dir}/shared.yaml\n"; exit(0);
public function loadFromYaml($yamlString, $saveMethod = NULL) { // load the fixtures data & process $allCreatedObjects = $this->processObjectList(WFYaml::loadString($yamlString)); if ($saveMethod) { foreach ($allCreatedObjects as $o) { try { $o->{$saveMethod}(); } catch (Exception $e) { throw new WFException("Error saving object: " . $o . "\n" . $e->getMessage()); } } } return $allCreatedObjects; }
function generateModuleForEntity($entity) { print "Generating module for entity '" . $entity->valueForKey('name') . "'\n"; $cwd = getcwd(); $moduleName = strtolower($entity->valueForKey('name')); $moduleDir = $cwd . '/' . $moduleName; if (file_exists($moduleDir)) { print "WARNING: Module {$moduleName} already exists. Skipping\n"; return; } mkdir($moduleDir); // module dir $this->modulePath .= $moduleName; // setup shared instances $sharedYaml[$entity->valueForKey('name')] = array('class' => 'WFArrayController', 'properties' => array('class' => $entity->valueForKey('name'), 'classIdentifiers' => $entity->valueForKey('primaryKeyProperty'), 'selectOnInsert' => true, 'automaticallyPreparesContent' => false)); $sharedYaml['paginator'] = array('class' => 'WFPaginator', 'properties' => array('modeForm' => 'search', 'pageSize' => 25, 'itemPhraseSingular' => $entity->valueForKey('name'), 'itemPhrasePlural' => $entity->valueForKey('name') . 's')); file_put_contents($moduleDir . '/shared.yaml', WFYaml::dump($sharedYaml)); $sharedEntityId = $entity->valueForKey('name'); // build module code $this->smarty->assign('moduleName', $moduleName); $this->smarty->assign('entity', $entity); $this->smarty->assign('entityName', $entity->valueForKey('name')); $this->smarty->assign('sharedEntityId', $sharedEntityId); $this->smarty->assign('sharedEntityPrimaryKeyProperty', $entity->valueForKey('primaryKeyProperty')); $this->smarty->assign('descriptiveColumnName', $entity->valueForKey('descriptiveColumnName')); // look up Peer column constant name from the PHP name; call ObjPeer::translateFieldName($name, $fromType, $toType) $translateF = array($entity->valueForKey('name') . 'Peer', 'translateFieldName'); $peerColName = call_user_func($translateF, ucfirst($entity->valueForKey('descriptiveColumnName')), BasePeer::TYPE_PHPNAME, BasePeer::TYPE_FIELDNAME); $this->smarty->assign('descriptiveColumnConstantName', strtoupper($peerColName)); $moduleCode = $this->smarty->fetch(FRAMEWORK_DIR . '/framework/generator/module.tpl'); file_put_contents($moduleDir . '/' . $moduleName . '.php', $moduleCode); // build list page // list.yaml $listYaml = array(); $listFormId = 'search' . $entity->valueForKey('name') . 'Form'; $listYaml[$listFormId] = array('class' => 'WFForm', 'children' => array('search' => array('class' => 'WFSubmit', 'properties' => array('label' => 'Search')), 'clear' => array('class' => 'WFSubmit', 'properties' => array('label' => 'Clear')), 'paginatorState' => array('class' => 'WFPaginatorState', 'properties' => array('paginator' => '#module#paginator')), 'query' => array('class' => 'WFTextField'))); $listYaml['paginatorNavigation'] = array('class' => 'WFPaginatorNavigation', 'properties' => array('paginator' => '#module#paginator')); $listYaml['paginatorPageInfo'] = array('class' => 'WFPaginatorPageInfo', 'properties' => array('paginator' => '#module#paginator')); $descriptiveColumnName = $entity->valueForKey('descriptiveColumnName'); $listYaml[$descriptiveColumnName] = array('class' => 'WFDynamic', 'properties' => array('arrayController' => "#module#{$sharedEntityId}"), 'children' => array("{$descriptiveColumnName}Prototype" => array('class' => 'WFLink', 'bindings' => array('value' => array('instanceID' => $sharedEntityId, 'controllerKey' => '#current#', 'modelKeyPath' => $entity->valueForKey('primaryKeyProperty'), 'options' => array('ValuePattern' => $this->modulePath . '/detail/%1%')), 'label' => array('instanceID' => $sharedEntityId, 'controllerKey' => '#current#', 'modelKeyPath' => $entity->valueForKey('descriptiveColumnName')))))); $listYaml['editLink'] = array('class' => 'WFDynamic', 'properties' => array('arrayController' => "#module#{$sharedEntityId}"), 'children' => array("editLinkPrototype" => array('class' => 'WFLink', 'properties' => array('label' => 'Edit'), 'bindings' => array('value' => array('instanceID' => $sharedEntityId, 'controllerKey' => '#current#', 'modelKeyPath' => $entity->valueForKey('primaryKeyProperty'), 'options' => array('ValuePattern' => $this->modulePath . '/edit/%1%')))))); $listYaml['deleteLink'] = array('class' => 'WFDynamic', 'properties' => array('arrayController' => "#module#{$sharedEntityId}"), 'children' => array("deleteLinkPrototype" => array('class' => 'WFLink', 'properties' => array('label' => 'Delete'), 'bindings' => array('value' => array('instanceID' => $sharedEntityId, 'controllerKey' => '#current#', 'modelKeyPath' => $entity->valueForKey('primaryKeyProperty'), 'options' => array('ValuePattern' => $this->modulePath . '/confirmDelete/%1%')))))); file_put_contents($moduleDir . '/list.yaml', WFYaml::dump($listYaml)); // build list.tpl $this->smarty->assign('listFormId', $listFormId); file_put_contents($moduleDir . '/list.tpl', $this->smarty->fetch(FRAMEWORK_DIR . '/framework/generator/list.tpl')); // build edit page // build edit.yaml $editYaml = array(); $editFormId = 'edit' . $entity->valueForKey('name') . 'Form'; $editYaml[$editFormId] = array('class' => 'WFForm', 'children' => array()); $widgets = array(); foreach ($entity->getProperties() as $property) { $widgetID = $property->valueForKey('name'); $widgets[$widgetID] = $property; if ($property->valueForKey('name') === $entity->valueForKey('primaryKeyProperty')) { $class = 'WFHidden'; } else { switch ($property->valueForKey('type')) { case WFModelEntityProperty::TYPE_TEXT: $class = 'WFTextArea'; break; case WFModelEntityProperty::TYPE_NUMBER: case WFModelEntityProperty::TYPE_STRING: case WFModelEntityProperty::TYPE_DATETIME: case WFModelEntityProperty::TYPE_TIME: case WFModelEntityProperty::TYPE_DATE: $class = 'WFTextField'; break; case WFModelEntityProperty::TYPE_BOOLEAN: $class = 'WFCheckbox'; break; default: $class = 'WFTextField'; } } $editYaml[$editFormId]['children'][$widgetID] = array('class' => $class, 'bindings' => array('value' => array('instanceID' => $sharedEntityId, 'controllerKey' => 'selection', 'modelKeyPath' => $widgetID))); } // status message $editYaml['statusMessage'] = array('class' => 'WFMessageBox'); $editYaml[$editFormId]['children']['saveNew'] = array('class' => 'WFSubmit', 'properties' => array('label' => 'Create ' . $entity->valueForKey('name'), 'action' => 'save'), 'bindings' => array('hidden' => array('instanceID' => $sharedEntityId, 'controllerKey' => 'selection', 'modelKeyPath' => 'isNew', 'options' => array('valueTransformer' => 'WFNegateBoolean')))); $editYaml[$editFormId]['children']['save'] = array('class' => 'WFSubmit', 'properties' => array('label' => 'Save'), 'bindings' => array('hidden' => array('instanceID' => $sharedEntityId, 'controllerKey' => 'selection', 'modelKeyPath' => 'isNew'))); $editYaml[$editFormId]['children']['deleteObj'] = array('class' => 'WFSubmit', 'properties' => array('label' => 'Delete'), 'bindings' => array('hidden' => array('instanceID' => $sharedEntityId, 'controllerKey' => 'selection', 'modelKeyPath' => 'isNew'))); file_put_contents($moduleDir . '/edit.yaml', WFYaml::dump($editYaml)); // build edit.tpl $this->smarty->assign('editFormId', $editFormId); $this->smarty->assign('widgets', $widgets); file_put_contents($moduleDir . '/edit.tpl', $this->smarty->fetch(FRAMEWORK_DIR . '/framework/generator/edit.tpl')); // build confirmDelete page $confirmDeleteYaml = array(); $confirmDeleteFormId = 'confirmDelete' . $entity->valueForKey('name') . 'Form'; $pkId = $entity->valueForKey('primaryKeyProperty'); $confirmDeleteYaml[$confirmDeleteFormId] = array('class' => 'WFForm', 'children' => array($pkId => array('class' => 'WFHidden', 'bindings' => array('value' => array('instanceID' => $sharedEntityId, 'controllerKey' => 'selection', 'modelKeyPath' => $entity->valueForKey('primaryKeyProperty')))), 'cancel' => array('class' => 'WFSubmit', 'properties' => array('label' => 'Cancel')), 'deleteObj' => array('class' => 'WFSubmit', 'properties' => array('label' => 'Delete')))); $confirmDeleteYaml['confirmMessage'] = array('class' => 'WFMessageBox', 'bindings' => array('value' => array('instanceID' => $sharedEntityId, 'controllerKey' => 'selection', 'modelKeyPath' => $descriptiveColumnName, 'options' => array('ValuePattern' => 'Are you sure you want to delete ' . $entity->valueForKey('name') . ' "%1%"?')))); file_put_contents($moduleDir . '/confirmDelete.yaml', WFYaml::dump($confirmDeleteYaml)); // confirmDelete.tpl file $this->smarty->assign('confirmDeleteFormId', $confirmDeleteFormId); file_put_contents($moduleDir . '/confirmDelete.tpl', $this->smarty->fetch(FRAMEWORK_DIR . '/framework/generator/confirmDelete.tpl')); // delete success $deleteSuccessYaml = array(); $deleteSuccessYaml['statusMessage'] = array('class' => 'WFMessageBox', 'properties' => array('value' => $entity->valueForKey('name') . ' successfully deleted.')); file_put_contents($moduleDir . '/deleteSuccess.yaml', WFYaml::dump($deleteSuccessYaml)); file_put_contents($moduleDir . '/deleteSuccess.tpl', $this->smarty->fetch(FRAMEWORK_DIR . '/framework/generator/deleteSuccess.tpl')); // detail page $detailYaml = array(); $widgets = array(); foreach ($entity->getProperties() as $property) { $widgetID = $property->valueForKey('name'); $widgets[$widgetID] = $property; $detailYaml[$widgetID] = array('class' => 'WFLabel', 'bindings' => array('value' => array('instanceID' => $sharedEntityId, 'controllerKey' => 'selection', 'modelKeyPath' => $widgetID))); } file_put_contents($moduleDir . '/detail.yaml', WFYaml::dump($detailYaml)); // build detail.tpl $this->smarty->assign('widgets', $widgets); file_put_contents($moduleDir . '/detail.tpl', $this->smarty->fetch(FRAMEWORK_DIR . '/framework/generator/detail.tpl')); }
function testLoadString() { $this->assertEquals($this->fixtureShouldBe, WFYaml::loadString(file_get_contents(dirname(__FILE__) . '/WFYamlTest.yaml'))); }