/**
  * Recursively creates parent folders
  *
  * @param string $path
  * @return sfAssetFolder
  */
 public function createFromPath($path)
 {
     $path = self::cleanPath($path, DIRECTORY_SEPARATOR);
     list($parent_path, $name) = sfAssetsLibraryTools::splitPath($path);
     if (!($parent_folder = $this->retrieveByPath($parent_path))) {
         $parent_folder = $this->createFromPath($parent_path);
         $parent_folder->save();
     }
     $folder = new sfAssetFolder();
     $folder->setName($name);
     $folder->setRelativePath($path);
     $folder->getNode()->insertAsLastChildOf($parent_folder);
     $folder->save();
     return $folder;
 }
 $sfAsset->setFilename('filename.jpg');
 $t->diag('sfAsset::getRelativePath()');
 $t->is($sfAsset->getRelativePath(), sfConfig::get('app_sfAssetsLibrary_upload_dir') . DIRECTORY_SEPARATOR . 'filename.jpg', 'getRelativePath() returns the path relative to the media directory');
 $t->diag('sfAsset::getFullPath()');
 $t->is($sfAsset->getFullPath(), sfConfig::get('sf_web_dir') . DIRECTORY_SEPARATOR . sfConfig::get('app_sfAssetsLibrary_upload_dir') . DIRECTORY_SEPARATOR . 'filename.jpg', 'getFullPath() returns the complete asset path on the disk');
 $t->is($sfAsset->getFullPath('small'), sfConfig::get('sf_web_dir') . DIRECTORY_SEPARATOR . sfConfig::get('app_sfAssetsLibrary_upload_dir') . DIRECTORY_SEPARATOR . 'thumbnail' . DIRECTORY_SEPARATOR . 'small_filename.jpg', 'getFullPath(\'small\') returns the complete small thumbnail path on the disk');
 $t->is($sfAsset->getFullPath('large'), sfConfig::get('sf_web_dir') . DIRECTORY_SEPARATOR . sfConfig::get('app_sfAssetsLibrary_upload_dir') . DIRECTORY_SEPARATOR . 'thumbnail' . DIRECTORY_SEPARATOR . 'large_filename.jpg', 'getFullPath(\'large\') returns the complete large thumbnail path on the disk');
 $t->diag('sfAsset::getUrl()');
 $t->is($sfAsset->getUrl(), '/' . sfConfig::get('app_sfAssetsLibrary_upload_dir') . DIRECTORY_SEPARATOR . 'filename.jpg', 'getUrl() returns the asset URL');
 $t->is($sfAsset->getUrl('small'), '/' . sfConfig::get('app_sfAssetsLibrary_upload_dir') . '/thumbnail/small_filename.jpg', 'getUrl(\'small\') returns the small thumbnail url');
 $t->is($sfAsset->getUrl('large'), '/' . sfConfig::get('app_sfAssetsLibrary_upload_dir') . '/thumbnail/large_filename.jpg', 'getUrl(\'large\') returns the large thumbnail url');
 $t->diag('sfAsset::create()');
 $assets_path = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR;
 $test_asset = $assets_path . 'raikkonen.jpg';
 $folder1 = new sfAssetFolder();
 $folder1->getNode()->insertAsFirstChildOf($root);
 $folder1->setName('Test_Directory');
 $folder1->save();
 $asset1 = new sfAsset();
 $asset1->setFolder($folder1);
 $asset1->create($test_asset, false);
 $asset_file_size = (int) (filesize($test_asset) / 1024);
 $t->is($asset1->getFilename(), 'raikkonen.jpg', 'create() sets the object filename according to the given asset');
 $t->is($asset1->getFilesize(), 18, 'create() sets the object filesize according to the given asset');
 $t->ok($asset1->isImage(), 'create() sets the object type according to the given asset');
 $t->is($asset1->getUrl(), $folder1->getUrl() . '/' . $asset1->getFilename(), 'create() sets the object url according to the given asset and folder object');
 $t->ok(is_file($asset1->getFullPath()), 'create() physically copies asset');
 $t->ok(is_file($asset1->getFullPath('large')), 'create() physically creates thumbnail');
 $t->diag('sfAsset::move()');
 $old_path = $asset1->getFullPath();
 $old_thumb_path = $asset1->getFullPath('large');
 /**
  * Move under a new parent
  *
  * @param sfAssetFolder $new_parent
  */
 public function move(sfAssetFolder $new_parent)
 {
     // controls
     if ($this->getNode()->isRoot()) {
         throw new sfAssetException('The root folder cannot be moved');
     } else {
         if ($new_parent->hasSubFolder($this->getName())) {
             throw new sfAssetException('The target folder "%folder%" already contains a folder named "%name%". The folder has not been moved.', array('%folder%' => $new_parent, '%name%' => $this->getName()));
         } else {
             if ($new_parent->getNode()->isDescendantOf($this)) {
                 throw new sfAssetException('The target folder cannot be a subfolder of moved folder. The folder has not been moved.');
             } else {
                 if ($this->getId() == $new_parent->getId()) {
                     return;
                 }
             }
         }
     }
     $old_path = $this->getFullPath();
     $this->getNode()->moveAsLastChildOf($new_parent);
     $this->save();
     $descendants = $this->getNode()->getChildren();
     $descendants = $descendants ? $descendants : array();
     // move its assets
     self::movePhysically($old_path, $this->getFullPath());
     foreach ($descendants as $descendant) {
         // Update relative path
         $descendant->save();
     }
     // else: nothing to do
 }
 $sfAssetFolder->setName('Test_Directory');
 $sfAssetFolder->getNode()->insertAsFirstChildOf($root);
 $sfAssetFolder->save();
 $t->is($sfAssetFolder->getName(), 'Test_Directory', 'getName() returns the folder name');
 $t->diag('sfAssetFolder::getRelativePath()');
 $t->is($sfAssetFolder->getRelativePath(), $root->getRelativePath() . '/' . $sfAssetFolder->getName(), 'getRelativePath() returns the folder relative path, including its own name');
 # $sfAssetFolder2 is /root/Test_Directory/Test_Sub-directory
 $sfAssetFolder2 = new sfAssetFolder();
 $sfAssetFolder2->setName('Test_Sub-directory');
 $sfAssetFolder2->getNode()->insertAsFirstChildOf($sfAssetFolder);
 $sfAssetFolder2->save();
 $t->is($sfAssetFolder2->getRelativePath(), $sfAssetFolder->getRelativePath() . '/' . $sfAssetFolder2->getName(), 'getRelativePath() returns the folder relative path, including its parent name');
 $id2 = $sfAssetFolder2->getId();
 # $sfAssetFolder3 is /root/Test_Directory/Test_Sub-directory/Test_Sub-sub-directory
 $sfAssetFolder3 = new sfAssetFolder();
 $sfAssetFolder3->getNode()->insertAsFirstChildOf($sfAssetFolder2);
 $sfAssetFolder3->setName('Test_Sub-sub-directory');
 $sfAssetFolder3->save();
 $t->is($sfAssetFolder3->getRelativePath(), $sfAssetFolder2->getRelativePath() . '/' . $sfAssetFolder3->getName(), 'getRelativePath() returns the folder relative path, including its ancestors names');
 $id3 = $sfAssetFolder3->getId();
 # $sfAsset is /root/Test_Directory/Test_Sub-directory/raikkonen.jpg
 $assets_path = dirname(__FILE__) . '/../assets/';
 $test_asset = $assets_path . 'raikkonen.jpg';
 $sfAsset = new sfAsset();
 $sfAsset->setFolder($sfAssetFolder2);
 $sfAsset->create($test_asset, false);
 $sfAsset->save();
 $sf_asset_id = $sfAsset->getId();
 # $sfAsset2 is /root/Test_Directory/Test_Sub-directory/Test_Sub-sub-directory/toto
 $sfAsset2 = new sfAsset();
 $sfAsset2->setFolder($sfAssetFolder3);
 /**
  * process search
  * @param  array    $params
  * @param  string   $sort
  * @return Doctrine_Query
  */
 protected function search(array $params, $sort = 'name')
 {
     $query = $this->createQuery('a');
     if (isset($params['folder_id']) && $params['folder_id'] !== '') {
         if (null != ($folder = sfAssetFolderTable::getInstance()->find($params['folder_id']))) {
             if (false) {
                 $folder = new sfAssetFolder();
             }
             $query->leftJoin('a.Folder f');
             $query->where('f.lft >= ?', $folder->getNode()->getLeftValue());
             $query->andWhere('f.rgt <= ?', $folder->getNode()->getRightValue());
         }
     }
     //    if (isset($params['filename']['is_empty']))
     //    {
     //      $query->andWhere('filename = \'\' or filename is null', null);
     ////      $criterion = $c->getNewCriterion(self::FILENAME, '');
     ////      $criterion->addOr($c->getNewCriterion(self::FILENAME, null, Criteria::ISNULL));
     ////      $c->add($criterion);
     //    }
     //    else
     if (isset($params['filename']['text']) && strlen($params['filename']['text'])) {
         $query->andWhere('filename like ?', '%' . trim($params['filename']['text'], '*%') . '%');
     }
     if (isset($params['author']['is_empty'])) {
         $query->andWhere('author = \'\' or author is null');
     } elseif (isset($params['author']['text']) && strlen($params['author']['text'])) {
         $query->andWhere('author like ?', '%' . trim($params['author']['text'], '*%') . '%');
     }
     if (isset($params['copyright']['is_empty'])) {
         $query->andWhere('copyright = \'\' or copyright is null');
     } elseif (isset($params['copyright']['text']) && strlen($params['copyright']['text'])) {
         $query->andWhere('copyright like ?', '%' . trim($params['copyright']['text'], '*%') . '%');
     }
     if (isset($params['created_at'])) {
         // TODO query
         //      if (isset($params['created_at']['from']) && $params['created_at']['from'] !== array())  // TODO check this
         //      {
         //        $criterion = $c->getNewCriterion(self::CREATED_AT, $params['created_at']['from'], Criteria::GREATER_EQUAL);
         //      }
         //      if (isset($params['created_at']['to']) && $params['created_at']['to'] !== array())  // TODO check this
         //      {
         //        if (isset($criterion))
         //        {
         //          $criterion->addAnd($c->getNewCriterion(self::CREATED_AT, $params['created_at']['to'], Criteria::LESS_EQUAL));
         //        }
         //        else
         //        {
         //          $criterion = $c->getNewCriterion(self::CREATED_AT, $params['created_at']['to'], Criteria::LESS_EQUAL);
         //        }
         //      }
         //      if (isset($criterion))
         //      {
         //        $c->add($criterion);
         //      }
     }
     if (isset($params['description']['is_empty'])) {
         $query->andWhere('description = \'\' or description is null');
     } else {
         if (isset($params['description']) && $params['description'] !== '') {
             $query->andWhere('description like ?', '%' . trim($params['description']['text'], '*%') . '%');
         }
     }
     switch ($sort) {
         case 'date':
             $query->orderBy('created_at DESC');
             break;
         default:
             $query->orderBy('filename ASC');
     }
     return $query;
 }