diff --git a/api_application/controllers/Files.php b/api_application/controllers/Files.php index 4279fda..ccb3956 100644 --- a/api_application/controllers/Files.php +++ b/api_application/controllers/Files.php @@ -1,1125 +1,1140 @@ . **/ class Files extends BaseController { public function getIndex() { $originId = null; $status = 'active'; $clientId = null; $ownerId = null; $collectionId = null; $collectionStatus = 'active'; $collectionCategory = null; $collectionTags = null; // Comma-separated list $collectionContentId = null; $types = null; // Comma-separated list $category = null; $tags = null; // Comma-separated list $ocsCompatibility = 'all'; $contentId = null; $search = null; // 3 or more strings $ids = null; // Comma-separated list $favoriteIds = array(); $downloadedTimeperiodBegin = null; // Datetime format $downloadedTimeperiodEnd = null; // Datetime format $sort = 'name'; $perpage = $this->appConfig->general['perpage']; $page = 1; if (!empty($this->request->origin_id)) { $originId = $this->request->origin_id; } if (!empty($this->request->status)) { $status = $this->request->status; } if (!empty($this->request->client_id)) { $clientId = $this->request->client_id; } if (!empty($this->request->owner_id)) { $ownerId = $this->request->owner_id; } if (!empty($this->request->collection_id)) { $collectionId = $this->request->collection_id; } if (!empty($this->request->collection_status)) { $collectionStatus = $this->request->collection_status; } if (isset($this->request->collection_category)) { $collectionCategory = $this->request->collection_category; } if (isset($this->request->collection_tags)) { $collectionTags = $this->request->collection_tags; } if (isset($this->request->collection_content_id)) { $collectionContentId = $this->request->collection_content_id; } if (!empty($this->request->types)) { $types = $this->request->types; } if (isset($this->request->category)) { $category = $this->request->category; } if (isset($this->request->tags)) { $tags = $this->request->tags; } if (!empty($this->request->ocs_compatibility)) { $ocsCompatibility = $this->request->ocs_compatibility; } if (isset($this->request->content_id)) { $contentId = $this->request->content_id; } if (!empty($this->request->search)) { $search = $this->request->search; } if (!empty($this->request->ids)) { $ids = $this->request->ids; } if (!empty($this->request->client_id) && !empty($this->request->favoritesby) ) { $favoriteIds = $this->_getFavoriteIds( $this->request->client_id, $this->request->favoritesby ); if (!$favoriteIds) { $this->response->setStatus(404); throw new Flooer_Exception('Not found', LOG_NOTICE); } } if (!empty($this->request->downloaded_timeperiod_begin)) { $downloadedTimeperiodBegin = $this->request->downloaded_timeperiod_begin; } if (!empty($this->request->downloaded_timeperiod_end)) { $downloadedTimeperiodEnd = $this->request->downloaded_timeperiod_end; } if (!empty($this->request->sort)) { $sort = $this->request->sort; } if (!empty($this->request->perpage) && $this->_isValidPerpageNumber($this->request->perpage) ) { $perpage = $this->request->perpage; } if (!empty($this->request->page) && $this->_isValidPageNumber($this->request->page) ) { $page = $this->request->page; } $files = $this->models->files->getFiles( $originId, $status, $clientId, $ownerId, $collectionId, $collectionStatus, $collectionCategory, $collectionTags, $collectionContentId, $types, $category, $tags, $ocsCompatibility, $contentId, $search, $ids, $favoriteIds, $downloadedTimeperiodBegin, $downloadedTimeperiodEnd, $sort, $perpage, $page ); if (!$files) { $this->response->setStatus(404); throw new Flooer_Exception('Not found', LOG_NOTICE); } $this->_setResponseContent('success', $files); } public function getFile() { $id = null; if (!empty($this->request->id)) { $id = $this->request->id; } $file = $this->models->files->getFile($id); if (!$file) { $this->response->setStatus(404); throw new Flooer_Exception('Not found', LOG_NOTICE); } $this->_setResponseContent( 'success', array('file' => $file) ); } public function postFile() { if (!$this->_isAllowedAccess()) { $this->response->setStatus(403); throw new Flooer_Exception('Forbidden', LOG_NOTICE); } $id = null; // Auto generated $originId = null; // Auto generated $active = 1; $clientId = null; $ownerId = null; $collectionId = null; $name = null; // Auto generated $type = null; // Auto detect $size = null; // Auto detect $title = null; // Name as default $description = null; $category = null; $tags = null; // Comma-separated list $version = null; $ocsCompatible = 1; $contentId = null; $contentPage = null; $downloadedCount = 0; // for hive files importing (Deprecated) if (!empty($this->request->client_id)) { $clientId = $this->request->client_id; } if (!empty($this->request->owner_id)) { $ownerId = $this->request->owner_id; } if (!empty($this->request->collection_id)) { $collectionId = $this->request->collection_id; } if (isset($this->request->tags)) { $tags = strip_tags($this->request->tags); } if (isset($_FILES['file'])) { if (!empty($_FILES['file']['name'])) { $name = mb_substr(strip_tags(basename($_FILES['file']['name'])), 0, 200); } if (!empty($_FILES['file']['tmp_name'])) { $finfo = new finfo(FILEINFO_MIME_TYPE); $type = $finfo->file($_FILES['file']['tmp_name']); if (!$type) { $type = 'application/octet-stream'; } } if (!empty($_FILES['file']['size'])) { $size = $_FILES['file']['size']; } } // for hive files importing (Deprecated) ---------- else if (isset($this->request->local_file_path)) { if (!empty($this->request->local_file_path)) { $name = mb_substr(strip_tags(basename($this->request->local_file_path)), 0, 200); $externalUri = $this->_detectLinkInTags($tags); if ($name == 'empty' && !empty($externalUri)) { $type = $this->_detectMimeTypeFromUri($externalUri); $size = $this->_detectFilesizeFromUri($externalUri); } else { $finfo = new finfo(FILEINFO_MIME_TYPE); $type = $finfo->file($this->request->local_file_path); if (!$type) { $type = 'application/octet-stream'; } $size = filesize($this->request->local_file_path); } } if (!empty($this->request->local_file_name)) { $name = mb_substr(strip_tags(basename($this->request->local_file_name)), 0, 200); } } // ------------------------------------------------ if (!empty($this->request->title)) { $title = mb_substr(strip_tags($this->request->title), 0, 200); } if (isset($this->request->description)) { $description = strip_tags($this->request->description); } if (isset($this->request->category)) { $category = mb_substr(strip_tags($this->request->category), 0, 64); } if (isset($this->request->version)) { $version = mb_substr(strip_tags($this->request->version), 0, 64); } if (isset($this->request->ocs_compatible)) { if ($this->request->ocs_compatible == 1) { $ocsCompatible = 1; } else if ($this->request->ocs_compatible == 0) { $ocsCompatible = 0; } } if (isset($this->request->content_id)) { $contentId = $this->request->content_id; } if (!empty($this->request->content_page)) { $contentPage = $this->request->content_page; } // for hive files importing (Deprecated) ---------- if (!empty($this->request->downloaded_count)) { $downloadedCount = intval($this->request->downloaded_count); } // ------------------------------------------------ $errors = array(); if (!$clientId) { $errors['client_id'] = 'Required'; } if (!$ownerId) { $errors['owner_id'] = 'Required'; } /* if (!isset($_FILES['file'])) { $errors['file'] = 'Required'; } else if (!empty($_FILES['file']['error'])) { // 0 = UPLOAD_ERR_OK $errors['file'] = $_FILES['file']['error']; } */ // for hive files importing (Deprecated) ---------- if (!isset($_FILES['file']) && !isset($this->request->local_file_path)) { $errors['file'] = 'Required'; } if (isset($_FILES['file']) && !empty($_FILES['file']['error'])) { // 0 = UPLOAD_ERR_OK $errors['file'] = $_FILES['file']['error']; } // ------------------------------------------------ if ($errors) { $this->response->setStatus(400); $this->_setResponseContent( 'error', array( 'message' => 'Validation error', 'errors' => $errors ) ); return; } // Get ID3 tags in the file $id3Tags = $this->_getId3Tags($type, $_FILES['file']['tmp_name']); // Prepare to append the file to collection $collectionName = null; $collectionData = array(); if ($collectionId) { // Get specified collection $collection = $this->models->collections->$collectionId; if (!$collection || $collection->client_id != $clientId || $collection->owner_id != $ownerId ) { $this->response->setStatus(403); throw new Flooer_Exception('Forbidden', LOG_NOTICE); } $collectionName = $collection->name; $collectionData = array( 'files' => $collection->files + 1, 'size' => $collection->size + $size ); } else { // Prepare new collection $collectionId = $this->models->collections->generateId(); $collectionActive = 1; $collectionName = $collectionId; $collectionTitle = $collectionName; $collectionDescription = null; $collectionCategory = null; $collectionTags = null; $collectionVersion = null; $collectionContentId = null; $collectionContentPage = null; if (!is_dir($this->appConfig->general['filesDir'] . '/' . $collectionName) && !mkdir($this->appConfig->general['filesDir'] . '/' . $collectionName) ) { $this->response->setStatus(500); throw new Flooer_Exception('Failed to create collection', LOG_ALERT); } $collectionData = array( 'active' => $collectionActive, 'client_id' => $clientId, 'owner_id' => $ownerId, 'name' => $collectionName, 'files' => 1, 'size' => $size, 'title' => $collectionTitle, 'description' => $collectionDescription, 'category' => $collectionCategory, 'tags' => $collectionTags, 'version' => $collectionVersion, 'content_id' => $collectionContentId, 'content_page' => $collectionContentPage ); } $id = $this->models->files->generateId(); $originId = $id; $name = $this->_fixFilename($name, $collectionName); if (!$title) { $title = $name; } // Save the uploaded file if (isset($_FILES['file'])) { try { move_uploaded_file( $_FILES['file']['tmp_name'], $this->appConfig->general['filesDir'] . '/' . $collectionName . '/' . $name ); } catch (Exception $exc) { //try to change owner try { $this->log->log("Set new rights", LOG_NOTICE); $output = shell_exec('/opt/php_root /opt/repair.sh '.$collectionName); // Log $this->log->log("Set new rights Done: ".$output, LOG_NOTICE); } catch (Exception $exc) { echo $exc->getTraceAsString(); } if (!move_uploaded_file( $_FILES['file']['tmp_name'], $this->appConfig->general['filesDir'] . '/' . $collectionName . '/' . $name )) { $this->response->setStatus(500); throw new Flooer_Exception('Failed to save the file', LOG_ALERT); } } /* if (!move_uploaded_file( $_FILES['file']['tmp_name'], $this->appConfig->general['filesDir'] . '/' . $collectionName . '/' . $name )) { $this->response->setStatus(500); throw new Flooer_Exception('Failed to save the file', LOG_ALERT); }*/ } // for hive files importing (Deprecated) ---------- else if (isset($this->request->local_file_path)) { try { copy( $this->request->local_file_path, $this->appConfig->general['filesDir'] . '/' . $collectionName . '/' . $name ); } catch (Exception $exc) { //try to change owner try { $this->log->log("Set new rights", LOG_NOTICE); $output = shell_exec('/opt/php_root /opt/repair.sh '.$collectionName); // Log $this->log->log("Set new rights Done: ".$output, LOG_NOTICE); } catch (Exception $exc) { echo $exc->getTraceAsString(); } if (!copy( $this->request->local_file_path, $this->appConfig->general['filesDir'] . '/' . $collectionName . '/' . $name )) { $this->response->setStatus(500); throw new Flooer_Exception('Failed to save the file', LOG_ALERT); } } /* if (!copy( $this->request->local_file_path, $this->appConfig->general['filesDir'] . '/' . $collectionName . '/' . $name )) { $this->response->setStatus(500); throw new Flooer_Exception('Failed to save the file', LOG_ALERT); }*/ } // ------------------------------------------------ // Add/Update the collection $this->models->collections->$collectionId = $collectionData; // Add the file $this->models->files->$id = array( 'origin_id' => $originId, 'active' => $active, 'client_id' => $clientId, 'owner_id' => $ownerId, 'collection_id' => $collectionId, 'name' => $name, 'type' => $type, 'size' => $size, 'title' => $title, 'description' => $description, 'category' => $category, 'tags' => $tags, 'version' => $version, 'ocs_compatible' => $ocsCompatible, 'content_id' => $contentId, 'content_page' => $contentPage, 'downloaded_count' => $downloadedCount // for hive files importing (Deprecated) ); // Add the media if ($id3Tags) { $this->_addMedia($id3Tags, $clientId, $ownerId, $collectionId, $id, $name); } $file = $this->models->files->getFile($id); $this->_setResponseContent( 'success', array('file' => $file) ); } public function putFile() { if (!$this->_isAllowedAccess()) { $this->response->setStatus(403); throw new Flooer_Exception('Forbidden', LOG_NOTICE); } $id = null; $title = null; $description = null; $category = null; $tags = null; // Comma-separated list $version = null; $ocsCompatible = null; $contentId = null; $contentPage = null; if (!empty($this->request->id)) { $id = $this->request->id; } if (!empty($this->request->title)) { $title = mb_substr(strip_tags($this->request->title), 0, 200); } if (isset($this->request->description)) { $description = strip_tags($this->request->description); } if (isset($this->request->category)) { $category = mb_substr(strip_tags($this->request->category), 0, 64); } if (isset($this->request->tags)) { $tags = strip_tags($this->request->tags); } if (isset($this->request->version)) { $version = mb_substr(strip_tags($this->request->version), 0, 64); } if (isset($this->request->ocs_compatible)) { if ($this->request->ocs_compatible == 1) { $ocsCompatible = 1; } else if ($this->request->ocs_compatible == 0) { $ocsCompatible = 0; } } if (isset($this->request->content_id)) { $contentId = $this->request->content_id; } if (!empty($this->request->content_page)) { $contentPage = $this->request->content_page; } $file = $this->models->files->$id; if (!$file) { $this->response->setStatus(404); throw new Flooer_Exception('Not found', LOG_NOTICE); } else if (!$file->active || $file->client_id != $this->request->client_id) { $this->response->setStatus(403); throw new Flooer_Exception('Forbidden', LOG_NOTICE); } // If new file has uploaded, // remove old file and replace to the new file with new file id if (isset($_FILES['file'])) { $id = null; $originId = $file->origin_id; $active = 1; $clientId = $file->client_id; $ownerId = $file->owner_id; $collectionId = $file->collection_id; $name = null; // Auto generated $type = null; // Auto detect $size = null; // Auto detect $downloadedCount = 0; // for hive files importing (Deprecated) if (!empty($_FILES['file']['name'])) { $name = mb_substr(strip_tags(basename($_FILES['file']['name'])), 0, 200); } if (!empty($_FILES['file']['tmp_name'])) { $finfo = new finfo(FILEINFO_MIME_TYPE); $type = $finfo->file($_FILES['file']['tmp_name']); if (!$type) { $type = 'application/octet-stream'; } } if (!empty($_FILES['file']['size'])) { $size = $_FILES['file']['size']; } if ($description === null) { $description = $file->description; } if ($category === null) { $category = $file->category; } if ($tags === null) { $tags = $file->tags; } if ($version === null) { $version = $file->version; } if ($ocsCompatible === null) { $ocsCompatible = $file->ocs_compatible; } if ($contentId === null) { $contentId = $file->content_id; } if ($contentPage === null) { $contentPage = $file->content_page; } $errors = array(); if (!empty($_FILES['file']['error'])) { // 0 = UPLOAD_ERR_OK $errors['file'] = $_FILES['file']['error']; } if ($errors) { $this->response->setStatus(400); $this->_setResponseContent( 'error', array( 'message' => 'File upload error', 'errors' => $errors ) ); return; } // Remove old file $this->_removeFile($file); // Get ID3 tags in the file $id3Tags = $this->_getId3Tags($type, $_FILES['file']['tmp_name']); // Prepare to append the file to collection $collection = $this->models->collections->$collectionId; $collectionName = $collection->name; $collectionData = array( 'files' => $collection->files + 1, 'size' => $collection->size + $size ); $id = $this->models->files->generateId(); $name = $this->_fixFilename($name, $collectionName); if (!$title) { $title = $name; } // Save the uploaded file if (!move_uploaded_file( $_FILES['file']['tmp_name'], $this->appConfig->general['filesDir'] . '/' . $collectionName . '/' . $name )) { $this->response->setStatus(500); throw new Flooer_Exception('Failed to save the file', LOG_ALERT); } // Add the file $this->models->files->$id = array( 'origin_id' => $originId, 'active' => $active, 'client_id' => $clientId, 'owner_id' => $ownerId, 'collection_id' => $collectionId, 'name' => $name, 'type' => $type, 'size' => $size, 'title' => $title, 'description' => $description, 'category' => $category, 'tags' => $tags, 'version' => $version, 'ocs_compatible' => $ocsCompatible, 'content_id' => $contentId, 'content_page' => $contentPage, 'downloaded_count' => $downloadedCount // for hive files importing (Deprecated) ); // Update the collection $this->models->collections->$collectionId = $collectionData; // Add the media if ($id3Tags) { $this->_addMedia($id3Tags, $clientId, $ownerId, $collectionId, $id, $name); } } // Update only file information else { $updata = array(); if ($title !== null) { $updata['title'] = $title; } if ($description !== null) { $updata['description'] = $description; } if ($category !== null) { $updata['category'] = $category; } if ($tags !== null) { $updata['tags'] = $tags; } if ($version !== null) { $updata['version'] = $version; } if ($ocsCompatible !== null) { $updata['ocs_compatible'] = $ocsCompatible; } if ($contentId !== null) { $updata['content_id'] = $contentId; } if ($contentPage !== null) { $updata['content_page'] = $contentPage; } $this->models->files->$id = $updata; } $file = $this->models->files->getFile($id); $this->_setResponseContent( 'success', array('file' => $file) ); } public function deleteFile() { if (!$this->_isAllowedAccess()) { $this->response->setStatus(403); throw new Flooer_Exception('Forbidden', LOG_NOTICE); } $id = null; if (!empty($this->request->id)) { $id = $this->request->id; } $file = $this->models->files->$id; if (!$file) { $this->response->setStatus(404); throw new Flooer_Exception('Not found', LOG_NOTICE); } else if (!$file->active || $file->client_id != $this->request->client_id) { $this->response->setStatus(403); throw new Flooer_Exception('Forbidden', LOG_NOTICE); } $this->_removeFile($file); $this->_setResponseContent('success'); } public function headDownloadfile() // Deprecated { // This is alias for HEAD /files/download $this->headDownload(); } public function getDownloadfile($headeronly = false) // Deprecated { // This is alias for GET /files/download $this->getDownload($headeronly); } public function headDownload() { $this->getDownload(true); } public function getDownload($headeronly = false) { $id = null; $as = null; $userId = null; $hashGiven = null; $timestamp = null; $isFromOcsApi = false; $isFilepreview = false; $linkType = null; if (!empty($this->request->id)) { $id = $this->request->id; } if (!empty($this->request->as)) { $as = $this->request->as; } if (!empty($this->request->u)) { $userId = $this->request->u; } if (!empty($this->request->s)) { $hashGiven = $this->request->s; } if (!empty($this->request->t)) { $timestamp = $this->request->t; } if (!empty($this->request->o)) { $isFromOcsApi = ($this->request->o == 1); } if (!empty($this->request->lt)) { $linkType = $this->request->lt; if($linkType === 'filepreview') { $isFilepreview = true; } } if ($id && $as) { $id = $this->models->files->getFileId($id, $as); } $file = $this->models->files->$id; if (!$file) { $this->response->setStatus(404); throw new Flooer_Exception('Not found', LOG_NOTICE); } $collectionId = $file->collection_id; // Check link if it is expired or old style $salt = $this->_getDownloadSecret($file->client_id); //20181009 ronald: change hash from MD5 to SHA512 //$hash = md5($salt . $collectionId . $timestamp); $hash = hash('sha512',$salt . $collectionId . $timestamp); $now = time(); $div = ($timestamp - $now); // Log $this->log->log("Start Download (client: $file->client_id; salt: $salt; hash: $hash; hashGiven: $hashGiven)", LOG_NOTICE); //Save downloads, but not for perview downloads if(!$isFilepreview) { if($isFromOcsApi) { $data = array( 'client_id' => $file->client_id, 'owner_id' => $file->owner_id, 'collection_id' => $file->collection_id, 'file_id' => $file->id, 'user_id' => $userId, 'referer' => 'OCS-API', 'source' => 'OCS-API' ); } else { $data = array( 'client_id' => $file->client_id, 'owner_id' => $file->owner_id, 'collection_id' => $file->collection_id, 'file_id' => $file->id, 'user_id' => $userId, 'source' => 'OCS-Webserver', 'link_type' => $linkType, 'referer' => null ); } try { //$downloadedId = $this->models->files_downloaded_all->generateId(); $downloadedId = $this->models->files_downloaded_all->generateNewId(); $ref = 'OCS-API'; $this->models->files_downloaded_all->$downloadedId = $data; } catch (Exception $exc) { //echo $exc->getTraceAsString(); $this->log->log("ERROR saving Download Data to DB: $exc->getTraceAsString()", LOG_ERR); } } if ($as || $isFromOcsApi || $isFilepreview || ($hashGiven == $hash && $div > 0)) { // Link is ok, go on $collection = $this->models->collections->$collectionId; $collectionDir = ''; if ($collection->active) { $collectionDir = $this->appConfig->general['filesDir'] . '/' . $collection->name; } else { $collectionDir = $this->appConfig->general['filesDir'] . '/.trash/' . $collection->id . '-' . $collection->name; } $filePath = ''; if ($file->active) { $filePath = $collectionDir . '/' . $file->name; } else { $filePath = $collectionDir . '/.trash/' . $file->id . '-' . $file->name; } $fileName = $file->name; $fileType = $file->type; $fileSize = $file->size; // If request URI ended with .zsync, make a response data as zsync data if (strtolower(substr($this->request->getUri(), -6)) == '.zsync') { // But don't make zsync for external URI if (!empty($this->_detectLinkInTags($file->tags))) { $this->response->setStatus(404); throw new Flooer_Exception('Not found', LOG_NOTICE); } $zsyncPath = $this->appConfig->general['zsyncDir'] . '/' . $file->id . '.zsync'; if (!is_file($zsyncPath)) { $this->_generateZsync($filePath, $zsyncPath, $fileName); } $filePath = $zsyncPath; $fileName .= '.zsync'; $fileType = 'application/x-zsync'; $fileSize = filesize($zsyncPath); } else { if (!$isFilepreview && !$headeronly && $file->downloaded_ip != $this->server->REMOTE_ADDR) { $this->models->files->updateDownloadedStatus($file->id); try { //$downloadedId = $this->models->files_downloaded->generateId(); $downloadedId = $this->models->files_downloaded->generateNewId(); $ref = null; if ($isFromOcsApi) { $ref = 'OCS-API'; } $this->models->files_downloaded->$downloadedId = array( 'client_id' => $file->client_id, 'owner_id' => $file->owner_id, 'collection_id' => $file->collection_id, 'file_id' => $file->id, 'user_id' => $userId, 'referer' => $ref ); + + //save unique dataset + $downloadedId = $this->models->files_downloaded_unique->generateNewId(); + $ref = null; + if ($isFromOcsApi) { + $ref = 'OCS-API'; + } + $this->models->files_downloaded_unique->$downloadedId = array( + 'client_id' => $file->client_id, + 'owner_id' => $file->owner_id, + 'collection_id' => $file->collection_id, + 'file_id' => $file->id, + 'user_id' => $userId, + 'referer' => $ref + ); } catch (Exception $exc) { //echo $exc->getTraceAsString(); $this->log->log("ERROR saving Download Data to DB: $exc->getMessage()", LOG_ERR); } } // If external URI has set, redirect to it $externalUri = $this->_detectLinkInTags($file->tags); if (!empty($externalUri)) { $this->response->redirect($externalUri); } } $this->_sendFile( $filePath, $fileName, $fileType, $fileSize, true, $headeronly ); } else { // Link is not ok // Log $this->log->log("Start Download failed (file: $file->id; time-div: $div; client: $file->client_id; salt: $salt; hash: $hash; hashGiven: $hashGiven)", LOG_NOTICE); // Redirect to opendesktop project page $this->response->redirect($this->appConfig->general['redirectTargetServer'] . '/co/' . $collectionId); } } private function _fixFilename($name, $collectionName) { if (is_file($this->appConfig->general['filesDir'] . '/' . $collectionName . '/' . $name)) { $fix = date('YmdHis'); if (preg_match("/^([^.]+)(\..+)/", $name, $matches)) { $name = $matches[1] . '-' . $fix . $matches[2]; } else { $name = $name . '-' . $fix; } } return $name; } private function _removeFile(Flooer_Db_Table_Row &$file) { // Please be care the remove process in Collections::deleteCollection() $id = $file->id; $collectionId = $file->collection_id; $collection = $this->models->collections->$collectionId; $trashDir = $this->appConfig->general['filesDir'] . '/' . $collection->name . '/.trash'; if (!is_dir($trashDir) && !mkdir($trashDir)) { $this->response->setStatus(500); throw new Flooer_Exception('Failed to remove the file', LOG_ALERT); } if (is_file($this->appConfig->general['filesDir'] . '/' . $collection->name . '/' . $file->name) && !rename( $this->appConfig->general['filesDir'] . '/' . $collection->name . '/' . $file->name, $trashDir . '/' . $id . '-' . $file->name ) ) { $this->response->setStatus(500); throw new Flooer_Exception('Failed to remove the file', LOG_ALERT); } $this->models->files->$id = array('active' => 0); //$this->models->files_downloaded->deleteByFileId($id); $this->models->favorites->deleteByFileId($id); $this->models->media->deleteByFileId($id); $this->models->media_played->deleteByFileId($id); $this->models->collections->$collectionId = array( 'files' => $collection->files - 1, 'size' => $collection->size - $file->size ); } private function _getId3Tags($filetype, $filepath) { // NOTE: getid3 may not work for a files in a network storage. $id3Tags = null; if (strpos($filetype, 'audio/') !== false || strpos($filetype, 'video/') !== false || strpos($filetype, 'application/ogg') !== false ) { require_once 'getid3/getid3.php'; $getID3 = new getID3(); $id3Tags = $getID3->analyze($filepath); getid3_lib::CopyTagsToComments($id3Tags); } return $id3Tags; } private function _addMedia(array $id3Tags, $clientId, $ownerId, $collectionId, $fileId, $defaultTitle) { // Get artist id or add new one $artistName = 'Unknown'; if (isset($id3Tags['comments']['artist'][0]) && $id3Tags['comments']['artist'][0] != '' ) { $artistName = mb_substr(strip_tags($id3Tags['comments']['artist'][0]), 0, 255); } $artistId = $this->models->media_artists->getId($clientId, $artistName); if (!$artistId) { $artistId = $this->models->media_artists->generateId(); $this->models->media_artists->$artistId = array( 'client_id' => $clientId, 'name' => $artistName ); } // Get album id or add new one $albumName = 'Unknown'; if (isset($id3Tags['comments']['album'][0]) && $id3Tags['comments']['album'][0] != '' ) { $albumName = mb_substr(strip_tags($id3Tags['comments']['album'][0]), 0, 255); } $albumId = $this->models->media->getAlbumId($clientId, $artistName, $albumName); if (!$albumId) { $albumId = $this->models->media_albums->generateId(); $this->models->media_albums->$albumId = array( 'client_id' => $clientId, 'name' => $albumName ); } // Add the media $mediaData = array( 'client_id' => $clientId, 'owner_id' => $ownerId, 'collection_id' => $collectionId, 'file_id' => $fileId, 'artist_id' => $artistId, 'album_id' => $albumId, 'title' => $defaultTitle, 'genre' => null, 'track' => null, 'creationdate' => null, 'bitrate' => 0, 'playtime_seconds' => 0, 'playtime_string' => 0 ); if (isset($id3Tags['comments']['title'][0]) && $id3Tags['comments']['title'][0] != '' ) { $mediaData['title'] = mb_substr(strip_tags($id3Tags['comments']['title'][0]), 0, 255); } if (!empty($id3Tags['comments']['genre'][0])) { $mediaData['genre'] = mb_substr(strip_tags($id3Tags['comments']['genre'][0]), 0, 64); } if (!empty($id3Tags['comments']['track_number'][0])) { $mediaData['track'] = mb_substr(strip_tags($id3Tags['comments']['track_number'][0]), 0, 5); } if (!empty($id3Tags['comments']['creationdate'][0])) { $mediaData['creationdate'] = mb_substr(strip_tags($id3Tags['comments']['creationdate'][0]), 0, 4); } if (!empty($id3Tags['bitrate'])) { $mediaData['bitrate'] = mb_substr(strip_tags($id3Tags['bitrate']), 0, 11); } if (!empty($id3Tags['playtime_seconds'])) { $mediaData['playtime_seconds'] = mb_substr(strip_tags($id3Tags['playtime_seconds']), 0, 11); } if (!empty($id3Tags['playtime_string'])) { $mediaData['playtime_string'] = mb_substr(strip_tags($id3Tags['playtime_string']), 0, 8); } $mediaId = $this->models->media->generateId(); $this->models->media->$mediaId = $mediaData; // Save the album cover if (!empty($id3Tags['comments']['picture'][0]['data'])) { $image = imagecreatefromstring($id3Tags['comments']['picture'][0]['data']); if ($image !== false) { imagejpeg($image, $this->appConfig->general['thumbnailsDir'] . '/album_' . $albumId . '.jpg', 75); imagedestroy($image); } } } } diff --git a/api_application/models/ModelContainer.php b/api_application/models/ModelContainer.php index dbd9ccb..655b7c1 100644 --- a/api_application/models/ModelContainer.php +++ b/api_application/models/ModelContainer.php @@ -1,291 +1,309 @@ . **/ require_once 'models/table_profiles.php'; require_once 'models/table_collections.php'; require_once 'models/table_collections_downloaded.php'; require_once 'models/table_files.php'; require_once 'models/table_files_downloaded.php'; require_once 'models/table_files_downloaded_all.php'; +require_once 'models/table_files_downloaded_unique.php'; require_once 'models/table_favorites.php'; require_once 'models/table_media.php'; require_once 'models/table_media_artists.php'; require_once 'models/table_media_albums.php'; require_once 'models/table_media_played.php'; class ModelContainer { protected $_db = null; protected $_config = array( 'createTables' => true ); public $profiles = null; public $collections = null; public $collections_downloaded = null; public $files = null; public $files_downloaded = null; public $files_downloaded_all = null; + + public $files_downloaded_unique = null; public $favorites = null; public $media = null; public $media_artists = null; public $media_albums = null; public $media_played = null; public function __construct(Flooer_Db &$db, array $config = null) { $this->_db =& $db; if ($config) { $this->_config = $config + $this->_config; } if ($this->_config['createTables']) { $this->createTables(); } $this->profiles = new table_profiles($this->_db); $this->collections = new table_collections($this->_db); $this->collections_downloaded = new table_collections_downloaded($this->_db); $this->files = new table_files($this->_db); $this->files_downloaded = new table_files_downloaded($this->_db); $this->files_downloaded_all = new table_files_downloaded_all($this->_db); + $this->files_downloaded_unique = new table_files_downloaded_unique($this->_db); $this->favorites = new table_favorites($this->_db); $this->media = new table_media($this->_db); $this->media_artists = new table_media_artists($this->_db); $this->media_albums = new table_media_albums($this->_db); $this->media_played = new table_media_played($this->_db); } public function createTables() { $idDifinition = 'INTEGER NOT NULL PRIMARY KEY'; $timestampDifinition = 'CHAR(19)'; switch ($this->_db->getAttribute(Flooer_Db::ATTR_DRIVER_NAME)) { case 'mysql': //$idDifinition = 'INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY'; $timestampDifinition = 'DATETIME'; break; case 'pgsql': //$idDifinition = 'SERIAL PRIMARY KEY'; $timestampDifinition = 'TIMESTAMP'; break; case 'sqlite': //$idDifinition = 'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT'; $timestampDifinition = 'CHAR(19)'; break; } if (!isset($this->_db->profiles)) { $this->_db->profiles = array( 'id' => $idDifinition, 'active' => 'INTEGER(1) NOT NULL DEFAULT 1', 'client_id' => 'INTEGER NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'name' => 'VARCHAR(255) NOT NULL', 'email' => 'VARCHAR(255)', 'homepage' => 'VARCHAR(255)', 'image' => 'VARCHAR(255)', 'description' => 'TEXT' ); } if (!isset($this->_db->collections)) { $this->_db->collections = array( 'id' => $idDifinition, 'active' => 'INTEGER(1) NOT NULL DEFAULT 1', 'client_id' => 'INTEGER NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'name' => 'VARCHAR(255) NOT NULL', 'files' => 'INTEGER NOT NULL', 'size' => 'BIGINT UNSIGNED NOT NULL', 'title' => 'VARCHAR(200)', 'description' => 'TEXT', 'category' => 'VARCHAR(64)', 'tags' => 'TEXT', 'version' => 'VARCHAR(64)', 'content_id' => 'VARCHAR(255)', 'content_page' => 'VARCHAR(255)', 'downloaded_timestamp' => $timestampDifinition, 'downloaded_ip' => 'VARCHAR(39)', 'downloaded_count' => 'INTEGER', 'created_timestamp' => $timestampDifinition, 'created_ip' => 'VARCHAR(39)', 'updated_timestamp' => $timestampDifinition, 'updated_ip' => 'VARCHAR(39)' ); } if (!isset($this->_db->collections_downloaded)) { $this->_db->collections_downloaded = array( 'id' => $idDifinition, 'client_id' => 'INTEGER NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'collection_id' => 'INTEGER NOT NULL', 'user_id' => 'VARCHAR(255)', 'referer' => 'VARCHAR(255)', 'downloaded_timestamp' => $timestampDifinition, 'downloaded_ip' => 'VARCHAR(39)' ); } if (!isset($this->_db->files)) { $this->_db->files = array( 'id' => $idDifinition, 'origin_id' => 'INTEGER NOT NULL', 'active' => 'INTEGER(1) NOT NULL DEFAULT 1', 'client_id' => 'INTEGER NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'collection_id' => 'INTEGER NOT NULL', 'name' => 'VARCHAR(255) NOT NULL', 'type' => 'VARCHAR(255) NOT NULL', 'size' => 'BIGINT UNSIGNED NOT NULL', 'title' => 'VARCHAR(200)', 'description' => 'TEXT', 'category' => 'VARCHAR(64)', 'tags' => 'TEXT', 'version' => 'VARCHAR(64)', 'ocs_compatible' => 'INTEGER(1) NOT NULL DEFAULT 1', 'content_id' => 'VARCHAR(255)', 'content_page' => 'VARCHAR(255)', 'downloaded_timestamp' => $timestampDifinition, 'downloaded_ip' => 'VARCHAR(39)', 'downloaded_count' => 'INTEGER', 'created_timestamp' => $timestampDifinition, 'created_ip' => 'VARCHAR(39)', 'updated_timestamp' => $timestampDifinition, 'updated_ip' => 'VARCHAR(39)' ); } if (!isset($this->_db->files_downloaded)) { $this->_db->files_downloaded = array( 'id' => $idDifinition, 'client_id' => 'INTEGER NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'collection_id' => 'INTEGER NOT NULL', 'file_id' => 'INTEGER NOT NULL', 'user_id' => 'VARCHAR(255)', 'referer' => 'VARCHAR(255)', 'downloaded_timestamp' => $timestampDifinition, 'downloaded_ip' => 'VARCHAR(39)' ); } if (!isset($this->_db->files_downloaded_all)) { $this->_db->files_downloaded_all = array( 'id' => $idDifinition, 'client_id' => 'INTEGER NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'collection_id' => 'INTEGER NOT NULL', 'file_id' => 'INTEGER NOT NULL', 'user_id' => 'VARCHAR(255)', 'referer' => 'VARCHAR(255)', 'downloaded_timestamp' => $timestampDifinition, 'downloaded_ip' => 'VARCHAR(39)', 'source' => 'VARCHAR(39)', 'link_type' => 'VARCHAR(39)' ); } + + if (!isset($this->_db->files_downloaded_unique)) { + $this->_db->files_downloaded_unique = array( + 'id' => $idDifinition, + 'client_id' => 'INTEGER NOT NULL', + 'owner_id' => 'VARCHAR(255) NOT NULL', + 'collection_id' => 'INTEGER NOT NULL', + 'file_id' => 'INTEGER NOT NULL', + 'user_id' => 'VARCHAR(255)', + 'referer' => 'VARCHAR(255)', + 'downloaded_timestamp' => $timestampDifinition, + 'downloaded_ip' => 'VARCHAR(39)' + ); + } if (!isset($this->_db->favorites)) { $this->_db->favorites = array( 'id' => $idDifinition, 'client_id' => 'INTEGER NOT NULL', 'user_id' => 'VARCHAR(255) NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'collection_id' => 'INTEGER', 'file_id' => 'INTEGER' ); } if (!isset($this->_db->media)) { $this->_db->media = array( 'id' => $idDifinition, 'client_id' => 'INTEGER NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'collection_id' => 'INTEGER NOT NULL', 'file_id' => 'INTEGER NOT NULL', 'artist_id' => 'INTEGER NOT NULL', 'album_id' => 'INTEGER NOT NULL', 'title' => 'VARCHAR(255)', 'genre' => 'VARCHAR(64)', 'track' => 'VARCHAR(5)', 'creationdate' => 'INTEGER(4)', 'bitrate' => 'INTEGER', 'playtime_seconds' => 'INTEGER', 'playtime_string' => 'VARCHAR(8)', 'played_timestamp' => $timestampDifinition, 'played_ip' => 'VARCHAR(39)', 'played_count' => 'INTEGER' ); } if (!isset($this->_db->media_artists)) { $this->_db->media_artists = array( 'id' => $idDifinition, 'client_id' => 'INTEGER NOT NULL', 'name' => 'VARCHAR(255) NOT NULL' ); } if (!isset($this->_db->media_albums)) { $this->_db->media_albums = array( 'id' => $idDifinition, 'client_id' => 'INTEGER NOT NULL', 'name' => 'VARCHAR(255) NOT NULL' ); } if (!isset($this->_db->media_played)) { $this->_db->media_played = array( 'id' => $idDifinition, 'client_id' => 'INTEGER NOT NULL', 'owner_id' => 'VARCHAR(255) NOT NULL', 'collection_id' => 'INTEGER NOT NULL', 'file_id' => 'INTEGER NOT NULL', 'media_id' => 'INTEGER NOT NULL', 'user_id' => 'VARCHAR(255)', 'played_timestamp' => $timestampDifinition, 'played_ip' => 'VARCHAR(39)' ); } } public function getDb() { return $this->_db; } } diff --git a/api_application/models/table_files_downloaded_unique.php b/api_application/models/table_files_downloaded_unique.php new file mode 100644 index 0000000..a953d31 --- /dev/null +++ b/api_application/models/table_files_downloaded_unique.php @@ -0,0 +1,63 @@ +. + **/ + +class table_files_downloaded_unique extends BaseModel +{ + + public function __construct(&$db) + { + parent::__construct($db, $db->getTableConfig()); + $this->setName('files_downloaded_unique'); + $this->setPrimaryInsert(true); + $this->setInsertIgnore(true); + } + + public function __set($key, $value) + { + $value = $this->_convertArrayToObject($value); + unset($value->id); + if(empty($value->referer)) { + $value->referer = $this->_getReferer(); + } + $value->downloaded_timestamp = $this->_getTimestamp(); + $value->downloaded_ip = $this->_getIp(); + parent::__set($key, $value); + } + + public function deleteByCollectionId($collectionId) + { + $primary = $this->getPrimary(); + $this->setPrimary('collection_id'); + unset($this->$collectionId); + $this->setPrimary($primary); + } + + public function deleteByFileId($fileId) + { + $primary = $this->getPrimary(); + $this->setPrimary('file_id'); + unset($this->$fileId); + $this->setPrimary($primary); + } + +} diff --git a/library/Flooer/Db/Table.php b/library/Flooer/Db/Table.php index ba23442..ccdfaa0 100644 --- a/library/Flooer/Db/Table.php +++ b/library/Flooer/Db/Table.php @@ -1,458 +1,484 @@ * @copyright Akira Ohgaki * @license https://opensource.org/licenses/BSD-2-Clause BSD License (2 Clause) * @link https://github.com/akiraohgaki/flooer */ require_once 'Flooer/Db/Table/Row.php'; require_once 'Flooer/Db/Table/Rowset.php'; /** * Usage * * $table = new Flooer_Db_Table($db); * $table->setName('TableName'); * $table->setPrimary('PrimaryKey'); * $row = $table->RecordID; */ /** * Table class of SQL database abstraction layer * * @category Flooer * @package Flooer_Db * @subpackage Table * @author Akira Ohgaki */ class Flooer_Db_Table { /** * Database connection object * * @var Flooer_Db */ protected $_db = null; /** * Configuration options * * @var array */ protected $_config = array( 'name' => null, 'prefix' => null, 'columns' => '*', 'primary' => 'id', - 'primaryInsert' => false + 'primaryInsert' => false, + 'insertIgnore' => false ); /** * Row exists * * @var array */ protected $_rowExists = array(); /** * Row object cache * * @var array */ protected $_rowCache = array(); /** * Constructor * * @param Flooer_Db &$db * @param array $config * @return void */ public function __construct(Flooer_Db &$db, array $config = null) { $this->_db =& $db; if ($config) { $this->_config = $config + $this->_config; } if (!$this->_config['name']) { $this->_config['name'] = get_class($this); } } /** * Magic method to update/insert a row * * @param string $key * @param array|object $value * @return void */ public function __set($key, $value) { if (is_array($value) || is_object($value)) { // Update a row if ($this->__isset($key)) { $this->_rowExists = array(); $this->_rowCache = array(); $columns = array(); $statementValues = array(); foreach ($value as $columnName => $columnValue) { $columns[] = "$columnName = :$columnName"; $statementValues[":$columnName"] = $columnValue; } $columnsSet = implode(',', $columns); $whereValue = $this->_db->quote($key); $sql = "UPDATE {$this->_config['prefix']}{$this->_config['name']}" . " SET $columnsSet" . " WHERE {$this->_config['primary']} = $whereValue;"; $this->_db->addStatementLog($sql); $statement = $this->_db->prepare($sql); $statement->execute($statementValues); $statement->closeCursor(); } // Insert a new row else { $this->_rowExists = array(); $this->_rowCache = array(); $columnNames = array(); $columnValues = array(); $statementValues = array(); if ($this->_config['primaryInsert']) { $columnNames[] = $this->_config['primary']; $columnValues[] = ":{$this->_config['primary']}"; $statementValues[":{$this->_config['primary']}"] = $key; } foreach ($value as $columnName => $columnValue) { $columnNames[] = $columnName; $columnValues[] = ":$columnName"; $statementValues[":$columnName"] = $columnValue; } $columnNamesSet = implode(',', $columnNames); $columnValuesSet = implode(',', $columnValues); - $sql = "INSERT INTO {$this->_config['prefix']}{$this->_config['name']}" + $sql = "INSERT "; + if($this->_config['insertIgnore']) { + $sql .= " IGNORE "; + } + $sql .= " INTO {$this->_config['prefix']}{$this->_config['name']}" . " ($columnNamesSet)" . " VALUES ($columnValuesSet);"; $this->_db->addStatementLog($sql); $statement = $this->_db->prepare($sql); $statement->execute($statementValues); $statement->closeCursor(); } return; } trigger_error( "Setting non-array or non-object property ($key) is not allowed", E_USER_NOTICE ); } /** * Magic method to get a row object * * @param string $key * @return Flooer_Db_Table_Row|null */ public function __get($key) { if ($this->__isset($key)) { if (empty($this->_rowCache[$key])) { $whereValue = $this->_db->quote($key); $sql = "SELECT {$this->_config['columns']}" . " FROM {$this->_config['prefix']}{$this->_config['name']}" . " WHERE {$this->_config['primary']} = $whereValue;"; $this->_db->addStatementLog($sql); $statement = $this->_db->prepare($sql); $statement->setFetchMode( Flooer_Db::FETCH_CLASS, 'Flooer_Db_Table_Row' ); $bool = $statement->execute(); $row = $statement->fetch(); $statement->closeCursor(); $this->_rowCache[$key] = null; if ($bool && $row) { $this->_rowCache[$key] = $row; } } return $this->_rowCache[$key]; } return null; } /** * Magic method to check a row * * @param string $key * @return bool */ public function __isset($key) { if (isset($this->_rowExists[$key])) { return $this->_rowExists[$key]; } $driver = $this->_db->getAttribute(Flooer_Db::ATTR_DRIVER_NAME); $whereValue = $this->_db->quote($key); $sql = "SELECT COUNT(*)" . " FROM {$this->_config['prefix']}{$this->_config['name']}" . " WHERE {$this->_config['primary']} = $whereValue;"; if ($driver == 'sqlite' || $driver == 'mysql' || $driver == 'pgsql') { $sql = "SELECT 1" . " FROM {$this->_config['prefix']}{$this->_config['name']}" . " WHERE {$this->_config['primary']} = $whereValue" . " LIMIT 1;"; } else if ($driver == 'sqlsrv') { $sql = "SELECT TOP 1 1" . " FROM {$this->_config['prefix']}{$this->_config['name']}" . " WHERE {$this->_config['primary']} = $whereValue;"; } $this->_db->addStatementLog($sql); $statement = $this->_db->prepare($sql); $bool = $statement->execute(); $row = $statement->fetch(Flooer_Db::FETCH_NUM); $statement->closeCursor(); if ($bool && $row) { if ($row[0]) { $this->_rowExists[$key] = true; return true; } $this->_rowExists[$key] = false; } return false; } /** * Magic method to delete a row * * @param string $key * @return void */ public function __unset($key) { if ($this->__isset($key)) { $whereValue = $this->_db->quote($key); $sql = "DELETE FROM {$this->_config['prefix']}{$this->_config['name']}" . " WHERE {$this->_config['primary']} = $whereValue;"; $this->_db->addStatementLog($sql); $statement = $this->_db->prepare($sql); $bool = $statement->execute(); $statement->closeCursor(); if ($bool) { $this->_rowExists[$key] = false; unset($this->_rowCache[$key]); } } } /** * Fetch one row * * @param string $statementOption * @param array $values * @return Flooer_Db_Table_Row|null */ public function fetchRow($statementOption = '', array $values = null) { $sql = "SELECT {$this->_config['columns']}" . " FROM {$this->_config['prefix']}{$this->_config['name']}" . " $statementOption;"; $this->_db->addStatementLog($sql); $statement = $this->_db->prepare($sql); $statement->setFetchMode( Flooer_Db::FETCH_CLASS, 'Flooer_Db_Table_Row' ); $bool = $statement->execute($values); $row = $statement->fetch(); $statement->closeCursor(); if ($bool && $row) { return $row; } return null; } /** * Fetch a rowset * * @param string $statementOption * @param array $values * @return Flooer_Db_Table_Rowset|null */ public function fetchRowset($statementOption = '', array $values = null) { $sql = "SELECT {$this->_config['columns']}" . " FROM {$this->_config['prefix']}{$this->_config['name']}" . " $statementOption;"; $this->_db->addStatementLog($sql); $statement = $this->_db->prepare($sql); $statement->setFetchMode( Flooer_Db::FETCH_CLASS, 'Flooer_Db_Table_Row' ); $bool = $statement->execute($values); $rowsetArray = $statement->fetchAll(); $statement->closeCursor(); if ($bool && $rowsetArray) { $rowset = new Flooer_Db_Table_Rowset(); foreach ($rowsetArray as $key => $value) { $rowset->$key = $value; } return $rowset; } return null; } /** * Count a record size * * @param string $statementOption * @param array $values * @return int|bool */ public function count($statementOption = '', array $values = null) { $sql = "SELECT COUNT(*)" . " FROM {$this->_config['prefix']}{$this->_config['name']}" . " $statementOption;"; $this->_db->addStatementLog($sql); $statement = $this->_db->prepare($sql); $bool = $statement->execute($values); $row = $statement->fetch(Flooer_Db::FETCH_NUM); $statement->closeCursor(); if ($bool && $row) { return $row[0]; } return false; } /** * Get a database connection object * * @return Flooer_Db */ public function getDb() { return $this->_db; } /** * Set a table name * * @param string $name * @return void */ public function setName($name) { $this->_config['name'] = $name; $this->_rowExists = array(); $this->_rowCache = array(); } /** * Get a table name * * @return string */ public function getName() { return $this->_config['name']; } /** * Set a table name prefix * * @param string $prefix * @return void */ public function setPrefix($prefix) { $this->_config['prefix'] = $prefix; $this->_rowExists = array(); $this->_rowCache = array(); } /** * Get a table name prefix * * @return string */ public function getPrefix() { return $this->_config['prefix']; } /** * Set a table columns * * @param string $columns * @return void */ public function setColumns($columns) { $this->_config['columns'] = $columns; $this->_rowCache = array(); } /** * Get a table columns * * @return string */ public function getColumns() { return $this->_config['columns']; } /** * Set a primary key name * * @param string $primary * @return void */ public function setPrimary($primary) { $this->_config['primary'] = $primary; $this->_rowExists = array(); $this->_rowCache = array(); } /** * Get a primary key name * * @return string */ public function getPrimary() { return $this->_config['primary']; } /** * Set an option for a primary key inserting * * @param bool $bool * @return void */ public function setPrimaryInsert($bool) { $this->_config['primaryInsert'] = $bool; } /** * Get an option for a primary key inserting * * @return bool */ public function getPrimaryInsert() { return $this->_config['primaryInsert']; } + + /** + * Set an option for a insert irgnore + * + * @param bool $bool + * @return void + */ + public function setInsertIgnore($bool) + { + $this->_config['insertIgnore'] = $bool; + } + + /** + * Get an option for a primary key inserting + * + * @return bool + */ + public function getInsertIgnore() + { + return $this->_config['insertIgnore']; + } }