/**
  * Register files associated to a PCI track by $typeIdentifier
  *
  * @refactor improve response
  *
  * @param PortableElementObject $object
  * @param string[] $files Relative path of portable element files
  * @param string $source Location of temporary directory
  * @return bool
  * @throws PortableElementFileStorageException
  */
 public function registerFiles(PortableElementObject $object, $files, $source)
 {
     $registered = false;
     $fileSystem = $this->getFileStorage();
     $source = $this->sanitizeSourceAsDirectory($source);
     foreach ($files as $file) {
         if (substr($file, 0, 2) != './' && !preg_match('/^' . $object->getTypeIdentifier() . '/', $file)) {
             // File is not relative, it's a shared libraries
             // Ignore this file, front have fallBack
             continue;
         }
         $filePath = $source . ltrim($file, DIRECTORY_SEPARATOR);
         if (!file_exists($filePath) || ($resource = fopen($filePath, 'r')) === false) {
             throw new PortableElementFileStorageException('File cannot be opened : ' . $filePath);
         }
         $fileId = $this->getPrefix($object) . preg_replace('/^' . $object->getTypeIdentifier() . '/', '.', $file);
         //Adjust file resource entries where {QTI_NS}/xxx/yyy.js is equivalent to ./xxx/yyy.js
         if ($fileSystem->has($fileId)) {
             $registered = $fileSystem->updateStream($fileId, $resource);
         } else {
             $registered = $fileSystem->writeStream($fileId, $resource);
         }
         fclose($resource);
         \common_Logger::i('Portable element asset file "' . $fileId . '" copied.');
     }
     return $registered;
 }
 /**
  * Create an temp export tree and return path
  *
  * @param PortableElementObject $object
  * @return string
  */
 protected function getZipLocation(PortableElementObject $object)
 {
     return \tao_helpers_Export::getExportPath() . DIRECTORY_SEPARATOR . 'pciPackage_' . $object->getTypeIdentifier() . '.zip';
 }
 /**
  * Replace the libs aliases with their relative url before saving into the registry
  * This format is consistent with the format of TAO portable package manifest
  *
  * @param PortableElementObject $object
  * @return PortableElementObject
  */
 private function replaceLibAliases(PortableElementObject $object)
 {
     $id = $object->getTypeIdentifier();
     $object->setRuntimeKey('libraries', array_map(function ($lib) use($id) {
         if (preg_match('/^' . $id . '/', $lib)) {
             return $lib . '.js';
         }
         return $lib;
     }, $object->getRuntimeKey('libraries')));
     return $object;
 }