1
0
Эх сурвалжийг харах

Ticket #5291 - Improve uploader and storage collaboration.

AntonLV 11 сар өмнө
parent
commit
d7e55d761d

+ 17 - 9
inc/classes/BxDolStorage.php

@@ -816,20 +816,17 @@ abstract class BxDolStorage extends BxDolFactory implements iBxDolFactoryObject
     /**
      * Get ghost/orphaned files for particular user.
      * @param $iProfileId profile id
-     * @param $iContentId content id, or false to not consider content id at all
+     * @param $mixedContent - int Content ID | array Content ID + Uploader ID | false to not consider content id at all
      * @param $isCheckAllAccountProfiles get all files associated with all account profiles
      * @param $isAdmin if true, then don't check files ownership, it makes sense when $iContentId is provided, so it will return all files assiciated with content
      * @return array of arrays
      */
-    public function getGhosts($iProfileId, $iContentId = false, $isCheckAllAccountProfiles = false, $isAdmin = false)
+    public function getGhosts($iProfileId, $mixedContent = false, $isCheckAllAccountProfiles = false, $isAdmin = false)
     {
-        if ($isCheckAllAccountProfiles && ($oProfile = BxDolProfile::getInstance($iProfileId))) {
-            $oAccount = $oProfile->getAccountObject();
-            $aProfiles = $oAccount->getProfilesIds(false, false);
-            return $this->_oDb->getGhosts($aProfiles, $iContentId, $isAdmin);
-        }
-        
-        return $this->_oDb->getGhosts($iProfileId, $iContentId, $isAdmin);
+        if($isCheckAllAccountProfiles && ($oProfile = BxDolProfile::getInstance($iProfileId)) !== false && ($oAccount = $oProfile->getAccountObject()) !== false)
+            $iProfileId = $oAccount->getProfilesIds(false, false);
+
+        return $this->_oDb->getGhosts($iProfileId, $mixedContent, $isAdmin);
     }
     
     /**
@@ -868,6 +865,17 @@ abstract class BxDolStorage extends BxDolFactory implements iBxDolFactoryObject
 
         return $this->_oDb->updateGhostsContentId($mixedFileIds, $iProfileId, $iContentId, $aProfiles, $isAdmin);
     }
+    
+    /**
+     * Update ghosts' uploader id.
+     * @param $mixedFileIds array of file ids or just one file id
+     * @param $iUploaderId uploader id
+     * @return true on success or false otherwise
+     */
+    public function updateGhostsUploaderId($mixedFileIds, $iUploaderId)
+    {
+        return $this->_oDb->updateGhostsUploaderId($mixedFileIds, $iUploaderId);
+    }
 
     /**
      * Get files list for particular user.

+ 21 - 8
inc/classes/BxDolStorageQuery.php

@@ -294,6 +294,14 @@ class BxDolStorageQuery extends BxDolDb
         $sQuery = $this->prepare("UPDATE `sys_storage_ghosts` SET `content_id` = :content $sSetAddon WHERE `object` = :object $sWhere AND `id` IN (" . $this->implode_escape($mixedFileIds) . ")");
         return $this->res($sQuery, $aBindings);
     }
+    
+    public function updateGhostsUploaderId($mixedFileIds, $iUploaderId)
+    {
+        return $this->query("UPDATE `sys_storage_ghosts` SET `uploader_id` = :uploader_id WHERE `object` = :object AND `id` IN (" . $this->implode_escape($mixedFileIds) . ")", [
+            'object' => $this->_aObject['object'],
+            'uploader_id' => $iUploaderId
+        ]);
+    }
 
     public function deleteGhosts($mixedFileIds, $iProfileId, $iContentId = false)
     {
@@ -313,9 +321,9 @@ class BxDolStorageQuery extends BxDolDb
         return $iCount;
     }
 
-    public function getGhosts($mixedProfileId, $iContentId = false, $isAdmin = false)
+    public function getGhosts($mixedProfileId, $mixedContent = false, $isAdmin = false)
     {
-        return $this->getFiles($mixedProfileId, true, $iContentId, $isAdmin);
+        return $this->getFiles($mixedProfileId, true, $mixedContent, $isAdmin);
     }
 
     public function getGhost($iFileId)
@@ -324,7 +332,7 @@ class BxDolStorageQuery extends BxDolDb
         return $this->getRow($sQuery);
     }
 
-    public function getFiles($mixedProfileId, $isGhostsOnly = false, $iContentId = false, $isAdmin = false)
+    public function getFiles($mixedProfileId, $isGhostsOnly = false, $mixedContent = false, $isAdmin = false)
     {
         $aBindings = array();        
 
@@ -335,7 +343,7 @@ class BxDolStorageQuery extends BxDolDb
             $aBindings['object'] = $this->_aObject['object'];
 
             $sOnProfile = '';
-            if ($isAdmin && $iContentId) {
+            if ($isAdmin && $mixedContent) {
                 // don't check profile id for admins, so admin can edit any entry
             }
             elseif (is_array($mixedProfileId) && $mixedProfileId) {
@@ -348,10 +356,15 @@ class BxDolStorageQuery extends BxDolDb
             }
             
             $sJoin .= " INNER JOIN `sys_storage_ghosts` AS `g` ON (`f`.`id` = `g`.`id` AND `g`.`object` = :object " . $sOnProfile;
-            if (false !== $iContentId) {
-                $aBindings['content_id'] = $iContentId;
-
-                $sJoin .= " AND `g`.`content_id` = :content_id";
+            if ($mixedContent !== false) {
+                if(!is_array($mixedContent)) {
+                    $aBindings['content_id'] = $mixedContent;
+                    $sJoin .= " AND `g`.`content_id` = :content_id";
+                }
+                else {
+                    list($aBindings['content_id'], $aBindings['uploader_id']) = $mixedContent;
+                    $sJoin .= " AND `g`.`content_id` = :content_id AND `g`.`uploader_id` = :uploader_id";
+                }
             }
 
             $sJoin .= ')';

+ 27 - 18
inc/classes/BxDolUploader.php

@@ -101,6 +101,7 @@
  */
 abstract class BxDolUploader extends BxDolFactory
 {
+    protected $_bIsApi;
     protected $_oTemplate;
 
     protected $_aObject; ///< object properties
@@ -130,6 +131,7 @@ abstract class BxDolUploader extends BxDolFactory
     protected function __construct($aObject, $sStorageObject, $sUniqId, $oTemplate)
     {
         parent::__construct();
+        $this->_bIsApi = bx_is_api();
         $this->_oTemplate = $oTemplate ? $oTemplate : BxDolTemplate::getInstance();
 
         $this->_aObject = $aObject;
@@ -217,28 +219,31 @@ abstract class BxDolUploader extends BxDolFactory
      */
     public function handleUploads ($iProfileId, $mixedFiles, $isMultiple = true, $iContentId = false, $bPrivate = true)
     {
-        $oStorage = BxDolStorage::getObjectInstance($this->_sStorageObject);
+        $oStorage = BxDolStorage::getObjectInstance($this->_sStorageObject);       
+
+        if(!$isMultiple)
+            $this->deleteGhostsForProfile($iProfileId, [$iContentId, $this->_aObject['id']]);
 
-        if (false == ($aMultipleFiles = $oStorage->convertMultipleFilesArray($mixedFiles)))
-            $aMultipleFiles = array($mixedFiles);
+        if($this->_bIsApi && $mixedFiles) {
+            if(($iId = $oStorage->storeFileFromForm($mixedFiles, $bPrivate, $iProfileId, $iContentId)))
+                $oStorage->updateGhostsUploaderId($iId, $this->_aObject['id']);
 
-        if (!$isMultiple)
-            $this->deleteGhostsForProfile($iProfileId, $iContentId);
+            return [
+                'success' => 1, 
+                'id' => $iId
+            ];
+        }
 
-        
-        if (bx_is_api() && $_FILES['file']) {
-            $iId = $oStorage->storeFileFromForm($_FILES['file'], $bPrivate, $iProfileId, $iContentId);
-            $aResponse = array ('success' => 1, 'id' => $iId);
-            return $aResponse;
-        } 
-        
-        foreach ($aMultipleFiles as $aFile) {
+        if(($aMultipleFiles = $oStorage->convertMultipleFilesArray($mixedFiles)) === false)
+            $aMultipleFiles = [$mixedFiles];
 
-            $iId = $oStorage->storeFileFromForm($aFile, $bPrivate, $iProfileId, $iContentId);
-            if (!$iId)
+        foreach($aMultipleFiles as $aFile) {
+            if(($iId = $oStorage->storeFileFromForm($aFile, $bPrivate, $iProfileId, $iContentId)))
+                $oStorage->updateGhostsUploaderId($iId, $this->_aObject['id']);
+            else 
                 $this->appendUploadErrorMessage(_t('_sys_uploader_err_msg', $aFile['name'], $oStorage->getErrorString()));
 
-            if (!$isMultiple)
+            if(!$isMultiple)
                 break;
         }
 
@@ -485,15 +490,19 @@ abstract class BxDolUploader extends BxDolFactory
 
     /**
      * Delete all ghosts files for the specified profile
+     * @param $iProfileId - profile id to get orphaned files from
+     * @param $mixedContent - int Content ID | array Content ID + Uploader ID | false
      * @return number of delete ghost files
      */
-    public function deleteGhostsForProfile($iProfileId, $iContentId = false)
+    public function deleteGhostsForProfile($iProfileId, $mixedContent = false)
     {
         $iCount = 0;
 
         $oStorage = BxDolStorage::getObjectInstance($this->_sStorageObject);
+        if($oStorage === false)
+            return $iCount;
 
-        $aGhosts = $oStorage->getGhosts($iProfileId, $iContentId, $iContentId ? true : false);
+        $aGhosts = $oStorage->getGhosts($iProfileId, $mixedContent, $mixedContent ? true : false);
         foreach ($aGhosts as $aFile)
             $iCount += $oStorage->deleteFile($aFile['id']);
 

+ 1 - 0
install/sql/system.sql

@@ -2696,6 +2696,7 @@ CREATE TABLE IF NOT EXISTS `sys_storage_ghosts` (
   `id` int(11) NOT NULL,
   `profile_id` int(10) unsigned NOT NULL,
   `object` varchar(64) NOT NULL,
+  `uploader_id` int(11) NOT NULL default '0',
   `content_id` int(11) NOT NULL,
   `created` int(10) unsigned NOT NULL,
   `order` int(11) NOT NULL default '0',

+ 9 - 7
modules/base/profile/classes/BxBaseModProfileUploaderCrop.php

@@ -25,18 +25,20 @@ class BxBaseModProfileUploaderCrop extends BxTemplUploaderCrop
         parent::__construct($aObject, $sStorageObject, $sUniqId, $oTemplate ? $oTemplate : $this->_oModule->_oTemplate);
     }
 
-    public function deleteGhostsForProfile($iProfileId, $iContentId = false)
+    public function deleteGhostsForProfile($iProfileId, $mixedContent = false)
     {
-        if (!$iContentId)
-            return parent::deleteGhostsForProfile($iProfileId, $iContentId);
+        if(!$mixedContent)
+            return parent::deleteGhostsForProfile($iProfileId, $mixedContent);
 
-        $CNF = $this->_oModule->_oConfig->CNF;
-        $aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId);
-        
         $iCount = 0;
 
         $oStorage = BxDolStorage::getObjectInstance($this->_sStorageObject);
-        $aGhosts = $oStorage->getGhosts($iProfileId, $iContentId, $iContentId ? true : false);
+        if($oStorage === false)
+            return $iCount;
+
+        $aContentInfo = $this->_oModule->_oDb->getContentInfoById(is_array($mixedContent) ? reset($mixedContent) : $mixedContent);
+
+        $aGhosts = $oStorage->getGhosts($iProfileId, $mixedContent, $mixedContent ? true : false);
         foreach ($aGhosts as $aFile) {
             // for requested image type delete only unassigned ghosts and currently set images
             if ($aFile['id'] == $aContentInfo[$this->_sImage] || !in_array($aFile['id'], array_map(function($sField) use ($aContentInfo) {

+ 8 - 10
template/scripts/BxBaseUploaderCrop.php

@@ -81,16 +81,14 @@ class BxBaseUploaderCrop extends BxDolUploader
     }
 
     public function handleUploads ($iProfileId, $mixedFiles, $isMultiple = true, $iContentId = false, $bPrivate = true)
-    {
-        if (bx_is_api()){
-             return parent::handleUploads ($iProfileId, $mixedFiles, $isMultiple, $iContentId, $bPrivate);;
-         }
-         else{
-            ob_start();
-            parent::handleUploads ($iProfileId, $mixedFiles, $isMultiple, $iContentId, $bPrivate);
-            $s = ob_get_clean();
-            echo strip_tags(str_replace('window.parent.', 'window.', $s));
-        }
+    {       
+        if($this->_bIsApi)
+            return parent::handleUploads ($iProfileId, $mixedFiles, $isMultiple, $iContentId, $bPrivate);
+
+        ob_start();
+        parent::handleUploads ($iProfileId, $mixedFiles, $isMultiple, $iContentId, $bPrivate);
+        $s = ob_get_clean();
+        echo strip_tags(str_replace('window.parent.', 'window.', $s));
     }
 
 }

+ 11 - 9
template/scripts/BxBaseUploaderHTML5.php

@@ -172,22 +172,24 @@ class BxBaseUploaderHTML5 extends BxDolUploader
         $oStorage = BxDolStorage::getObjectInstance($this->_sStorageObject);
 
         if (!$isMultiple)
-            $this->deleteGhostsForProfile($iProfileId, $iContentId);
+            $this->deleteGhostsForProfile($iProfileId, [$iContentId, $this->_aObject['id']]);
 
-        if (bx_get('file')) {
-            $iId = $oStorage->storeFileFromXhr(bx_get('file'), $bPrivate, $iProfileId, $iContentId);
-        } 
-        else {
+        if (($sFile = bx_get('file')) !== false)
+            $iId = $oStorage->storeFileFromXhr($sFile, $bPrivate, $iProfileId, $iContentId);
+        else
             $iId = $oStorage->storeFileFromForm($_FILES['file'], $bPrivate, $iProfileId, $iContentId);
-        }
 
         if ($iId) {
-            $aResponse = array ('success' => 1, 'id' => $iId);
+            $oStorage->updateGhostsUploaderId($iId, $this->_aObject['id']);
+
+            $aResponse = ['success' => 1, 'id' => $iId];
         } else {
             $this->appendUploadErrorMessage(_t('_sys_uploader_err_msg', isset($_FILES['file']['name']) ? $_FILES['file']['name'] : bx_get('file'), $oStorage->getErrorString()));
-            $aResponse = array ('error' => $this->getUploadErrorMessages());
+
+            $aResponse = ['error' => $this->getUploadErrorMessages()];
         }
-        if (bx_is_api())
+
+        if ($this->_bIsApi)
             return $aResponse;
         else
             echo htmlspecialchars(json_encode($aResponse), ENT_NOQUOTES);

+ 12 - 13
template/scripts/BxBaseUploaderServices.php

@@ -53,7 +53,7 @@ class BxBaseUploaderServices extends BxDol
         else
             $iContentId = bx_process_input($iContentId, BX_DATA_INT);
 
-        
+        $iProfileId = (int)bx_get_logged_profile_id();
         $isPrivate = (int)bx_get('p') ? 1 : 0;
 
         $oUploader = BxDolUploader::getObjectInstance($sUploaderObject, $sStorageObject, $sUniqId);
@@ -64,7 +64,7 @@ class BxBaseUploaderServices extends BxDol
 
             case 'restore_ghosts':
                 $sImagesTranscoder = bx_process_input(bx_get('img_trans'));
-                $oData = $oUploader->getGhostsWithOrder((int)bx_get_logged_profile_id(), $sFormat, $sImagesTranscoder, $iContentId);
+                $oData = $oUploader->getGhostsWithOrder($iProfileId, $sFormat, $sImagesTranscoder, $iContentId);
                 $aRv = isset($oData['g']) ? [$oData['g'], $oData['o']] : [];
                 return $aRv;
                 break;
@@ -72,19 +72,20 @@ class BxBaseUploaderServices extends BxDol
             case 'delete':
                 header('Content-type: text/html; charset=utf-8');
                 $iFileId = bx_process_input(bx_get('id'), BX_DATA_INT);
-                return $oUploader->deleteGhost($iFileId, bx_get_logged_profile_id());
+                return $oUploader->deleteGhost($iFileId, $iProfileId);
                 break;
 
             case 'upload':
-                $iProfileId = (int)bx_get_logged_profile_id();
-
-                $aResult = $oUploader->handleUploads($iProfileId, isset($_FILES['f']) ? $_FILES['f'] : null, $isMultiple, $iContentId, $isPrivate);
-                if(isset($aResult['id']) && ($iId = (int)$aResult['id']) && ($sImagesTranscoder = bx_get('img_trans')) !== false) {
-                    $aGhosts = $oUploader->getGhosts($iProfileId, 'array', bx_process_input($sImagesTranscoder), $iContentId);
-                    if(isset($aGhosts[$iId]))
-                        $aResult['ghost'] = $aGhosts[$iId];
+                if(($aFile = $_FILES['file'] ?? false)) {
+                    $aResult = $oUploader->handleUploads($iProfileId, $aFile, $isMultiple, $iContentId, $isPrivate);
+                    if(($iId = (int)($aResult['id'] ?? 0)) && ($sImagesTranscoder = bx_get('img_trans')) !== false) {
+                        $aGhosts = $oUploader->getGhosts($iProfileId, 'array', bx_process_input($sImagesTranscoder), $iContentId);
+                        if(isset($aGhosts[$iId]))
+                            $aResult['ghost'] = $aGhosts[$iId];
+                    }
+
+                    return $aResult;
                 }
-                return $aResult;
                 break;
 
             case 'upload_inline':
@@ -92,8 +93,6 @@ class BxBaseUploaderServices extends BxDol
                 $sFile = bx_process_input(bx_get('f'));
 
                 $oStorage = BxDolStorage::getObjectInstance($sStorageObject);
-                
-                $iProfileId = bx_get_logged_profile_id();
 
                 if (!($iId = $oStorage->storeFileFromForm($_FILES['file'], false, $iProfileId))) {
                     return array('error' => '1');