/** * Update data of the asset * * @param mixed $data * @return void */ function put($data) { $tmpFile = PIMCORE_WEBDAV_TEMP . "/" . md5($this->asset->getId() . microtime()); file_put_contents($tmpFile, $data); $data = file_get_contents($tmpFile); unlink($tmpFile); $this->asset->setData($data); $this->asset->save(); }
/** * @param Document|Asset|Object_Abstract $element * @return array */ public static function getDependencyForFrontend($element) { if ($element instanceof Document) { return array("id" => $element->getId(), "path" => $element->getFullPath(), "type" => "document", "subtype" => $element->getType()); } else { if ($element instanceof Asset) { return array("id" => $element->getId(), "path" => $element->getFullPath(), "type" => "asset", "subtype" => $element->getType()); } else { if ($element instanceof Object_Abstract) { return array("id" => $element->getId(), "path" => $element->getFullPath(), "type" => "object", "subtype" => $element->geto_Type()); } } } }
/** * @see Object\ClassDefinition\Data::getDataForResource * @param Asset $data * @param null|Model\Object\AbstractObject $object * @return integer|null */ public function getDataForResource($data, $object = null) { if ($data instanceof PriceRule) { return $data->getId(); } return null; }
/** * @param Asset $target * @param Asset $source * @return Asset copied asset */ public function copyRecursive($target, $source) { // avoid recursion if (!$this->_copyRecursiveIds) { $this->_copyRecursiveIds = array(); } if (in_array($source->getId(), $this->_copyRecursiveIds)) { return; } $source->getProperties(); if (!$source instanceof Asset_Folder) { $source->getData(); } $new = clone $source; $new->id = null; if ($new instanceof Asset_Folder) { $new->setChilds(null); } $new->setFilename(Element_Service::getSaveCopyName("asset", $new->getFilename(), $target)); $new->setParentId($target->getId()); $new->setUserOwner($this->_user->getId()); $new->setUserModification($this->_user->getId()); $new->setResource(null); $new->setLocked(false); $new->save(); // add to store $this->_copyRecursiveIds[] = $new->getId(); foreach ($source->getChilds() as $child) { $this->copyRecursive($new, $child); } if ($target instanceof Asset_Folder) { $this->updateChilds($target, $new); } return $new; }
/** * Answer a list of parameters to pass through urls * * @return array * @access public * @since 10/16/07 */ public static function getUrlParams(Asset $asset) { $repository = $asset->getRepository(); $params = array("collection_id" => $repository->getId()->getIdString(), "asset_id" => $asset->getId()->getIdString(), RequestContext::name("starting_number") => RequestContext::value("starting_number"), RequestContext::name("limit_by_type") => RequestContext::value("limit_by_type"), RequestContext::name("order") => RequestContext::value("order"), RequestContext::name("direction") => RequestContext::value("direction"), RequestContext::name("type") => RequestContext::value("type"), RequestContext::name("searchtype") => RequestContext::value("searchtype")); if (RequestContext::value("searchtype")) { $searchModuleManager = Services::getService("RepositorySearchModules"); foreach ($searchModuleManager->getCurrentValues(HarmoniType::fromString(RequestContext::value("searchtype"))) as $key => $value) { $params[$key] = $value; } } // if we are limiting by type if (RequestContext::value("limit_by_type") == 'true') { $types = $repository->getAssetTypes(); $selectedTypes = array(); while ($types->hasNext()) { $type = $types->next(); if (RequestContext::value("type___" . $type->asString()) == 'true') { $params[RequestContext::name("type___" . $type->asString())] = RequestContext::value("type___" . $type->asString()); } } } return $params; }
/** * Static helper to get an asset by the passed path (returned is not the concrete asset like Asset_Folder!) * * @param string $path * @return Asset */ public static function getByPath($path) { $path = Element_Service::correctPath($path); try { $asset = new Asset(); if (Pimcore_Tool::isValidPath($path)) { $asset->getResource()->getByPath($path); return self::getById($asset->getId()); } } catch (Exception $e) { Logger::warning($e); } return null; }
/** * @see Object_Class_Data::getDataForQueryResource * @param Asset $data * @param null|Object_Abstract $object * @return integer|null */ public function getDataForQueryResource($data, $object = null) { if ($data instanceof Asset) { return $data->getId(); } return null; }
/** * * Checks if an asset is an allowed relation * @param Asset $asset * @return boolean */ protected function allowAssetRelation($asset) { $allowedAssetTypes = $this->getAssetTypes(); $allowed = true; if (!$this->getAssetsAllowed()) { $allowed = false; } else { if ($this->getAssetsAllowed() and is_array($allowedAssetTypes) and count($allowedAssetTypes) > 0) { //check for allowed asset types foreach ($allowedAssetTypes as $t) { if (is_array($t) && array_key_exists("assetTypes", $t)) { $t = $t["assetTypes"]; } if ($t && is_string($t)) { $allowedTypes[] = $t; } } if (!in_array($asset->getType(), $allowedTypes)) { $allowed = false; } } else { //don't check if no allowed asset types set } } \Logger::debug("checked object relation to target asset [" . $asset->getId() . "] in field [" . $this->getName() . "], allowed:" . $allowed); return $allowed; }
/** * Create and/or return the component for an asset and register it for later fetching * * @param object Asset $asset * @return object SiteComponent * @access public * @since 4/5/06 */ function getSiteComponentFromAsset(Asset $asset) { $id = $asset->getId(); $idString = $id->getIdString(); if (!isset($this->_createdSiteComponents[$idString])) { $type = $asset->getAssetType(); foreach ($this->siteDisplayTypes as $siteDisplayType) { if ($type->isEqual($siteDisplayType)) { $typeKey = ucfirst($type->getKeyword()); break; } } if (!isset($typeKey)) { $typeKey = 'Block'; } $class = "Asset" . $typeKey . "SiteComponent"; try { $xmlDocument = $this->getXmlDocumentFromAsset($asset); $documentElement = $xmlDocument->documentElement; } catch (NonNavException $e) { $documentElement = null; } $this->_createdSiteComponents[$idString] = new $class($this, $asset, $documentElement); } return $this->_createdSiteComponents[$idString]; }
/** * Answer all media assets below the specified asset * * @param object Asset $asset * @param optional object Id $excludeId * @return object Iterator * @access protected * @since 2/26/07 */ protected function getAllMediaAssets(Asset $asset, $excludeId = null) { if ($excludeId && $excludeId->isEqual($asset->getId())) { return false; } if ($this->mediaFileType->isEqual($asset->getAssetType())) { $tmp = array(); $tmp[] = $asset; $iterator = new HarmoniIterator($tmp); return $iterator; } else { $iterator = new MultiIteratorIterator(); $children = $asset->getAssets(); while ($children->hasNext()) { $result = $this->getAllMediaAssets($children->next(), $excludeId); if ($result) { $iterator->addIterator($result); } } return $iterator; } }
/** * Answer true if this site should be included * * @param object Asset $asset * @return boolean * @access protected * @since 4/1/08 */ protected function includeSite(Asset $asset) { $matches = false; if ($this->match($asset->getDisplayName())) { $matches = true; } else { if ($this->match($asset->getDescription())) { $matches = true; } } if (!$matches) { $slotMgr = SlotManager::instance(); try { $slot = $slotMgr->getSlotBySiteId($asset->getId()); } catch (UnknownIdException $e) { } if (isset($slot) && $this->match($slot->getShortname())) { $matches = true; } } if (!$matches) { return false; } $authZ = Services::getService("AuthZ"); $idManager = Services::getService("Id"); // Since View AZs now cascade up, we don't need to check isAuthorizedBelow() if ($authZ->isUserAuthorized($idManager->getId("edu.middlebury.authorization.view"), $asset->getId())) { return TRUE; } else { return FALSE; } }
/** * * * @param <##> * @return <##> * @access public * @since 1/18/06 */ public function printSiteShort(Asset $asset, $action, $num, Slot $otherSlot = null) { $harmoni = Harmoni::instance(); $assetId = $asset->getId(); $authZ = Services::getService('AuthZ'); $idMgr = Services::getService('Id'); if (!$authZ->isUserAuthorized($idMgr->getId('edu.middlebury.authorization.view'), $assetId) && !$otherSlot->isUserOwner()) { return new UnstyledBlock('', BLANK); } $container = new Container(new YLayout(), BLOCK, STANDARD_BLOCK); $fillContainerSC = new StyleCollection("*.fillcontainer", "fillcontainer", "Fill Container", "Elements with this style will fill their container."); $fillContainerSC->addSP(new MinHeightSP("88%")); // $fillContainerSC->addSP(new WidthSP("100%")); // $fillContainerSC->addSP(new BorderSP("3px", "solid", "#F00")); $container->addStyle($fillContainerSC); $centered = new StyleCollection("*.centered", "centered", "Centered", "Centered Text"); $centered->addSP(new TextAlignSP("center")); // Use the alias instead of the Id if it is available. $viewUrl = SiteDispatcher::getSitesUrlForSiteId($assetId->getIdString()); $slotManager = SlotManager::instance(); try { $sitesTrueSlot = $slotManager->getSlotBySiteId($assetId); } catch (Exception $e) { } // Print out the content ob_start(); print "\n\t<div class='portal_list_slotname'>"; if (isset($sitesTrueSlot)) { if (is_null($otherSlot) || $sitesTrueSlot->getShortname() == $otherSlot->getShortname()) { print $sitesTrueSlot->getShortname(); } else { print $otherSlot->getShortname(); $targets = array(); $target = $otherSlot->getAliasTarget(); while ($target) { $targets[] = $target->getShortname(); if ($target->isAlias()) { $target = $target->getAliasTarget(); } else { $target = null; } } print "\n<br/>"; print str_replace('%1', implode(' » ', $targets), _("(an alias of %1)")); // Add Alias info. // if ($otherSlot->isAlias()) { // ob_start(); // // print _("This slot is an alias of ").$slot->getAliasTarget()->getShortname(); // // $container->add(new UnstyledBlock(ob_get_clean()), "100%", null, LEFT, TOP); // } } } else { print _("ID#") . ": " . $assetId->getIdString(); } print "\n\t</div>"; print "\n\t<div class='portal_list_site_title'>"; if ($authZ->isUserAuthorized($idMgr->getId('edu.middlebury.authorization.view'), $assetId)) { print "\n\t\t<a href='" . $viewUrl . "'>"; print "\n\t\t\t<strong>" . HtmlString::getSafeHtml($asset->getDisplayName()) . "</strong>"; print "\n\t\t</a>"; print "\n\t\t<br/>"; print "\n\t\t<a href='" . $viewUrl . "' style='font-size: smaller;'>"; print "\n\t\t\t" . $viewUrl; print "\n\t\t</a>"; } print "\n\t</div>"; print "\n\t<div class='portal_list_controls'>\n\t\t"; $controls = array(); if ($authZ->isUserAuthorized($idMgr->getId('edu.middlebury.authorization.view'), $assetId)) { $controls[] = "<a href='" . $viewUrl . "'>" . _("view") . "</a>"; } // Hide all edit links if not authenticated to prevent web spiders from traversing them if ($this->isAuthenticated) { // While it is more correct to check modify permission permission, doing // so forces us to check AZs on the entire site until finding a node with // authorization or running out of nodes to check. Since edit-mode actions // devolve into view-mode if no authorization is had by the user, just // show the links all the time to cut page loads from 4-6 seconds to // less than 1 second. if ($authZ->isUserAuthorized($idMgr->getId('edu.middlebury.authorization.view'), $assetId)) { $controls[] = "<a href='" . SiteDispatcher::quickURL($action->getUiModule(), 'editview', array('node' => $assetId->getIdString())) . "'>" . _("edit") . "</a>"; } // if ($action->getUiModule() == 'ui2') { // $controls[] = "<a href='".SiteDispatcher::quickURL($action->getUiModule(), 'arrangeview', array('node' => $assetId->getIdString()))."'>"._("arrange")."</a>"; // } // add link to tracking if ($authZ->isUserAuthorized($idMgr->getId('edu.middlebury.authorization.view'), $assetId)) { $trackUrl = $harmoni->request->quickURL("participation", "actions", array('node' => $assetId->getIdString())); ob_start(); print " <a target='_blank' href='" . $trackUrl . "'"; print ' onclick="'; print "var url = '" . $trackUrl . "'; "; print "window.open(url, 'site_map', 'width=600,height=600,resizable=yes,scrollbars=yes'); "; print "return false;"; print '"'; print ">" . _("track") . "</a>"; $controls[] = ob_get_clean(); } if (!is_null($otherSlot) && $otherSlot->isAlias() && $otherSlot->isUserOwner()) { $controls[] = "<a href='" . $harmoni->request->quickURL('slots', 'remove_alias', array('slot' => $otherSlot->getShortname())) . "' onclick=\"if (!confirm('" . str_replace("%1", $otherSlot->getShortname(), str_replace("%2", $otherSlot->getAliasTarget()->getShortname(), _("Are you sure that you want \\'%1\\' to no longer be an alias of \\'%2\\'?"))) . "')) { return false; }\">" . _("remove alias") . "</a>"; } else { if ($authZ->isUserAuthorized($idMgr->getId('edu.middlebury.authorization.delete'), $assetId)) { $controls[] = "<a href='" . $harmoni->request->quickURL($action->getUiModule(), 'deleteComponent', array('node' => $assetId->getIdString())) . "' onclick=\"if (!confirm('" . _("Are you sure that you want to permenantly delete this site?") . "')) { return false; }\">" . _("delete") . "</a>"; } } // Add a control to select this site for copying. This should probably // have its own authorization, but we'll use add_children/modify for now. if ($authZ->isUserAuthorized($idMgr->getId('edu.middlebury.authorization.modify'), $assetId)) { if (isset($sitesTrueSlot) && (is_null($otherSlot) || $sitesTrueSlot->getShortname() == $otherSlot->getShortname())) { $controls[] = Segue_Selection::instance()->getAddLink(SiteDispatcher::getSiteDirector()->getSiteComponentFromAsset($asset)); } } } print implode("\n\t\t | ", $controls); print "\n\t</div>"; if ($authZ->isUserAuthorized($idMgr->getId('edu.middlebury.authorization.view'), $assetId)) { $description = HtmlString::withValue($asset->getDescription()); $description->trim(25); print "\n\t<div class='portal_list_site_description'>" . $description->asString() . "</div>"; } print "\n\t<div style='clear: both;'></div>"; print $this->getExportControls($assetId, $otherSlot, $sitesTrueSlot); $component = new UnstyledBlock(ob_get_clean()); $container->add($component, "100%", null, LEFT, TOP); return $container; }
/** * Record any extra files that are used by plugins * * @param Asset $asset * @return void */ public function recordPluginExtras(Asset $asset) { $audioType = new Type('SeguePlugins', 'edu.middlebury', 'AudioPlayer'); $downloadType = new Type('SeguePlugins', 'edu.middlebury', 'Download'); if ($asset->getAssetType()->isEqual($audioType) || $asset->getAssetType()->isEqual($downloadType)) { $query = 'count(item[wp:post_type = "attachment" and title = "downarrow.gif"])'; if (!$this->xpath->evaluate($query, $this->channel)) { $url = MYPATH . '/images/downarrow.gif'; $element = $this->channel->insertBefore($this->doc->createElement('item'), $this->endFiles); $element->appendChild($this->getElement('title', "downarrow.gif")); $element->appendChild($this->getElement('link', $url)); $element->appendChild($this->getElement('guid', $url))->setAttribute('isPermaLink', 'false'); $element->appendChild($this->getElement('description', 'Download icon.')); $element->appendChild($this->getElement('pubDate', date('r'))); $agentUID = $this->recordAgent($asset->getCreator()); $element->appendChild($this->getElementNS("http://purl.org/dc/elements/1.1/", 'dc:creator', '0')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:post_id', '0')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:post_date', date('Y-m-d H:i:s'))); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:post_date_gmt', date('Y-m-d H:i:s'))); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:comment_status', 'closed')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:ping_status', 'closed')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:status', 'publish')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:post_parent', $asset->getId()->getIdString())); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:menu_order', '0')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:post_type', 'attachment')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:post_password', '')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:is_sticky', '0')); $element->appendChild($this->getElementNS("http://wordpress.org/export/1.1/", 'wp:attachment_url', $url)); } } }
/** * Function for printing the asset block of the slideshow XML file * * @param object Asset $asset * @param optional object Id $recordId * @return void * @access public * @since 10/14/05 */ function printAssetXML(Asset $asset, Id $recordId = null) { $assetId = $asset->getId(); $repository = $asset->getRepository(); $repositoryId = $repository->getId(); $idManager = Services::getService("Id"); // ------------------------------------------ print "\t<slide>\n"; // Title print "\t\t<title><![CDATA["; print htmlspecialchars($asset->getDisplayName(), ENT_COMPAT, 'UTF-8'); print "]]></title>\n"; // Caption print "\t\t<caption><![CDATA["; $this->printAsset($asset); print "]]></caption>\n"; // Text-Position print "\t\t<text-position>"; print "right"; print "</text-position>\n"; $fileRecords = new MultiIteratorIterator(); $fileRecords->addIterator($asset->getRecordsByRecordStructure($idManager->getId("FILE"))); $fileRecords->addIterator($asset->getRecordsByRecordStructure($idManager->getId("REMOTE_FILE"))); /********************************************************* * Files *********************************************************/ $harmoni = Harmoni::instance(); $harmoni->request->startNamespace("polyphony-repository"); $imgProcessor = Services::getService("ImageProcessor"); while ($fileRecords->hasNext()) { $this->printFileRecord($fileRecords->next(), $repositoryId, $assetId); } $harmoni->request->endNamespace(); print "\t</slide>\n"; }
/** * @param Asset $asset */ public function addAsset(Asset $asset) { $this->assets[$asset->getId()] = $asset; }
/** * @see Object_Class_Data::getDataForEditmode * @param Asset|Document|Object_Abstract $data * @param null|Object_Abstract $object * @return array */ public function getDataForEditmode($data, $object = null) { if ($data) { $r = array("id" => $data->getId(), "path" => $data->getFullPath()); if ($data instanceof Document) { $r["subtype"] = $data->getType(); $r["type"] = "document"; } else { if ($data instanceof Asset) { $r["subtype"] = $data->getType(); $r["type"] = "asset"; } else { if ($data instanceof Object_Abstract) { $r["subtype"] = $data->getO_Type(); $r["type"] = "object"; } } } return $r; } return; }
/** * Static helper to get an asset by the passed path (returned is not the concrete asset like Asset_Folder!) * * @param string $path * @return Asset */ public static function getByPath($path) { // remove trailing slash if ($path != "/") { $path = rtrim($path, "/ "); } // correct wrong path (root-node problem) $path = str_replace("//", "/", $path); try { $asset = new Asset(); if (Pimcore_Tool::isValidPath($path)) { $asset->getResource()->getByPath($path); return self::getById($asset->getId()); } } catch (Exception $e) { Logger::warning($e); } return null; }
/** * @param Asset $asset * @return string */ protected static function createAssetComparisonString($asset, $ignoreCopyDifferences = false) { if ($asset instanceof Asset) { $a = array(); //custom settings if (is_array($asset->getCustomSettings())) { $a["customSettings"] = serialize($asset->getCustomSettings()); } if ($asset->getData()) { $a["data"] = base64_encode($asset->getData()); } if (!$ignoreCopyDifferences) { $a["filename"] = $asset->getFilename(); $a["id"] = $asset->getId(); $a["modification"] = $asset->getModificationDate(); $a["creation"] = $asset->getCreationDate(); $a["userModified"] = $asset->getUserModification(); $a["parentId"] = $asset->getParentId(); $a["path"] = $asset->getPath; } $a["userOwner"] = $asset->getUserOwner(); $properties = $asset->getProperties(); $a = array_merge($a, self::createPropertiesComparisonString($properties)); return implode(",", $a); } else { return null; } }
/** * @param Asset $asset * @return array|string */ protected function getTreeNodeConfig($asset) { $tmpAsset = array("id" => $asset->getId(), "text" => $asset->getFilename(), "type" => $asset->getType(), "path" => $asset->getFullPath(), "basePath" => $asset->getPath(), "locked" => $asset->isLocked(), "lockOwner" => $asset->getLocked() ? true : false, "elementType" => "asset", "permissions" => array("remove" => $asset->isAllowed("delete"), "settings" => $asset->isAllowed("settings"), "rename" => $asset->isAllowed("rename"), "publish" => $asset->isAllowed("publish"), "view" => $asset->isAllowed("view"))); // set type specific settings if ($asset->getType() == "folder") { $tmpAsset["leaf"] = false; $tmpAsset["expanded"] = $asset->hasNoChilds(); $tmpAsset["iconCls"] = "pimcore_icon_folder"; $tmpAsset["permissions"]["create"] = $asset->isAllowed("create"); } else { $tmpAsset["leaf"] = true; $tmpAsset["iconCls"] = "pimcore_icon_" . Pimcore_File::getFileExtension($asset->getFilename()); } $tmpAsset["qtipCfg"] = array("title" => "ID: " . $asset->getId()); if ($asset->getType() == "image") { try { $tmpAsset["qtipCfg"] = array("title" => "ID: " . $asset->getId(), "text" => '<img src="/admin/asset/get-image-thumbnail/id/' . $asset->getId() . '/width/130/aspectratio/true" width="130" />', "width" => 140); // this is for backward-compatibilty, to calculate the dimensions if they are not there if (!$asset->getCustomSetting("imageDimensionsCalculated")) { $asset->save(); } if ($asset->getCustomSetting("imageWidth") && $asset->getCustomSetting("imageHeight")) { $tmpAsset["imageWidth"] = $asset->getCustomSetting("imageWidth"); $tmpAsset["imageHeight"] = $asset->getCustomSetting("imageHeight"); } } catch (Exception $e) { Logger::debug("Cannot get dimensions of image, seems to be broken."); } } else { if ($asset->getType() == "video") { try { if (Pimcore_Video::isAvailable()) { $tmpAsset["qtipCfg"] = array("title" => "ID: " . $asset->getId(), "text" => '<img src="/admin/asset/get-video-thumbnail/id/' . $asset->getId() . '/width/130/aspectratio/true" width="130" />', "width" => 140); } } catch (Exception $e) { Logger::debug("Cannot get dimensions of video, seems to be broken."); } } } $tmpAsset["cls"] = ""; if ($asset->isLocked()) { $tmpAsset["cls"] .= "pimcore_treenode_locked "; } if ($asset->getLocked()) { $tmpAsset["cls"] .= "pimcore_treenode_lockOwner "; } return $tmpAsset; }
/** * Function for printing the asset block of the slideshow XML file * * @param object Asset $asset * @param optional object Id $recordId * @return void * @access public * @since 10/14/05 */ function printAssetXML(Asset $asset, Id $recordId = null) { $harmoni = Harmoni::instance(); $assetId = $asset->getId(); $repository = $asset->getRepository(); $repositoryId = $repository->getId(); $idManager = Services::getService("Id"); // ------------------------------------------ print "\t<slide>\n"; // Title print "\t\t<title><![CDATA["; // print htmlspecialchars($asset->getDisplayName(), ENT_COMPAT, 'UTF-8'); print "]]></title>\n"; // Caption print "\t\t<caption><![CDATA["; // $this->printAsset($asset); print "]]></caption>\n"; // Text-Position print "\t\t<text-position>"; print "none"; print "</text-position>\n"; $fileRecords = $asset->getRecordsByRecordStructure($idManager->getId("FILE")); /********************************************************* * Files *********************************************************/ while ($fileRecords->hasNext()) { $fileRecord = $fileRecords->next(); $fileRecordId = $fileRecord->getId(); if ($fileRecordId->isEqual($recordId)) { $this->printFileRecord($fileRecord, $repositoryId, $assetId); } } print "\t</slide>\n"; }
/** * creates a new folder in current directory * * @param string $name * @return string */ function createDirectory($name) { $asset = Asset::create($this->asset->getId(), array("filename" => Pimcore_File::getValidFilename($name), "type" => "folder")); }