/** * Deletes an asset * * @apiMethod POST * @apiUri /courses/asset/delete * @apiParameter { * "name": "asset_id", * "description": "ID of asset to delete", * "type": "integer", * "required": true, * "default": null * } * @apiParameter { * "name": "scope", * "description": "Asset scope", * "type": "string", * "required": true, * "default": null * } * @apiParameter { * "name": "scope_id", * "description": "Asset scope ID", * "type": "integer", * "required": true, * "default": null * } * @return void */ public function deleteTask() { // Require authentication and authorization $this->authorizeOrFail(); // First, delete the asset association $database = App::get('db'); $assocObj = new AssetAssociation($database); // Get vars $asset_id = Request::getInt('asset_id', 0); $scope = Request::getCmd('scope', 'asset_group'); $scope_id = Request::getInt('scope_id', 0); // Make sure we're not missing anything if (!$asset_id || !$scope || !$scope_id) { // Missing needed variables to identify asset association App::abort(404, 'Missing one of asset id, scope, or scope id'); } else { // Try to load the association if (!$assocObj->loadByAssetScope($asset_id, $scope_id, $scope)) { App::abort(500, 'Loading asset association failed'); } else { // Delete the association if (!$assocObj->delete()) { App::abort(500, $assocObj->getError()); } } } // Then, lookup whether or not there are other assocations connected to this asset $assetObj = new AssetTbl($database); if (!$assetObj->load($asset_id)) { App::abort(500, "Loading asset {$id} failed"); } // See if the asset is orphaned if (!$assetObj->isOrphaned()) { // Asset isn't an orphan (i.e. it's still being used elsewhere), so we're done $this->send(['asset_id' => $assetObj->id]); return; } // If no other associations exist, we'll delete the asset file and folder on the file system $deleted = []; $params = Component::params('com_courses'); $path = DS . trim($params->get('uploadpath', '/site/courses'), DS) . DS . $this->course_id . DS . $assetObj->id; // If the path exists, delete it! if (Filesystem::exists($path)) { $deleted = Filesystem::listFolderTree($path); Filesystem::deleteDirectory($path); } // Then we'll delete the asset entry itself if (!$assetObj->delete()) { App::abort(500, $assetObj->getError()); } // Return message $this->send(['asset_id' => $assetObj->id, 'deleted' => $deleted]); }
/** * Create method for this handler * * @return array of assets created **/ public function create() { // Include needed files require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'asset.association.php'; require_once dirname(dirname(__DIR__)) . DS . 'tables' . DS . 'asset.php'; require_once dirname(__DIR__) . DS . 'asset.php'; // Get the file if (isset($_FILES['files'])) { $file = $_FILES['files']['name'][0]; $size = (int) $_FILES['files']['size']; // Get the file extension $pathinfo = pathinfo($file); $filename = $pathinfo['filename']; $ext = $pathinfo['extension']; } else { return array('error' => 'No files provided'); } // @FIXME: should these come from the global settings, or should they be courses specific // Get config $config = Component::params('com_media'); // Max upload size $sizeLimit = (int) $config->get('upload_maxsize'); $sizeLimit = $sizeLimit * 1024 * 1024; // Check to make sure we have a file and its not too big if ($size == 0) { return array('error' => 'File is empty'); } if ($size > $sizeLimit) { $max = preg_replace('/<abbr \\w+=\\"\\w+\\">(\\w{1,3})<\\/abbr>/', '$1', \Hubzero\Utility\Number::formatBytes($sizeLimit)); return array('error' => "File is too large. Max file upload size is {$max}"); } // Create our asset table object $assetObj = new Tables\Asset($this->db); $this->asset['title'] = $filename; $this->asset['type'] = !empty($this->asset['type']) ? $this->asset['type'] : 'file'; $this->asset['subtype'] = !empty($this->asset['subtype']) ? $this->asset['subtype'] : 'file'; $this->asset['url'] = $file; $this->asset['created'] = Date::toSql(); $this->asset['created_by'] = App::get('authn')['user_id']; $this->asset['course_id'] = Request::getInt('course_id', 0); // Save the asset if (!$assetObj->save($this->asset)) { return array('error' => 'Asset save failed'); } // Create asset assoc object $assocObj = new Tables\AssetAssociation($this->db); $this->assoc['asset_id'] = $assetObj->get('id'); $this->assoc['scope'] = Request::getCmd('scope', 'asset_group'); $this->assoc['scope_id'] = Request::getInt('scope_id', 0); // Save the asset association if (!$assocObj->save($this->assoc)) { return array('error' => 'Asset association save failed'); } // Get courses config $cconfig = Component::params('com_courses'); // Build the upload path if it doesn't exist $uploadDirectory = PATH_APP . DS . trim($cconfig->get('uploadpath', '/site/courses'), DS) . DS . $this->asset['course_id'] . DS . $this->assoc['asset_id'] . DS; // Make sure upload directory exists and is writable if (!is_dir($uploadDirectory)) { if (!Filesystem::makeDirectory($uploadDirectory, 0755, true)) { return array('error' => 'Server error. Unable to create upload directory'); } } if (!is_writable($uploadDirectory)) { return array('error' => 'Server error. Upload directory isn\'t writable'); } // Get the final file path $target_path = $uploadDirectory . $filename . '.' . $ext; // Move the file to the site folder set_time_limit(60); // Scan for viruses if (!Filesystem::isSafe($_FILES['files']['tmp_name'][0])) { // Scan failed, delete asset and association and return an error $assetObj->delete(); $assocObj->delete(); Filesystem::deleteDirectory($uploadDirectory); return array('error' => 'File rejected because the anti-virus scan failed.'); } if (!($move = move_uploaded_file($_FILES['files']['tmp_name'][0], $target_path))) { // Move failed, delete asset and association and return an error $assetObj->delete(); $assocObj->delete(); Filesystem::deleteDirectory($uploadDirectory); return array('error' => 'Move file failed'); } // Get the url to return to the page $course_id = Request::getInt('course_id', 0); $offering_alias = Request::getCmd('offering', ''); $course = new \Components\Courses\Models\Course($course_id); $url = Route::url('index.php?option=com_courses&controller=offering&gid=' . $course->get('alias') . '&offering=' . $offering_alias . '&asset=' . $assetObj->get('id')); $url = rtrim(str_replace('/api', '', Request::root()), '/') . '/' . ltrim($url, '/'); $return_info = array('asset_id' => $this->assoc['asset_id'], 'asset_title' => $this->asset['title'], 'asset_type' => $this->asset['type'], 'asset_subtype' => $this->asset['subtype'], 'asset_url' => $url, 'course_id' => $this->asset['course_id'], 'offering_alias' => Request::getCmd('offering', ''), 'scope_id' => $this->assoc['scope_id'], 'asset_ext' => $ext, 'upload_path' => $uploadDirectory, 'target_path' => $target_path); // Return info return array('assets' => $return_info); }
/** * Unlink an asset from an object * * @return void */ public function unlinkTask() { // Check for request forgeries Request::checkToken(['get', 'post']); // Incoming $asset_id = Request::getInt('asset', 0); $tmpl = Request::getVar('tmpl', ''); $scope = Request::getVar('scope', 'asset_group'); $scope_id = Request::getInt('scope_id', 0); $course_id = Request::getInt('course_id', 0); // Load association $tbl = new Tables\AssetAssociation($this->database); $tbl->loadByAssetScope($asset_id, $scope_id, $scope); // Remove association if (!$tbl->delete()) { $this->setError($tbl->getError()); } $model = new \Components\Courses\Models\Asset($asset_id); // Is this asset linked anywhere else? if ($model->parents(array('count' => true)) <= 0) { // No -- Asset no longer used. Delete it. if (!$model->delete()) { $this->setError($model->delete()); } } App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller . '&tmpl=' . $tmpl . '&scope=' . $scope . '&scope_id=' . $scope_id . '&course_id=' . $course_id, false), $this->getError() ? $this->getError() : null, $this->getError() ? 'error' : 'message'); }