Source for file HarmoniRepository.class.php

Documentation is available at HarmoniRepository.class.php

  1. <?php
  2.  
  3. require_once(HARMONI."/oki2/repository/HarmoniRepository.interface.php");
  4. require_once(HARMONI."/oki2/repository/HarmoniAsset.class.php");
  5. require_once(HARMONI."/oki2/repository/HarmoniAssetIterator.class.php");
  6. require_once(HARMONI."/oki2/repository/HarmoniRepositoryIterator.class.php");
  7. require_once(HARMONI."/oki2/repository/HarmoniRecordStructure.class.php");
  8.  
  9. require_once(HARMONI."/oki2/repository/File/FileRecord.class.php");
  10. require_once(HARMONI."/oki2/repository/File/FileSystemFileRecord.class.php");
  11. require_once(HARMONI."/oki2/repository/File/FileRecordStructure.class.php");
  12. require_once(HARMONI."/oki2/repository/File/RemoteFileRecord.class.php");
  13. require_once(HARMONI."/oki2/repository/File/RemoteFileRecordStructure.class.php");
  14.  
  15. require_once(HARMONI."/oki2/repository/HarmoniRecordStructureIterator.class.php");//where is this now?
  16. require_once(HARMONI."/oki2/shared/HarmoniTypeIterator.class.php");
  17. //require_once(HARMONI."/oki2/shared/HarmoniCalendarIterator.class.php");
  18. // Search Modules
  19.  
  20. require_once(dirname(__FILE__)."/SearchModules/KeywordSearch.class.php");
  21. require_once(dirname(__FILE__)."/SearchModules/AssetTypeSearch.class.php");
  22. require_once(dirname(__FILE__)."/SearchModules/ContentSearch.class.php");
  23. require_once(dirname(__FILE__)."/SearchModules/DescriptionSearch.class.php");
  24. require_once(dirname(__FILE__)."/SearchModules/DisplayNameSearch.class.php");
  25. require_once(dirname(__FILE__)."/SearchModules/RootAssetSearch.class.php");
  26. require_once(dirname(__FILE__)."/SearchModules/AuthoritativeValuesSearch.class.php");
  27.  
  28. /**
  29. * Repository manages Assets of various Types and information about the Assets.
  30. * Assets are created, persisted, and validated by the Repository. When
  31. * initially created, an Asset has an immutable Type and unique Id and its
  32. * validation status is false. In this state, all methods can be called, but
  33. * integrity checks are not enforced. When the Asset and its Records are
  34. * ready to be validated, the validateAsset method checks the Asset and sets
  35. * the validation status. When working with a valid Asset, all methods
  36. * include integrity checks and an exception is thrown if the activity would
  37. * result in an inappropriate state. Optionally, the invalidateAsset method
  38. * can be called to release the requirement for integrity checks, but the
  39. * Asset will not become valid again, until validateAsset is called and the
  40. * entire Asset is checked.
  41. *
  42. * <p>
  43. * OSID Version: 2.0
  44. * </p>
  45. *
  46. * @package harmoni.osid_v2.repository
  47. *
  48. * @copyright Copyright &copy;2005, Middlebury College
  49. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
  50. *
  51. * @version $Id: HarmoniRepository.class.php,v 1.62 2007/09/04 20:25:43 adamfranco Exp $
  52. */
  53.  
  54. class HarmoniRepository
  55. extends HarmoniRepositoryInterface
  56. {
  57. var $_configuration;
  58. var $_searchTypes;
  59. var $_node;
  60. var $_type;
  61. var $_hierarchy;
  62. var $_createdAssets;
  63. var $_createdRecordStructures;
  64. var $_assetValidFlags;
  65. /**
  66. * Constructor
  67. */
  68. function HarmoniRepository ($hierarchy, $id, $configuration) {
  69. // Get the node coresponding to our id
  70. $this->_hierarchy =$hierarchy;
  71. $this->_node =$this->_hierarchy->getNode($id);
  72. // Cache any created Assets so that we can pass out references to them.
  73. $this->_createdAssets = array();
  74. $this->_assetValidFlags = array();
  75. // $this->_assetDataSets = array();
  76. // Set up an array of searchTypes that this DR supports
  77. $this->_registerSearchTypes();
  78. // Define the type to use as a key for Identifying DRs
  79. $this->_repositoryKeyType = new HarmoniType("Repository", "edu.middlebury.harmoni",
  80. "Repository", "Nodes with this type are by definition Repositories.");
  81. // Set up an array of created RecordStructures so we can pass out references to them.
  82. $this->_createdRecordStructures = array();
  83. // Add the file RecordStructure to the DR
  84. $this->_createdRecordStructures['FILE'] = new HarmoniFileRecordStructure;
  85. $this->_createdRecordStructures['REMOTE_FILE'] = new RemoteFileRecordStructure;
  86. // Built-in Types
  87. // Keys of the array are the RecordStructure Ids,
  88. // Vals of the array are the record class-names to instantiate.
  89. $this->_builtInTypes = array();
  90. if ($configuration->getProperty('use_filesystem_for_files'))
  91. $this->_builtInTypes['FILE'] = 'FileSystemFileRecord';
  92. else
  93. $this->_builtInTypes['FILE'] = 'FileRecord';
  94. $this->_builtInTypes['REMOTE_FILE'] = 'RemoteFileRecord';
  95. // Store our configuration
  96. $this->_configuration =$configuration;
  97. }
  98. /**
  99. * Returns if this Asset is valid or not.
  100. *
  101. * WARNING: NOT IN OSID - Method no longer in OSID
  102. *
  103. * @param object assetId
  104. * @return bool
  105. */
  106. function isAssetValid($assetId) {
  107. throw(new Error("Method gone from OSID","Repository",TRUE));
  108. return $this->_assetValidFlags[$assetId->getIdString()];
  109. }
  110.  
  111. /**
  112. * Update the display name for this Repository.
  113. *
  114. * @param string $displayName
  115. *
  116. * @throws object RepositoryException An exception with one of
  117. * the following messages defined in
  118. * org.osid.repository.RepositoryException may be thrown: {@link }
  119. * org.osid.repository.RepositoryException#OPERATION_FAILED
  120. * OPERATION_FAILED}, {@link }
  121. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  122. * PERMISSION_DENIED}, {@link }
  123. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  124. * CONFIGURATION_ERROR}, {@link }
  125. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  126. * UNIMPLEMENTED}, {@link }
  127. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  128. * NULL_ARGUMENT}
  129. *
  130. * @access public
  131. */
  132. function updateDisplayName ( $displayName ) {
  133. $this->_node->updateDisplayName($displayName);
  134. }
  135. /**
  136. * Get the display name for this Repository.
  137. *
  138. * @return string
  139. *
  140. * @throws object RepositoryException An exception with one of
  141. * the following messages defined in
  142. * org.osid.repository.RepositoryException may be thrown: {@link }
  143. * org.osid.repository.RepositoryException#OPERATION_FAILED
  144. * OPERATION_FAILED}, {@link }
  145. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  146. * PERMISSION_DENIED}, {@link }
  147. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  148. * CONFIGURATION_ERROR}, {@link }
  149. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  150. * UNIMPLEMENTED}
  151. *
  152. * @access public
  153. */
  154. function getDisplayName () {
  155. return $this->_node->getDisplayName();
  156. }
  157. /**
  158. * Get the unique Id for this Repository.
  159. *
  160. * @return object Id
  161. *
  162. * @throws object RepositoryException An exception with one of
  163. * the following messages defined in
  164. * org.osid.repository.RepositoryException may be thrown: {@link }
  165. * org.osid.repository.RepositoryException#OPERATION_FAILED
  166. * OPERATION_FAILED}, {@link }
  167. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  168. * PERMISSION_DENIED}, {@link }
  169. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  170. * CONFIGURATION_ERROR}, {@link }
  171. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  172. * UNIMPLEMENTED}
  173. *
  174. * @access public
  175. */
  176. function getId() {
  177. return $this->_node->getId();
  178. }
  179.  
  180. /**
  181. * Get the RepositoryType of this Repository.
  182. *
  183. * @return object Type
  184. *
  185. * @throws object RepositoryException An exception with one of
  186. * the following messages defined in
  187. * org.osid.repository.RepositoryException may be thrown: {@link }
  188. * org.osid.repository.RepositoryException#OPERATION_FAILED
  189. * OPERATION_FAILED}, {@link }
  190. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  191. * PERMISSION_DENIED}, {@link }
  192. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  193. * CONFIGURATION_ERROR}, {@link }
  194. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  195. * UNIMPLEMENTED}
  196. *
  197. * @access public
  198. */
  199. function getType () {
  200. // If we don't have it cached, get our type.
  201. if (!$this->_type) {
  202. $myId =$this->getId();
  203. $query = new SelectQuery;
  204. $query->addColumn("type_domain");
  205. $query->addColumn("type_authority");
  206. $query->addColumn("type_keyword");
  207. $query->addColumn("type_description");
  208. $query->addTable("dr_repository_type");
  209. $query->addTable("dr_type", INNER_JOIN, "fk_dr_type = type_id");
  210. $query->addWhere("repository_id = '".addslashes($myId->getIdString())."'");
  211. $dbc = Services::getService("DatabaseManager");
  212. $result =$dbc->query($query, $this->_configuration->getProperty('database_index'));
  213. // Return our type
  214. if ($result->getNumberOfRows()) {
  215. $this->_type = new HarmoniType($result->field("type_domain"),
  216. $result->field("type_authority"),
  217. $result->field("type_keyword"),
  218. $result->field("type_description"));
  219. $result->free();
  220. }
  221. // Otherwise, throw an error
  222. else {
  223. $result->free();
  224. throwError(new Error(RepositoryException::OPERATION_FAILED(), "Repository", 1));
  225. }
  226. }
  227. return $this->_type;
  228. }
  229.  
  230. /** NOT IN OSID???
  231. * Get the description for this Repository.
  232. * @return String the name
  233. * @throws osid.dr.DigitalRepositoryException An exception with one of the following messages defined in osid.dr.DigitalRepositoryException may be thrown: {@link DigitalRepositoryException#OPERATION_FAILED OPERATION_FAILED}, {@link DigitalRepositoryException#PERMISSION_DENIED PERMISSION_DENIED}, {@link DigitalRepositoryException#CONFIGURATION_ERROR CONFIGURATION_ERROR}, {@link DigitalRepositoryException#UNIMPLEMENTED UNIMPLEMENTED}
  234. */
  235. function getDescription() {
  236. return $this->_node->getDescription();
  237. }
  238.  
  239. /**
  240. * Update the description for this Repository.
  241. *
  242. * @param string $description
  243. *
  244. * @throws object RepositoryException An exception with one of
  245. * the following messages defined in
  246. * org.osid.repository.RepositoryException may be thrown: {@link }
  247. * org.osid.repository.RepositoryException#OPERATION_FAILED
  248. * OPERATION_FAILED}, {@link }
  249. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  250. * PERMISSION_DENIED}, {@link }
  251. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  252. * CONFIGURATION_ERROR}, {@link }
  253. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  254. * UNIMPLEMENTED}, {@link }
  255. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  256. * NULL_ARGUMENT}
  257. *
  258. * @access public
  259. */
  260. function updateDescription ( $description ) {
  261. $this->_node->updateDescription($description);
  262. }
  263.  
  264. /**
  265. * Create a new Asset of this AssetType in this Repository. The
  266. * implementation of this method sets the Id for the new object.
  267. *
  268. * @param string $displayName
  269. * @param string $description
  270. * @param object Type $assetType
  271. *
  272. * @return object Asset
  273. *
  274. * @throws object RepositoryException An exception with one of
  275. * the following messages defined in
  276. * org.osid.repository.RepositoryException may be thrown: {@link }
  277. * org.osid.repository.RepositoryException#OPERATION_FAILED
  278. * OPERATION_FAILED}, {@link }
  279. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  280. * PERMISSION_DENIED}, {@link }
  281. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  282. * CONFIGURATION_ERROR}, {@link }
  283. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  284. * UNIMPLEMENTED}, {@link }
  285. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  286. * NULL_ARGUMENT}, {@link }
  287. * org.osid.repository.RepositoryException#UNKNOWN_TYPE
  288. * UNKNOWN_TYPE}
  289. *
  290. * @access public
  291. */
  292. function createAsset ( $displayName, $description, $assetType, $id = NULL ) {
  293. // Get our id for the parent id
  294. $repositoryId =$this->_node->getId();
  295. // Create an Id for the new Asset
  296. if (!is_object($id)) {
  297. $IDManager = Services::getService("Id");
  298. $id =$IDManager->createId();
  299. }
  300. // verify that this type exists or add it if needed.
  301. if (isset($this->_assetTypes)) {
  302. $typeExists = false;
  303. foreach(array_keys($this->_assetTypes) as $key) {
  304. if ($assetType->isEqual($this->_assetTypes[$key])) {
  305. $typeExists = true;
  306. break;
  307. }
  308. }
  309. if (!$typeExists)
  310. $this->_assetTypes[] =$assetType;
  311. }
  312. // Add this DR's root node to the hierarchy.
  313. $node =$this->_hierarchy->createNode($id, $repositoryId, $assetType, $displayName, $description);
  314. // Create the asset with its new ID and cache it.
  315. $this->_createdAssets[$id->getIdString()] = new HarmoniAsset($this->_hierarchy, $this, $id, $this->_configuration);
  316. $this->_createdAssets[$id->getIdString()]->updateModificationDate();
  317. return $this->_createdAssets[$id->getIdString()];
  318. }
  319.  
  320. /**
  321. * Delete an Asset from this Repository.
  322. *
  323. * @param object Id $assetId
  324. *
  325. * @throws object RepositoryException An exception with one of
  326. * the following messages defined in
  327. * org.osid.repository.RepositoryException may be thrown: {@link }
  328. * org.osid.repository.RepositoryException#OPERATION_FAILED
  329. * OPERATION_FAILED}, {@link }
  330. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  331. * PERMISSION_DENIED}, {@link }
  332. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  333. * CONFIGURATION_ERROR}, {@link }
  334. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  335. * UNIMPLEMENTED}, {@link }
  336. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  337. * NULL_ARGUMENT}, {@link }
  338. * org.osid.repository.RepositoryException#UNKNOWN_ID UNKNOWN_ID}
  339. *
  340. * @access public
  341. */
  342. function deleteAsset ( $assetId , $parentId = null) {
  343. ArgumentValidator::validate($assetId, ExtendsValidatorRule::getRule("Id"));
  344. // Get the asset
  345. $asset =$this->getAsset($assetId);
  346. $assetIdString = $assetId->getIdString();
  347. $children =$asset->getAssets();
  348. // deeper and deeper
  349. while ($children->hasNext()) {
  350. $child =$children->next();
  351. $this->deleteAsset($child->getId(), $assetIdString);
  352. }
  353. // climbing out if multiparent unlink parent
  354. $parents =$asset->_node->getParents();
  355. if ($parents->count() > 1) {
  356. $idManager = Services::getService("Id");
  357. $asset->_node->removeParent($idManager->getId($parentId));
  358. return;
  359. }
  360. // not multiparent delete asset itself
  361.  
  362. // Delete the Records for the Asset
  363. $records =$asset->getRecords();
  364. while ($records->hasNext()) {
  365. $record =$records->next();
  366. $recordId =$record->getId();
  367. $asset->deleteRecord($recordId);
  368. }
  369. // Delete the Record Set
  370. $recordMgr = Services::getService("RecordManager");
  371. $assetId =$asset->getId();
  372. $recordMgr->deleteRecordSet($assetId->getIdString());
  373. // Delete the Asset info
  374. $query = new DeleteQuery;
  375. $query->setTable("dr_asset_info");
  376. $query->setWhere("asset_id='".addslashes($assetId->getIdString())."'");
  377. $dbc = Services::getService("DatabaseManager");
  378. $dbc->query($query, $this->_configuration->getProperty('database_index'));
  379. // Delete the Node for this Asset
  380. $this->_hierarchy->deleteNode($assetId);
  381. // Delete this asset from the createdAssets cache
  382. unset($this->_createdAssets[$assetId->getIdString()]);
  383. // unset our asset types as the list may have now changed.
  384. unset($this->_assetTypes);
  385. }
  386.  
  387. /**
  388. * Get all the Assets in this Repository. Iterators return a set, one at a
  389. * time.
  390. *
  391. * @return object AssetIterator
  392. *
  393. * @throws object RepositoryException An exception with one of
  394. * the following messages defined in
  395. * org.osid.repository.RepositoryException may be thrown: {@link }
  396. * org.osid.repository.RepositoryException#OPERATION_FAILED
  397. * OPERATION_FAILED}, {@link }
  398. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  399. * PERMISSION_DENIED}, {@link }
  400. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  401. * CONFIGURATION_ERROR}, {@link }
  402. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  403. * UNIMPLEMENTED}
  404. *
  405. * @access public
  406. */
  407. function getAssets () {
  408. // get a list for all the nodes under this hierarchy.
  409. $traversalInfoIterator =$this->_hierarchy->traverse($this->_node->getId(),
  410. Hierarchy::TRAVERSE_MODE_DEPTH_FIRST(), Hierarchy::TRAVERSE_DIRECTION_DOWN(),
  411. Hierarchy::TRAVERSE_LEVELS_ALL());
  412. // These are for ignoring nodes, used when we have another repository
  413. // as a child.
  414. $ignoreNodes = FALSE;
  415. $childRepositoryLevel = NULL;
  416. while ($traversalInfoIterator->hasNext()) {
  417. $traversalInfo =$traversalInfoIterator->next();
  418. $assetId =$traversalInfo->getNodeId();
  419. // If we are skipping a child repository, break out of skipping
  420. // when we have reached the level of the child repository and
  421. // its siblings.
  422. if ($ignoreNodes
  423. && $traversalInfo->getLevel() <= $childRepositoryLevel)
  424. {
  425. $ignoreNodes = FALSE;
  426. $childRepositoryLevel = NULL;
  427. }
  428. // make sure that the asset is loaded into the createdAssets array
  429. // make sure that we don't create an asset with the id of the dr.
  430. if (!$assetId->isEqual($this->getId())) {
  431. $node =$this->_hierarchy->getNode($assetId);
  432. // Make sure the child nod is not also a DR
  433. // If the node has the type which defines it as an repository
  434. // ignore it and its children.
  435. if ($this->_repositoryKeyType->isEqual($node->getType())) {
  436. $ignoreNodes = TRUE;
  437. $childRepositoryLevel = $traversalInfo->getLevel();
  438. }
  439. if (!$ignoreNodes)
  440. $this->getAsset($assetId, FALSE);
  441. }
  442. }
  443. // create an AssetIterator with all fo the Assets in the createdAssets array
  444. $assetIterator = new HarmoniAssetIterator($this->_createdAssets);
  445. return $assetIterator;
  446. }
  447.  
  448. /**
  449. * Get all the Assets of the specified AssetType in this Asset. Iterators
  450. * return a set, one at a time.
  451. *
  452. * @param object Type $assetType
  453. *
  454. * @return object AssetIterator
  455. *
  456. * @throws object RepositoryException An exception with one of
  457. * the following messages defined in
  458. * org.osid.repository.RepositoryException may be thrown: {@link }
  459. * org.osid.repository.RepositoryException#OPERATION_FAILED
  460. * OPERATION_FAILED}, {@link }
  461. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  462. * PERMISSION_DENIED}, {@link }
  463. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  464. * CONFIGURATION_ERROR}, {@link }
  465. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  466. * UNIMPLEMENTED}, {@link }
  467. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  468. * NULL_ARGUMENT}, {@link }
  469. * org.osid.repository.RepositoryException#UNKNOWN_TYPE
  470. * UNKNOWN_TYPE}
  471. *
  472. * @access public
  473. */
  474. function getAssetsByType ( $assetType ) {
  475. ArgumentValidator::validate($assetType, ExtendsValidatorRule::getRule("Type"));
  476. $assets = array();
  477. $allAssets =$this->getAssets();
  478. while ($allAssets->hasNext()) {
  479. $asset =$allAssets->next();
  480. if ($assetType->isEqual($asset->getAssetType()))
  481. $assets[] =$asset;
  482. }
  483. $obj = new HarmoniAssetIterator($assets);
  484. return $obj;
  485. }
  486.  
  487. /**
  488. * Get all the AssetTypes in this Repository. AssetTypes are used to
  489. * categorize Assets. Iterators return a set, one at a time.
  490. *
  491. * @return object TypeIterator
  492. *
  493. * @throws object RepositoryException An exception with one of
  494. * the following messages defined in
  495. * org.osid.repository.RepositoryException may be thrown: {@link }
  496. * org.osid.repository.RepositoryException#OPERATION_FAILED
  497. * OPERATION_FAILED}, {@link }
  498. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  499. * PERMISSION_DENIED}, {@link }
  500. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  501. * CONFIGURATION_ERROR}, {@link }
  502. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  503. * UNIMPLEMENTED}
  504. *
  505. * @access public
  506. */
  507. function getAssetTypes () {
  508. if (!isset($this->_assetTypes)) {
  509. $assets =$this->getAssets();
  510. $this->_assetTypes = array();
  511. while ($assets->hasNext()) {
  512. $asset =$assets->next();
  513. // Make sure we haven't added the type yet.
  514. $added = FALSE;
  515. if (count($this->_assetTypes)) {
  516. foreach ($this->_assetTypes as $key=>$type) {
  517. if ($this->_assetTypes[$key]->isEqual($asset->getAssetType()))
  518. $added = TRUE;
  519. }
  520. }
  521. // if we haven't, add the type
  522. if (!$added)
  523. $this->_assetTypes[] =$asset->getAssetType();
  524. }
  525. }
  526. // create the iterator and return it
  527. $typeIterator = new HarmoniTypeIterator($this->_assetTypes);
  528. return $typeIterator;
  529. }
  530. /**
  531. * Get the Properties of this Type associated with this Repository.
  532. *
  533. * @param object Type $propertiesType
  534. *
  535. * @return object Properties
  536. *
  537. * @throws object RepositoryException An exception with one of
  538. * the following messages defined in
  539. * org.osid.repository.RepositoryException may be thrown: {@link }
  540. * org.osid.repository.RepositoryException#OPERATION_FAILED
  541. * OPERATION_FAILED}, {@link }
  542. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  543. * PERMISSION_DENIED}, {@link }
  544. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  545. * CONFIGURATION_ERROR}, {@link }
  546. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  547. * UNIMPLEMENTED}, {@link }
  548. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  549. * NULL_ARGUMENT}, {@link }
  550. * org.osid.repository.RepositoryException#UNKNOWN_TYPE
  551. * UNKNOWN_TYPE}
  552. *
  553. * @access public
  554. */
  555. function getPropertiesByType ( $propertiesType ) {
  556. die ("Method <b>".__FUNCTION__."()</b> declared in interface<b> ".__CLASS__."</b> has not been overloaded in a child class.");
  557. }
  558.  
  559. /**
  560. * Get all the Property Types for Repository.
  561. *
  562. * @return object TypeIterator
  563. *
  564. * @throws object RepositoryException An exception with one of
  565. * the following messages defined in
  566. * org.osid.repository.RepositoryException may be thrown: {@link }
  567. * org.osid.repository.RepositoryException#OPERATION_FAILED
  568. * OPERATION_FAILED}, {@link }
  569. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  570. * PERMISSION_DENIED}, {@link }
  571. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  572. * CONFIGURATION_ERROR}, {@link }
  573. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  574. * UNIMPLEMENTED}
  575. *
  576. * @access public
  577. */
  578. function getPropertyTypes () {
  579. die ("Method <b>".__FUNCTION__."()</b> declared in interface<b> ".__CLASS__."</b> has not been overloaded in a child class.");
  580. }
  581. /**
  582. * Get the Properties associated with this Repository.
  583. *
  584. * @return object PropertiesIterator
  585. *
  586. * @throws object RepositoryException An exception with one of
  587. * the following messages defined in
  588. * org.osid.repository.RepositoryException may be thrown: {@link }
  589. * org.osid.repository.RepositoryException#OPERATION_FAILED
  590. * OPERATION_FAILED}, {@link }
  591. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  592. * PERMISSION_DENIED}, {@link }
  593. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  594. * CONFIGURATION_ERROR}, {@link }
  595. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  596. * UNIMPLEMENTED}
  597. *
  598. * @access public
  599. */
  600. function getProperties () {
  601. die ("Method <b>".__FUNCTION__."()</b> declared in interface<b> ".__CLASS__."</b> has not been overloaded in a child class.");
  602. }
  603.  
  604. /**
  605. * Get all the RecordStructures with the specified RecordStructureType in
  606. * this Repository. RecordStructures are used to categorize information
  607. * about Assets. Iterators return a set, one at a time.
  608. *
  609. * @param object Type $recordStructureType
  610. *
  611. * @return object RecordStructure
  612. *
  613. * @throws object RepositoryException An exception with one of
  614. * the following messages defined in
  615. * org.osid.repository.RepositoryException may be thrown: {@link }
  616. * org.osid.repository.RepositoryException#OPERATION_FAILED
  617. * OPERATION_FAILED}, {@link }
  618. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  619. * PERMISSION_DENIED}, {@link }
  620. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  621. * CONFIGURATION_ERROR}, {@link }
  622. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  623. * UNIMPLEMENTED}
  624. *
  625. * @access public
  626. */
  627. function getRecordStructuresByType ( $recordStructureType ) {
  628. die ("Method <b>".__FUNCTION__."()</b> declared in interface<b> ".__CLASS__."</b> has not been overloaded in a child class.");
  629. }
  630. /**
  631. * Get all the SearchTypes supported by this Repository. Iterators return
  632. * a set, one at a time.
  633. *
  634. * @return object TypeIterator
  635. *
  636. * @throws object RepositoryException An exception with one of
  637. * the following messages defined in
  638. * org.osid.repository.RepositoryException may be thrown: {@link }
  639. * org.osid.repository.RepositoryException#OPERATION_FAILED
  640. * OPERATION_FAILED}, {@link }
  641. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  642. * PERMISSION_DENIED}, {@link }
  643. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  644. * CONFIGURATION_ERROR}, {@link }
  645. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  646. * UNIMPLEMENTED}
  647. *
  648. * @access public
  649. */
  650. function getSearchTypes () {
  651. $obj = new HarmoniTypeIterator($this->_searchTypes);
  652. return $obj;
  653. }
  654. /**
  655. * Get all the StatusTypes supported by this Repository. Iterators return
  656. * a set, one at a time.
  657. *
  658. * @return object TypeIterator
  659. *
  660. * @throws object RepositoryException An exception with one of
  661. * the following messages defined in
  662. * org.osid.repository.RepositoryException may be thrown: {@link }
  663. * org.osid.repository.RepositoryException#OPERATION_FAILED
  664. * OPERATION_FAILED}, {@link }
  665. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  666. * PERMISSION_DENIED}, {@link }
  667. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  668. * CONFIGURATION_ERROR}, {@link }
  669. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  670. * UNIMPLEMENTED}
  671. *
  672. * @access public
  673. */
  674. function getStatusTypes () {
  675. die ("Method <b>".__FUNCTION__."()</b> declared in class <b> ".__CLASS__."</b> has not been implimented.");
  676. }
  677. /**
  678. * Get the RecordStructure in this DigitalRepository with the specified Id. RecordStructures are used to categorize information about Assets.
  679. * Note: This method is a Harmoni addition to the OSID and at the time of this writing,
  680. * was not a part of the DR OSID.
  681. * @param object $infoStructureId
  682. * @return object RecordStructure The RecordStructure of the requested Id.
  683. * @throws osid.dr.DigitalRepositoryException An exception with one of the following messages defined in osid.dr.DigitalRepositoryException may be thrown: {@link DigitalRepositoryException#OPERATION_FAILED OPERATION_FAILED}, {@link DigitalRepositoryException#PERMISSION_DENIED PERMISSION_DENIED}, {@link DigitalRepositoryException#CONFIGURATION_ERROR CONFIGURATION_ERROR}, {@link DigitalRepositoryException#UNIMPLEMENTED UNIMPLEMENTED}
  684. */
  685. function getRecordStructure( $infoStructureId ) {
  686. // Check that we have created an infoStructure with the ID
  687. if (!isset($this->_createdRecordStructures[$infoStructureId->getIdString()])) {
  688. // If not, create the infoStructure
  689. $schemaMgr = Services::getService("SchemaManager");
  690. $schema =$schemaMgr->getSchemaByID($infoStructureId->getIdString());
  691. $this->_createdRecordStructures[$infoStructureId->getIdString()] = new HarmoniRecordStructure(
  692. $schema, $this->getId());
  693. }
  694. return $this->_createdRecordStructures[$infoStructureId->getIdString()];
  695. }
  696. /**
  697. * Get all the RecordStructures in this Repository. RecordStructures are
  698. * used to categorize information about Assets. Iterators return a set,
  699. * one at a time.
  700. *
  701. * @return object RecordStructureIterator
  702. *
  703. * @throws object RepositoryException An exception with one of
  704. * the following messages defined in
  705. * org.osid.repository.RepositoryException may be thrown: {@link }
  706. * org.osid.repository.RepositoryException#OPERATION_FAILED
  707. * OPERATION_FAILED}, {@link }
  708. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  709. * PERMISSION_DENIED}, {@link }
  710. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  711. * CONFIGURATION_ERROR}, {@link }
  712. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  713. * UNIMPLEMENTED}
  714. *
  715. * @access public
  716. */
  717. function getRecordStructures () {
  718. $schemaMgr = Services::getService("SchemaManager");
  719. $schemaIDs = $schemaMgr->getAllSchemaIDs();
  720. foreach ($schemaIDs as $id) {
  721. // Make sure that this record structure is either a global one
  722. // or particular to this repository
  723. $repositoryId =$this->getId();
  724. $repositoryIdString = str_replace('.', '\.', $repositoryId->getIdString());
  725. if ((preg_match("/^Repository::".$repositoryIdString."::.+/", $id)
  726. || !preg_match("/^Repository::.+::.+/", $id))
  727. // Check that we have created an RecordStructure with the ID
  728. && !isset($this->_createdRecordStructures[$id]))
  729. {
  730. // If not, create the RecordStructure
  731. $schema =$schemaMgr->getSchemaByID($id);
  732. $this->_createdRecordStructures[$id] = new HarmoniRecordStructure(
  733. $schema, $this->getId());
  734. }
  735. }
  736. // create an Iterator and return it
  737. $iterator = new HarmoniRecordStructureIterator($this->_createdRecordStructures);
  738. return $iterator;
  739. }
  740.  
  741. /**
  742. * Get the StatusType of the Asset with the specified unique Id.
  743. *
  744. * @param object Id $assetId
  745. *
  746. * @return object Type
  747. *
  748. * @throws object RepositoryException An exception with one of
  749. * the following messages defined in
  750. * org.osid.repository.RepositoryException may be thrown: {@link }
  751. * org.osid.repository.RepositoryException#OPERATION_FAILED
  752. * OPERATION_FAILED}, {@link }
  753. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  754. * PERMISSION_DENIED}, {@link }
  755. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  756. * CONFIGURATION_ERROR}, {@link }
  757. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  758. * UNIMPLEMENTED}, {@link }
  759. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  760. * NULL_ARGUMENT}, {@link }
  761. * org.osid.repository.RepositoryException#UNKNOWN_ID UNKNOWN_ID}
  762. *
  763. * @access public
  764. */
  765. function getStatus ( $assetId ) {
  766. die ("Method <b>".__FUNCTION__."()</b> declared in class <b> ".__CLASS__."</b> has not been implimented.");
  767. }
  768.  
  769. /**
  770. * Validate all the Records for an Asset and set its status Type
  771. * accordingly. If the Asset is valid, return true; otherwise return
  772. * false. The implementation may throw an Exception for any validation
  773. * failures and use the Exception's message to identify specific causes.
  774. *
  775. * @param object Id $assetId
  776. *
  777. * @return boolean
  778. *
  779. * @throws object RepositoryException An exception with one of
  780. * the following messages defined in
  781. * org.osid.repository.RepositoryException may be thrown: {@link }
  782. * org.osid.repository.RepositoryException#OPERATION_FAILED
  783. * OPERATION_FAILED}, {@link }
  784. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  785. * PERMISSION_DENIED}, {@link }
  786. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  787. * CONFIGURATION_ERROR}, {@link }
  788. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  789. * UNIMPLEMENTED}, {@link }
  790. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  791. * NULL_ARGUMENT}, {@link }
  792. * org.osid.repository.RepositoryException#UNKNOWN_ID UNKNOWN_ID}
  793. *
  794. * @access public
  795. */
  796. function validateAsset ( $assetId ) {
  797. $string = $assetId->getIdString();
  798. $this->_assetValidFlags[$string] = true;
  799. }
  800.  
  801. /**
  802. * Set the Asset's status Type accordingly and relax validation checking
  803. * when creating Records and Parts or updating Parts' values.
  804. *
  805. * @param object Id $assetId
  806. *
  807. * @throws object RepositoryException An exception with one of
  808. * the following messages defined in
  809. * org.osid.repository.RepositoryException may be thrown: {@link }
  810. * org.osid.repository.RepositoryException#OPERATION_FAILED
  811. * OPERATION_FAILED}, {@link }
  812. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  813. * PERMISSION_DENIED}, {@link }
  814. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  815. * CONFIGURATION_ERROR}, {@link }
  816. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  817. * UNIMPLEMENTED}, {@link }
  818. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  819. * NULL_ARGUMENT}, {@link }
  820. * org.osid.repository.RepositoryException#UNKNOWN_ID UNKNOWN_ID}
  821. *
  822. * @access public
  823. */
  824. function invalidateAsset ( $assetId ) {
  825. $string = $assetId->getIdString();
  826. $this->_assetValidFlags[$string] = false;
  827. }
  828.  
  829. /**
  830. * Get the Asset with the specified unique Id.
  831. *
  832. * @param object Id $assetId
  833. * @param option boolean $verifyExistance WARNING: not in OSID.
  834. * This parameter is used to allow calls to getAsset() from
  835. * inside this implementation to avoid re-checking the existance
  836. * of the asset as by their nature, that existance is ensured.
  837. *
  838. * @return object Asset
  839. *
  840. * @throws object RepositoryException An exception with one of
  841. * the following messages defined in
  842. * org.osid.repository.RepositoryException may be thrown: {@link }
  843. * org.osid.repository.RepositoryException#OPERATION_FAILED
  844. * OPERATION_FAILED}, {@link }
  845. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  846. * PERMISSION_DENIED}, {@link }
  847. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  848. * CONFIGURATION_ERROR}, {@link }
  849. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  850. * UNIMPLEMENTED}, {@link }
  851. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  852. * NULL_ARGUMENT}, {@link }
  853. * org.osid.repository.RepositoryException#UNKNOWN_ID UNKNOWN_ID}
  854. *
  855. * @access public
  856. */
  857. function getAsset ( $assetId, $verifyExistance = TRUE) {
  858. ArgumentValidator::validate($assetId, ExtendsValidatorRule::getRule("Id"));
  859. if (!isset($this->_createdAssets[$assetId->getIdString()])) {
  860. if ($verifyExistance) {
  861. // Get the node for this asset to make sure its available
  862. if (!$this->_hierarchy->getNode($assetId))
  863. throwError(new Error(RepositoryException::UNKNOWN_ID(), "Repository", 1));
  864. // Verify that the requested Asset is in this DR.
  865. $repositoryMan = Services::getService("Repository");
  866. $repositoryId = $repositoryMan->_getAssetRepository($assetId);
  867. if (!$repositoryId
  868. || !$repositoryId->isEqual($this->getId()))
  869. {
  870. throwError(new Error(RepositoryException::UNKNOWN_ID()." for an Asset: ".$assetId->getIdString(), "Repository", 1));
  871. }
  872. }
  873. // create the asset and add it to the cache
  874. $this->_createdAssets[$assetId->getIdString()] = new HarmoniAsset($this->_hierarchy, $this, $assetId, $this->_configuration);
  875. $this->_assetValidFlags[$assetId->getIdString()] = true;
  876. }
  877. // Dish out the asset.
  878. return $this->_createdAssets[$assetId->getIdString()];
  879. }
  880. /**
  881. * Answer true if the asset exists
  882. *
  883. * WARNING: NOT IN OSID
  884. *
  885. * @param object Id $assetId
  886. * @return boolean
  887. * @access public
  888. * @since 1/22/07
  889. */
  890. function assetExists ( $assetId ) {
  891. if (isset($this->_createdAssets[$assetId->getIdString()]))
  892. return true;
  893. else {
  894. if ($this->_hierarchy->nodeExists($assetId))
  895. return true;
  896. else
  897. return false;
  898. }
  899. }
  900.  
  901. /**
  902. * Get the Asset with the specified unique Id that is appropriate for the
  903. * date specified. The specified date allows a Repository implementation
  904. * to support Asset versioning.
  905. *
  906. * @param object Id $assetId
  907. * @param object DateAndTime $date
  908. *
  909. * @return object Asset
  910. *
  911. * @throws object RepositoryException An exception with one of
  912. * the following messages defined in
  913. * org.osid.repository.RepositoryException may be thrown: {@link }
  914. * org.osid.repository.RepositoryException#OPERATION_FAILED
  915. * OPERATION_FAILED}, {@link }
  916. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  917. * PERMISSION_DENIED}, {@link }
  918. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  919. * CONFIGURATION_ERROR}, {@link }
  920. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  921. * UNIMPLEMENTED}, {@link }
  922. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  923. * NULL_ARGUMENT}, {@link }
  924. * org.osid.repository.RepositoryException#NO_OBJECT_WITH_THIS_DATE
  925. * NO_OBJECT_WITH_THIS_DATE}
  926. *
  927. * @access public
  928. */
  929. function getAssetByDate ( $assetId, $date ) {
  930. ArgumentValidator::validate($assetId, ExtendsValidatorRule::getRule("Id"));
  931. ArgumentValidator::validate($date, HasMethodsValidatorRule::getRule("asDateAndTime"));
  932. die ("Method <b>".__FUNCTION__."()</b> declared in class <b> ".__CLASS__."</b> has not been implimented.");
  933. // Return an Asset where all Records have the values that they
  934. // would have on the specified date.
  935. }
  936. /**
  937. * Get all the dates for the Asset with the specified unique Id. These
  938. * dates allows a Repository implementation to support Asset versioning.
  939. *
  940. * @param object Id $assetId
  941. *
  942. * @return object LongValueIterator
  943. *
  944. * @throws object RepositoryException An exception with one of
  945. * the following messages defined in
  946. * org.osid.repository.RepositoryException may be thrown: {@link }
  947. * org.osid.repository.RepositoryException#OPERATION_FAILED
  948. * OPERATION_FAILED}, {@link }
  949. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  950. * PERMISSION_DENIED}, {@link }
  951. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  952. * CONFIGURATION_ERROR}, {@link }
  953. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  954. * UNIMPLEMENTED}, {@link }
  955. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  956. * NULL_ARGUMENT}
  957. *
  958. * @access public
  959. */
  960. function getAssetDates ( $assetId ) {
  961. ArgumentValidator::validate($assetId, ExtendsValidatorRule::getRule("Id"));
  962. $recordMgr = Services::getService("RecordManager");
  963. // Get the DataSets in the Asset's DataSetGroup
  964. $recordSet =$recordMgr->fetchRecordSet($assetId->getIdString());
  965. // $recordSet->loadRecords(RECORD_FULL);
  966. // $records =$dataSetGroup->fetchDataSets(TRUE);
  967. $dates = $recordSet->getMergedTagDates();
  968.  
  969. // Create and return an iterator.
  970. $dateIterator = new HarmoniCalendarIterator($dates);
  971. return $dateIterator;
  972. }
  973.  
  974. /**
  975. * Perform a search of the specified Type and get all the Assets that
  976. * satisfy the SearchCriteria. Iterators return a set, one at a time.
  977. *
  978. * @param object mixed $searchCriteria (original type: java.io.Serializable)
  979. * @param object Type $searchType
  980. * @param object Properties $searchProperties
  981. *
  982. * @return object AssetIterator
  983. *
  984. * @throws object RepositoryException An exception with one of
  985. * the following messages defined in
  986. * org.osid.repository.RepositoryException may be thrown: {@link }
  987. * org.osid.repository.RepositoryException#OPERATION_FAILED
  988. * OPERATION_FAILED}, {@link }
  989. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  990. * PERMISSION_DENIED}, {@link }
  991. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  992. * CONFIGURATION_ERROR}, {@link }
  993. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  994. * UNIMPLEMENTED}, {@link }
  995. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  996. * NULL_ARGUMENT}, {@link }
  997. * org.osid.repository.RepositoryException#UNKNOWN_TYPE
  998. * UNKNOWN_TYPE}
  999. *
  1000. * @access public
  1001. */
  1002. function getAssetsBySearch ( $searchCriteria, $searchType, $searchProperties ) {
  1003. ArgumentValidator::validate($searchType, ExtendsValidatorRule::getRule("Type"));
  1004. ArgumentValidator::validate($searchProperties, OptionalRule::getRule(
  1005. ExtendsValidatorRule::getRule("Properties")));
  1006. // Check that we support the searchType
  1007. $supported = FALSE;
  1008. foreach (array_keys($this->_searchTypes) as $key) {
  1009. if ($searchType->isEqual($this->_searchTypes[$key])) {
  1010. $supported = TRUE;
  1011. $searchName = $key;
  1012. break;
  1013. }
  1014. }
  1015. if ($supported) {
  1016. $search = new $searchName($this);
  1017. $assetIds =$search->searchAssets($searchCriteria, $searchProperties);
  1018. // get the assets for the resuting ids
  1019. $assets = array();
  1020. // Order
  1021. if (is_object($searchProperties)
  1022. && $searchProperties->getProperty("order") == ("DisplayName"))
  1023. {
  1024. foreach ($assetIds as $key => $id) {
  1025. $asset =$this->getAsset($assetIds[$key], FALSE);
  1026. $assets[$asset->getDisplayName().$id->getIdString()] =$asset;
  1027. }
  1028. } else if (is_object($searchProperties)
  1029. && $searchProperties->getProperty("order") == ("Id"))
  1030. {
  1031. foreach ($assetIds as $key => $id)
  1032. $assets[$assetIds[$key]->getIdString()] =$this->getAsset($assetIds[$key], FALSE);
  1033. } else if (is_object($searchProperties)
  1034. && $searchProperties->getProperty("order") == ("ModificationDate"))
  1035. {
  1036. foreach ($assetIds as $key => $id) {
  1037. $asset =$this->getAsset($assetIds[$key], FALSE);
  1038. $date =$asset->getModificationDate();
  1039. $assets[$date->asString().$id->getIdString()] =$asset;
  1040. }
  1041. } else if (is_object($searchProperties)
  1042. && $searchProperties->getProperty("order") == ("CreationDate"))
  1043. {
  1044. foreach ($assetIds as $key => $id) {
  1045. $asset =$this->getAsset($assetIds[$key], FALSE);
  1046. $date =$asset->getCreationDate();
  1047. $assets[$date->asString().$id->getIdString()] =$asset;
  1048. }
  1049. } else {
  1050. foreach ($assetIds as $key => $id)
  1051. $assets[] =$this->getAsset($assetIds[$key], FALSE);
  1052. }
  1053. // Filter based on type
  1054. // This can probably be moved to the search modules to improve
  1055. // performance by eliminating these assets before they are otherwise
  1056. // operated on.
  1057. if (is_object($searchProperties)
  1058. && is_array($searchProperties->getProperty("allowed_types"))
  1059. && count($searchProperties->getProperty("allowed_types")))
  1060. {
  1061. $allowedTypes =$searchProperties->getProperty("allowed_types");
  1062. foreach (array_keys($assets) as $key) {
  1063. $type =$assets[$key]->getAssetType();
  1064. $allowed = FALSE;
  1065. foreach (array_keys($allowedTypes) as $typeKey) {
  1066. if ($type->isEqual($allowedTypes[$typeKey])) {
  1067. $allowed = TRUE;
  1068. break;
  1069. }
  1070. }
  1071. if (!$allowed)
  1072. unset($assets[$key]);
  1073. }
  1074. }
  1075. // Order Direction
  1076. if (is_object($searchProperties)
  1077. && $searchProperties->getProperty("direction") == "DESC")
  1078. {
  1079. krsort($assets);
  1080. } else {
  1081. ksort($assets);
  1082. }
  1083. // create an AssetIterator and return it
  1084. $assetIterator = new HarmoniAssetIterator($assets);
  1085. return $assetIterator;
  1086. } else {
  1087. throwError(new Error(RepositoryException::UNKNOWN_TYPE()." ".$searchType->getDomain()."::".$searchType->getAuthority()."::".$searchType->getKeyword(), "Repository", 1));
  1088. }
  1089. }
  1090.  
  1091. /**
  1092. * Create a copy of an Asset. The Id, AssetType, and Repository for the
  1093. * new Asset is set by the implementation. All Records are similarly
  1094. * copied.
  1095. *
  1096. * @param object Asset $asset
  1097. *
  1098. * @return object Id
  1099. *
  1100. * @throws object RepositoryException An exception with one of
  1101. * the following messages defined in
  1102. * org.osid.repository.RepositoryException may be thrown: {@link }
  1103. * org.osid.repository.RepositoryException#OPERATION_FAILED
  1104. * OPERATION_FAILED}, {@link }
  1105. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  1106. * PERMISSION_DENIED}, {@link }
  1107. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  1108. * CONFIGURATION_ERROR}, {@link }
  1109. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  1110. * UNIMPLEMENTED}, {@link }
  1111. * org.osid.repository.RepositoryException#NULL_ARGUMENT
  1112. * NULL_ARGUMENT}, {@link }
  1113. * org.osid.repository.RepositoryException#UNKNOWN_ID UNKNOWN_ID}
  1114. *
  1115. * @access public
  1116. */
  1117. function copyAsset ( $asset ) {
  1118. // Copy the asset to the dr root (recursivley for children)
  1119. $id =$this->_copyAsset($asset, $this->getId());
  1120. return $id;
  1121. }
  1122. /**
  1123. * Create an RecordStructure in this DR. This is not part of the DR OSID at
  1124. * the time of this writing, but is needed for dynamically created
  1125. * RecordStructures.
  1126. *
  1127. * @param string $displayName The DisplayName of the new RecordStructure.
  1128. * @param string $description The Description of the new RecordStructure.
  1129. * @param string $format The Format of the new RecordStructure.
  1130. * @param string $schema The schema of the new RecordStructure.
  1131. *
  1132. * @return object RecordStructure The newly created RecordStructure.
  1133. */
  1134. /**
  1135. * This method indicates whether this implementation supports Repository
  1136. * methods getAssetsDates() and getAssetByDate()
  1137. *
  1138. * @return boolean
  1139. *
  1140. * @throws object RepositoryException An exception with one of
  1141. * the following messages defined in
  1142. * org.osid.repository.RepositoryException may be thrown: {@link }
  1143. * org.osid.repository.RepositoryException#OPERATION_FAILED
  1144. * OPERATION_FAILED}, {@link }
  1145. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  1146. * PERMISSION_DENIED}, {@link }
  1147. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  1148. * CONFIGURATION_ERROR}, {@link }
  1149. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  1150. * UNIMPLEMENTED}
  1151. *
  1152. * @access public
  1153. */
  1154. function supportsVersioning () {
  1155. die ("Method <b>".__FUNCTION__."()</b> declared in interface<b> ".__CLASS__."</b> has not been overloaded in a child class.");
  1156. }
  1157. /**
  1158. * This method indicates whether this implementation supports Repository
  1159. * methods: copyAsset, deleteAsset, invalidateAsset, updateDescription,
  1160. * updateDisplayName. Asset methods: addAsset, copyRecordStructure,
  1161. * createRecord, deleteRecord, inheritRecordStructure, removeAsset,
  1162. * updateContent, updateDescription, updateDisplayName,
  1163. * updateEffectiveDate, updateExpirationDate. Part methods: createPart,
  1164. * deletePart, updateDisplayName, updateValue. PartStructure methods:
  1165. * updateDisplayName, validatePart. Record methods: createPart,
  1166. * deletePart, updateDisplayName. RecordStructure methods:
  1167. * updateDisplayName, validateRecord.
  1168. *
  1169. * @return boolean
  1170. *
  1171. * @throws object RepositoryException An exception with one of
  1172. * the following messages defined in
  1173. * org.osid.repository.RepositoryException may be thrown: {@link }
  1174. * org.osid.repository.RepositoryException#OPERATION_FAILED
  1175. * OPERATION_FAILED}, {@link }
  1176. * org.osid.repository.RepositoryException#PERMISSION_DENIED
  1177. * PERMISSION_DENIED}, {@link }
  1178. * org.osid.repository.RepositoryException#CONFIGURATION_ERROR
  1179. * CONFIGURATION_ERROR}, {@link }
  1180. * org.osid.repository.RepositoryException#UNIMPLEMENTED
  1181. * UNIMPLEMENTED}
  1182. *
  1183. * @access public
  1184. */
  1185. function supportsUpdate () {
  1186. die ("Method <b>".__FUNCTION__."()</b> declared in interface<b> ".__CLASS__."</b> has not been overloaded in a child class.");
  1187. }
  1188. /**
  1189. * Create a new RecordStructure
  1190. *
  1191. * WARNING: NOT IN OSID
  1192. *
  1193. * @param string $displayName
  1194. * @param string $description
  1195. * @param string $format
  1196. * @param string $schema
  1197. * @param optional object $theID
  1198. * @param boolean $isGlobal
  1199. * @return object RecordStructure
  1200. * @access public
  1201. * @since 2/17/05
  1202. */
  1203. function createRecordStructure($displayName, $description, $format, $schema,
  1204. $theID=null, $isGlobal = FALSE)
  1205. {
  1206. $schemaMgr = Services::getService("SchemaManager");
  1207. if ($theID == null) {
  1208. $idMgr = Services::getService("Id");
  1209. $id =$idMgr->createId();
  1210. } else {
  1211. $id =$theID;
  1212. }
  1213. // Limit the Record Struture just to this repository if it is not
  1214. // specified as global.
  1215. if ($isGlobal)
  1216. $idString = $id->getIdString();
  1217. else {
  1218. $repositoryId =$this->getId();
  1219. $idString = "Repository::".$repositoryId->getIdString()."::".$id->getIdString();
  1220. }
  1221.  
  1222. // Create the Schema
  1223. $tempSchema = new Schema($idString, $displayName, 1, $description,
  1224. array("format"=>$format, "schema"=>$schema));
  1225. $schemaMgr->synchronize($tempSchema);
  1226. // The SchemaManager only allows you to use Schemas created by it for use with Records.
  1227. $schema =$schemaMgr->getSchemaByID($idString);
  1228. //debug::output("RecordStructure is being created from Schema with Id: '".$schema->getID()."'");
  1229. $this->_createdRecordStructures[$schema->getID()] = new HarmoniRecordStructure(
  1230. $schema, $this->getId());
  1231. return $this->_createdRecordStructures[$schema->getID()];
  1232. }
  1233. /**
  1234. * Delete a RecordStructure all Records in the repository that use it.
  1235. *
  1236. * WARNING: NOT IN OSID
  1237. *
  1238. * @param object Id $recordStructureId
  1239. * @return void
  1240. * @access public
  1241. * @since 6/6/06
  1242. */
  1243. function deleteRecordStructure ( $recordStructureId, $statusStars = null ) {
  1244. // Delete the Records that use this RecordStructure
  1245. $assets =$this->getAssets();
  1246. if (!is_null($statusStars))
  1247. $statusStars->initializeStatistics($assets->count());
  1248. while ($assets->hasNext()) {
  1249. $asset =$assets->next();
  1250. $records =$asset->getRecordsByRecordStructure($recordStructureId);
  1251. while ($records->hasNext()) {
  1252. $record =$records->next();
  1253. $asset->deleteRecord($record->getId());
  1254. }
  1255. if (!is_null($statusStars))
  1256. $statusStars->updateStatistics();
  1257. }
  1258. // Delete the Structure
  1259. $schemaMgr = Services::getService("SchemaManager");
  1260. $recordMgr = Services::getService("RecordManager");
  1261. $recordIdsForSchema = $recordMgr->getRecordIDsByType($recordStructureId->getIdString());
  1262. if (count($recordIdsForSchema)) {
  1263. throwError(new Error(
  1264. RepositoryException::OPERATION_FAILED()
  1265. ." when deleting RecordStructure: '"
  1266. .$recordStructureId->getIdString()
  1267. ."', Records exist for this RecordStructure.",
  1268. "Repository", 1));
  1269. }
  1270. $schema =$schemaMgr->deleteSchema($recordStructureId->getIdString());
  1271. }
  1272. /**
  1273. * Duplicate a RecordStructure, optionally duplicating the records as well,
  1274. * also optionally deleting the records in the original RecordStructure.
  1275. *
  1276. * Use this method to convert from data stored in a 'global' RecordStructure
  1277. * such as DublinCore into a 'local' version of the RecordStructure Core in which the
  1278. * user has the option of customizing fields.
  1279. *
  1280. * As well, this method can be used to convert a RecordStructure and associated
  1281. * Records to a local version if the RecordStructure was accidentally created
  1282. * as a 'global' one.
  1283. *
  1284. * WARNING: NOT IN OSID
  1285. *
  1286. * @param object Id $recordStructureId The id of the RecordStructure to duplicate
  1287. * @param boolean $copyRecords If true, existing records will be duplicated
  1288. * under the new RecordStructure.
  1289. * @param optional object $id An optional id for the new RecordStructure
  1290. * @param optional boolean $isGlobal If true the new RecordStructure will be made a global one.
  1291. * @param optional object $statusStars A status indicator to use if passed.
  1292. * @return void
  1293. * @access public
  1294. * @since 6/7/06
  1295. */
  1296. function duplicateRecordStructure ( $recordStructureId, $copyRecords = FALSE,
  1297. $id = null, $isGlobal = FALSE, $statusStars = null )
  1298. {
  1299. ArgumentValidator::validate($recordStructureId, ExtendsValidatorRule::getRule("Id"));
  1300. ArgumentValidator::validate($copyRecords, BooleanValidatorRule::getRule());
  1301. ArgumentValidator::validate($id, OptionalRule::getRule(
  1302. ExtendsValidatorRule::getRule("Id")));
  1303. ArgumentValidator::validate($isGlobal, BooleanValidatorRule::getRule());
  1304. $oldRecStruct =$this->getRecordStructure($recordStructureId);
  1305. $newRecStruct =$this->createRecordStructure(
  1306. $oldRecStruct->getDisplayName()._(" Copy"),
  1307. $oldRecStruct->getDescription(),
  1308. $oldRecStruct->getFormat(),
  1309. $oldRecStruct->getSchema(),
  1310. $id,
  1311. $isGlobal);
  1312. $mapping = array();
  1313. $oldPartStructs =$oldRecStruct->getPartStructures();
  1314. while ($oldPartStructs->hasNext()) {
  1315. $oldPartStruct =$oldPartStructs->next();
  1316. $newPartStruct =$newRecStruct->createPartStructure(
  1317. $oldPartStruct->getDisplayName(),
  1318. $oldPartStruct->getDescription(),
  1319. $oldPartStruct->getType(),
  1320. $oldPartStruct->isMandatory(),
  1321. $oldPartStruct->isRepeatable(),
  1322. $oldPartStruct->isPopulatedByRepository());
  1323. // Mapping
  1324. $oldPartStructId =$oldPartStruct->getId();
  1325. $mapping[$oldPartStructId->getIdString()] =$newPartStruct->getId();
  1326. }
  1327. unset($oldPartStruct, $newPartStruct);
  1328. if ($copyRecords) {
  1329. $assets =$this->getAssets();
  1330. if (!is_null($statusStars))
  1331. $statusStars->initializeStatistics($assets->count());
  1332. while ($assets->hasNext()) {
  1333. $asset =$assets->next();
  1334. $oldRecords =$asset->getRecordsByRecordStructure($oldRecStruct->getId());
  1335. while ($oldRecords->hasNext()) {
  1336. $oldRecord =$oldRecords->next();
  1337. // Create the new Record
  1338. $newRecord =$asset->createRecord($newRecStruct->getId());
  1339. $oldParts =$oldRecord->getParts();
  1340. while ($oldParts->hasNext()) {
  1341. $oldPart =$oldParts->next();
  1342. $oldPartStruct =$oldPart->getPartStructure();
  1343. $oldPartStructId =$oldPartStruct->getId();
  1344. $newPart =$newRecord->createPart(
  1345. $mapping[$oldPartStructId->getIdString()],
  1346. $oldPart->getValue());
  1347. }
  1348. }
  1349. if (!is_null($statusStars))
  1350. $statusStars->updateStatistics();
  1351. }
  1352. }
  1353. return $newRecStruct;
  1354. }
  1355.  
  1356. /**
  1357. * Recursively copies an asset and its children to a new parent.
  1358. *
  1359. * @access private
  1360. */
  1361. function _copyAsset($asset, $newParentId) {
  1362. // Create the new asset
  1363. $newAsset =$this->createAsset($asset->getDisplayName(),$asset->getDescription(), $asset->getAssetType());
  1364. // Move the new asset to the proper parent if it
  1365. // is not being copied to the dr root.
  1366. if (!$newParentId->isEqual($this->getId())) {
  1367. $newParent =$this->getAsset($newParentId);
  1368. $newParent->addAsset($newAsset->getId());
  1369. }
  1370. // Copy its data
  1371. // @todo
  1372. // Copy the children
  1373. $children =$asset->getAssets();
  1374. while ($children->hasNext()) {
  1375. $childAsset =$children->next();
  1376. $this->_copyAsset($childAsset, $newAsset->getId());
  1377. }
  1378. // Return its Id
  1379. return $newAsset->getId();
  1380. }
  1381. // /**
  1382. // * Convert Records from one storage method (Class) to another.
  1383. // *
  1384. // * @param object Id $recordStructureId The Id of the RecordStructure of both
  1385. // * Record classes. They must share the same RecordStructure
  1386. // * @param string $destinationClass
  1387. // * @return void
  1388. // * @access public
  1389. // * @since 2/17/05
  1390. // */
  1391. // function convertRecords ( $recordStructureId, $destinationClass ) {
  1392. // $recordStructure =$this->getRecordStructure($recordStructureId);
  1393. //
  1394. // $allAssets =$this->getAssets();
  1395. // while ($allAssets->hasNextAsset()) {
  1396. // $asset =$allAssets->nextAsset();
  1397. //
  1398. // $assetId =$asset->getId();
  1399. // print "\n<br/>\t - Converting Asset: ".$assetId->getIdString();
  1400. //
  1401. // $origRecords =$asset->getRecordsByRecordStructure($recordStructureId);
  1402. // while ($origRecords->hasNextRecord()) {
  1403. // $origRecord =$origRecords->nextRecord();
  1404. //
  1405. // $recordId =$origRecord->getId();
  1406. // print "\n<br/>\t - \t - Converting Record: ".$recordId->getIdString();
  1407. //
  1408. // $newRecord = new $destinationClass (
  1409. // $recordStructure,
  1410. // $origRecord->getId(),
  1411. // $this->_configuration()
  1412. // );
  1413. // $newRecord->copyFromRecord($origRecord);
  1414. // }
  1415. // }
  1416. // }
  1417.  
  1418. /****************************************************************************
  1419. * Search Types
  1420. *
  1421. * The private functions below contain the funtionality for searching the DR.
  1422. * The registerSearchTypes() function sets up an array of supported searchTypes
  1423. * for the DR. When creating a search function, be sure to add its type to
  1424. * registerSearchTypes().
  1425. * Search functions are named _searchBy_TypeAuthority_TypeDomain_TypeKeyword().
  1426. ******************************************************************************/
  1427.  
  1428. /**
  1429. * Sets up an array of supported searchTypes for the DR.
  1430. *
  1431. * @access private
  1432. */
  1433. function _registerSearchTypes () {
  1434. $this->_searchTypes = array();
  1435. // classname => type obj
  1436. $this->_searchTypes["KeywordSearch"] = new Type(
  1437. "Repository",
  1438. "edu.middlebury.harmoni",
  1439. "Keyword",
  1440. "Search with a string for keywords.");
  1441. $this->_searchTypes["AuthoritativeValuesSearch"] = new Type(
  1442. "Repository",
  1443. "edu.middlebury.harmoni",
  1444. "Authoritative Values",
  1445. "Select from the authoritative values on a particular field.");
  1446. $this->_searchTypes["AssetTypeSearch"] = new Type(
  1447. "Repository",
  1448. "edu.middlebury.harmoni",
  1449. "AssetType",
  1450. "Select all asset's of the specified Type.");
  1451. $this->_searchTypes["RootAssetSearch"] = new Type(
  1452. "Repository",
  1453. "edu.middlebury.harmoni",
  1454. "RootAssets",
  1455. "Search for just the 'root' or 'top level' assets which are not assets of other assets.");
  1456. $this->_searchTypes["DisplayNameSearch"] = new Type(
  1457. "Repository",
  1458. "edu.middlebury.harmoni",
  1459. "DisplayName",
  1460. "Search with a regular expression string in the Asset DisplayName.");
  1461.  
  1462. $this->_searchTypes["DescriptionSearch"] = new Type(
  1463. "Repository",
  1464. "edu.middlebury.harmoni",
  1465. "Description",
  1466. "Search with a regular expression string in the Asset Description.");
  1467.  
  1468. $this->_searchTypes["ContentSearch"] = new Type(
  1469. "Repository",
  1470. "edu.middlebury.harmoni",
  1471. "Content",
  1472. "Search with a regular expression string in the Asset Content.");
  1473.  
  1474. }
  1475.  
  1476. }
  1477.  
  1478. ?>

Documentation generated on Wed, 19 Sep 2007 10:24:17 -0400 by phpDocumentor 1.3.0RC3