/**
  * Saves a component to cache.
  *
  * This method saves the serialized component into memory and as a file (if necessary).
  *
  * Derived classes may override this method to provide other ways of caching component.
  * Be sure to override {@link cloneComponent} to make it consistent.
  * @param TComponent the component to be cached
  * @see cloneComponent()
  */
 public function cacheComponent($component)
 {
     if (!$this->enabled) {
         return;
     }
     $type = get_class($component);
     $id = empty($this->currentModule) ? $type : $this->currentModule . '.' . $type;
     if ($component instanceof TPage) {
         $data = array(TComponent::getDefinition(null), $component);
     } else {
         $data = array(TComponent::getDefinition($type), $component);
     }
     $data = serialize($data);
     if (!isset($this->components[$id])) {
         $this->components[$id] = $data;
         if (!empty($this->savePath)) {
             $cacheFile = $this->savePath . '/' . $type . self::EXT_CACHE;
             if (!file_exists($cacheFile)) {
                 $fp = fopen($cacheFile, "wb");
                 if ($fp) {
                     if (flock($fp, LOCK_EX)) {
                         fputs($fp, $data);
                         flock($fp, LOCK_UN);
                     }
                     fclose($fp);
                 }
             }
         }
     }
 }
 /**
  * Instantiates a template for a component.
  * Components declared in the template will be instantiated
  * and added as children of the component. The container-containee
  * relationship will also be established.
  * @param TComponent the owner of the template
  * @param array the parsing result returned by TResourceParser.
  */
 public function instantiateTemplate($component, $template)
 {
     $application = pradoGetApplication();
     if (is_string($template)) {
         $template = $application->getResourceParser()->parseTemplate($template);
     }
     $components = array();
     foreach ($template as $key => $object) {
         //special directives
         if ((string) $object[0] === 'directive') {
             $directiveClass = 'T' . $object[1] . 'Directive';
             $directive = new $directiveClass();
             $directive->assess($object[2], $this);
         } else {
             if (count($object) > 2) {
                 // component
                 list($cid, $type, $id, $attributes) = $object;
                 $child = $application->createComponent($type, $id);
                 $childSpec = TComponent::getDefinition($type);
                 foreach ($attributes as $name => $value) {
                     if ($childSpec->canSetProperty($name)) {
                         if (strlen($value) > 1 && $value[0] === '#') {
                             if ($value[1] !== '#') {
                                 $child->bindProperty($name, substr($value, 1));
                             } else {
                                 $child->setPropertyInitValue($name, substr($value, 1));
                             }
                         } else {
                             $child->setPropertyInitValue($name, $value);
                         }
                     } else {
                         if ($childSpec->hasEvent($name)) {
                             $child->attachEventHandler($name, $value);
                         } else {
                             $child->setAttribute($name, $value);
                         }
                     }
                 }
                 if ($child instanceof TControl) {
                     $child->initSkin($child->getPropertyInitValue("Skin"));
                 }
                 $child->initProperties();
                 $components[$key] = $child;
                 $container = isset($components[$cid]) ? $components[$cid] : $component;
                 $container->addParsedObject($child, $component);
             } else {
                 // static text
                 $cid = (string) $object[0];
                 $container = isset($components[$cid]) ? $components[$cid] : $component;
                 $container->addParsedObject($object[1], $component);
             }
         }
     }
 }