_helper->getHelper('AjaxContext'); $ajaxContext->addActionContext('upload', 'json') ->addActionContext('recent-uploads', 'json') ->initContext(); } public function indexAction() { $CC_CONFIG = Config::getConfig(); $baseUrl = Application_Common_OsPath::getBaseDir(); $locale = Application_Model_Preference::GetLocale(); $this->view->headScript()->appendFile($baseUrl.'js/datatables/js/jquery.dataTables.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/plupload/plupload.full.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/plupload/jquery.plupload.queue.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/plupload.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/plupload/i18n/'.$locale.'.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/libs/dropzone.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headLink()->appendStylesheet($baseUrl.'css/plupload.queue.css?'.$CC_CONFIG['airtime_version']); $this->view->headLink()->appendStylesheet($baseUrl.'css/addmedia.css?'.$CC_CONFIG['airtime_version']); $this->view->headLink()->appendStylesheet($baseUrl.'css/dashboard.css?'.$CC_CONFIG['airtime_version']); $this->view->quotaLimitReached = false; if (Application_Model_Systemstatus::isDiskOverQuota()) { $this->view->quotaLimitReached = true; } //Because uploads are done via AJAX (and we're not using Zend form for those), we manually add the CSRF //token in here. $csrf_namespace = new Zend_Session_Namespace('csrf_namespace'); //The CSRF token is generated in Bootstrap.php $csrf_element = new Zend_Form_Element_Hidden('csrf'); $csrf_element->setValue($csrf_namespace->authtoken)->setRequired('true')->removeDecorator('HtmlTag')->removeDecorator('Label'); $csrf_form = new Zend_Form(); $csrf_form->addElement($csrf_element); $this->view->form = $csrf_form; // get max upload files size in MiB for plupload js. $uploadMaxSize = $this->file_upload_max_size() / 1024 / 1024; if ($uploadMaxSize === 0) { // fall back to old default behaviour if unlimited uploads are // configured on the server side. $uploadMaxSize = 500; } $this->view->uploadMaxSize = $uploadMaxSize; } public function uploadAction() { $current_namespace = new Zend_Session_Namespace('csrf_namespace'); $observed_csrf_token = $this->_getParam('csrf_token'); $expected_csrf_token = $current_namespace->authtoken; if($observed_csrf_token == $expected_csrf_token){ $upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload"; $tempFilePath = Application_Model_StoredFile::uploadFile($upload_dir); $tempFileName = basename($tempFilePath); $this->_helper->json->sendJson(array("jsonrpc" => "2.0", "tempfilepath" => $tempFileName)); }else{ $this->_helper->json->sendJson(array("jsonrpc" => "2.0", "valid" => false, "error" => "CSRF token did not match.")); } } public function recentUploadsAction() { $request = $this->getRequest(); $filter = $request->getParam('uploadFilter', "all"); $limit = intval($request->getParam('iDisplayLength', 10)); $rowStart = intval($request->getParam('iDisplayStart', 0)); $recentUploadsQuery = CcFilesQuery::create(); //old propel 1.5 to reuse this query item (for counts/finds) $recentUploadsQuery->keepQuery(true); //Hide deleted files $recentUploadsQuery->filterByDbFileExists(true); $numTotalRecentUploads = $recentUploadsQuery->count(); $numTotalDisplayUploads = $numTotalRecentUploads; if ($filter == "pending") { $recentUploadsQuery->filterByDbImportStatus(1); $numTotalDisplayUploads = $recentUploadsQuery->count(); } else if ($filter == "failed") { $recentUploadsQuery->filterByDbImportStatus(2); $numTotalDisplayUploads = $recentUploadsQuery->count(); //TODO: Consider using array('min' => 200)) or something if we have multiple errors codes for failure. } $recentUploads = $recentUploadsQuery ->orderByDbUtime(Criteria::DESC) ->offset($rowStart) ->limit($limit) ->find(); $uploadsArray = array(); $utcTimezone = new DateTimeZone("UTC"); $displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone()); foreach ($recentUploads as $upload) { $upload = $upload->toArray(BasePeer::TYPE_FIELDNAME); //TODO: $this->sanitizeResponse($upload)); $upload['utime'] = new DateTime($upload['utime'], $utcTimezone); $upload['utime']->setTimeZone($displayTimezone); $upload['utime'] = $upload['utime']->format(DEFAULT_TIMESTAMP_FORMAT); //TODO: Invoke sanitization here (MediaController's removeBlacklist stuff) array_push($uploadsArray, $upload); } $this->view->sEcho = intval($request->getParam('sEcho')); $this->view->iTotalDisplayRecords = $numTotalDisplayUploads; $this->view->iTotalRecords = $numTotalRecentUploads; $this->view->files = SecurityHelper::htmlescape_recursive($uploadsArray); } /** * get configured upload max size from php * * Pinched from Drupal: https://github.com/drupal/drupal/blob/4204b0b29a7318008f10765cf88114bf3ed21c32/core/includes/file.inc#L1099 * * Drupal seems to be the only framework that does this somewhat the right * way. I'm adding the method here since it's part of their core and I did * not find an easy way to grab that thrrough composer in an isolated way. */ private function file_upload_max_size() { static $max_size = -1; if ($max_size < 0) { // Start with post_max_size. $max_size = $this->bytes_to_int(ini_get('post_max_size')); // If upload_max_size is less, then reduce. Except if upload_max_size is // zero, which indicates no limit. $upload_max = $this->bytes_to_int(ini_get('upload_max_filesize')); if ($upload_max > 0 && $upload_max < $max_size) { $max_size = $upload_max; } } return $max_size; } /** * Pinched from Drupal: https://github.com/drupal/drupal/blob/4204b0b29a7318008f10765cf88114bf3ed21c32/core/lib/Drupal/Component/Utility/Bytes.php#L27 * * This is the real point of importing the Drupal solution. They have done * an implementation for figuring out what the user specified in the * post_max_size and upload_max_size configuration. Sadly php does not * support a nice way to get at the results of this config after it is * parsed by the engine, hence the below hack. */ private function bytes_to_int($size) { // Remove the non-unit characters from the size. $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-numeric characters from the size. $size = preg_replace('/[^0-9\.]/', '', $size); if ($unit) { // Find the position of the unit in the ordered string which is the power // of magnitude to multiply a kilobyte by. return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); } else { return round($size); } } }