Quellcode durchsuchen

Ticket #4395 - Timeline: Media attachment deletes link embed. Core changes.

AntonLV vor 3 Jahren
Ursprung
Commit
ff2e33216e

+ 3 - 1
inc/classes/BxDolUploader.php

@@ -289,7 +289,9 @@ abstract class BxDolUploader extends BxDolFactory
                     'uploader_instance_name' => $sJsObject,
                     'is_init_reordering' => isset($aParams['is_init_reordering']) ? $aParams['is_init_reordering'] : 0,
                 ]
-            ]
+            ],
+            'on_upload' => 'false',
+            'on_restore_ghosts' => 'false'
         ], $aParams));
 
         if(!$bDynamic) {

+ 26 - 6
inc/js/classes/BxDolUploader.js

@@ -52,6 +52,9 @@ BxDolUploaderBase.prototype.init = function (sUploaderObject, sStorageObject, sU
     this._isPrivate = undefined == options.storage_private || parseInt(options.storage_private) ? 1 : 0;
 
     this._isErrorShown = false;
+
+    this._onUpload = typeof options.on_upload === 'function' ? options.on_upload : function () {};
+    this._onRestoreGhosts = typeof options.on_restore_ghosts === 'function' ? options.on_restore_ghosts : function () {};
 }
 
 BxDolUploaderBase.prototype.isMultiple = function () {    
@@ -124,11 +127,14 @@ BxDolUploaderBase.prototype.onUploadCompleted = function (sErrorMsg) {
     this._loading(false, true);
 
     if (sErrorMsg.length) {
-        this.restoreGhosts();        
+        this.restoreGhosts();
         this._showError(sErrorMsg);
-    } else {        
+    } else {
         this.restoreGhosts();
         $('#' + this._sPopupContainerId).dolPopupHide({});
+
+        if(typeof this._onUpload === 'function')
+            this._onUpload(this._iContentId);
     }
 }
 
@@ -142,6 +148,7 @@ BxDolUploaderBase.prototype.restoreGhosts = function (bInitReordering, onComplet
     var $this = this;
 
     bInitReordering = bInitReordering !== undefined ? bInitReordering : this._isReordering;
+    onComplete = typeof onComplete === 'function' ? onComplete : this._onRestoreGhosts;
 
     $.getJSON(sUrl, function (aData) {
 
@@ -221,7 +228,7 @@ BxDolUploaderBase.prototype.showGhost = function(iId, oVars) {
     oFileContainer.find('.bx-uploader-ghost-preview img').hide().fadeIn(1000);
 };
 
-BxDolUploaderBase.prototype.deleteGhost = function (iFileId) {
+BxDolUploaderBase.prototype.deleteGhost = function (iFileId, onComplete) {
     var sUrl = this._getUrlWithStandardParams() + '&a=delete&id=' + iFileId;
     var $this = this;
 
@@ -229,14 +236,24 @@ BxDolUploaderBase.prototype.deleteGhost = function (iFileId) {
     bx_loading(sFileContainerId, true);
 
     $.post(sUrl, {_t: escape(new Date())}, function (sMsg) {
+        var fOnComplete = function(sMsg) {
+            if(typeof onComplete === 'function')
+                onComplete(sMsg);
+        };
+
         bx_loading(sFileContainerId, false);
+
         if ('ok' == sMsg) {
             $('#' + sFileContainerId).slideUp('slow', function () {
                 $(this).remove();
+
+                fOnComplete(sMsg);
             });
         } else {
             $('#' + this._sResultContainerId).prepend($this._sTemplateErrorGhosts.replace('{error}', sMsg));
-        }        
+
+            fOnComplete(sMsg);
+        }
     });
 };
 
@@ -622,13 +639,16 @@ function BxDolUploaderHTML5 (sUploaderObject, sStorageObject, sUniqId, options)
             this._showError(sErrorMsg);        
         
         var $this = this;
-        if($this._uploader.status != 3){
+        if($this._uploader.status != 3) {
             this._isUploadsInProgress = false;
             this.restoreGhosts();
-            if (!this._isErrorShown) {
+            if(!this._isErrorShown) {
                 $('#' + this._sPopupContainerId).dolPopupHide({});
                 this.removeFiles();
             }
+
+            if(typeof this._onUpload === 'function')
+                this._onUpload(this._iContentId);
         }
     }
 

+ 1 - 0
modules/boonex/russian/data/langs/bx_timeline/ru.xml

@@ -61,6 +61,7 @@
     <string name="_bx_timeline_option_cache_table_interval"><![CDATA[Интервал времени (в днях) для получения событий для табличного кэша]]></string>
     <string name="_bx_timeline_option_enable_editor_toolbar"><![CDATA[Включить панель инструментов в форме создания сообщения]]></string>
     <string name="_bx_timeline_option_editor_auto_attach_insertion"><![CDATA[Обрабатывать изображения, вставленные в редактор, как вложения]]></string>
+    <string name="_bx_timeline_option_enable_media_priority"><![CDATA[Включить приоритет медиаконтента над ссылками во вложениях]]></string>
     <string name="_bx_timeline_option_limit_attach_links"><![CDATA[Ограничить число присоединенных линок (0 - без ограничений)]]></string>
 
     <string name="_bx_timeline_form_post"><![CDATA[Сообщение]]></string>

+ 7 - 0
modules/boonex/timeline/classes/BxTimelineConfig.php

@@ -59,6 +59,7 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
 
     protected $_bEditorToolbar;
     protected $_bEditorAutoAttach;
+    protected $_bEnableMediaPriority;
     protected $_iLimitAttachLinks;
 
     protected $_bUnhideRestored;
@@ -456,6 +457,7 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
 
         $this->_bEditorToolbar = getParam($sOptionPrefix . 'enable_editor_toolbar') == 'on';
         $this->_bEditorAutoAttach = getParam($sOptionPrefix . 'editor_auto_attach_insertion') == 'on';
+        $this->_bEnableMediaPriority = getParam($sOptionPrefix . 'enable_media_priority') == 'on';
         $this->_iLimitAttachLinks = (int)getParam($sOptionPrefix . 'limit_attach_links');
 
         $this->_bUnhideRestored = false;
@@ -609,6 +611,11 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
     	return $this->_bEditorAutoAttach;
     }
 
+    public function isMediaPriority()
+    {
+        return $this->_bEnableMediaPriority;
+    }
+
     public function isUnhideRestored()
     {
         return $this->_bUnhideRestored;

+ 15 - 0
modules/boonex/timeline/classes/BxTimelineDb.php

@@ -237,6 +237,21 @@ class BxTimelineDb extends BxBaseModNotificationsDb
         )) > 0;
     }
 
+    public function hasMedia($iEventId)
+    {
+        $bResult = false;
+
+        foreach($this->_aTablesMedia as $sType) {
+            $aMedia = $this->getMedia($sType, $iEventId);
+            if(!empty($aMedia) && is_array($aMedia)) {
+                $bResult = true;
+                break;
+            }
+        }
+
+        return $bResult;
+    }
+
     public function getMedia($sType, $iEventId, $iOffset = 0, $bFullInfo = false)
     {
     	$sTableMedia = $this->_aTablesMedia[$sType];

+ 11 - 5
modules/boonex/timeline/classes/BxTimelineFormPost.php

@@ -458,16 +458,22 @@ class BxTimelineFormPost extends BxBaseModGeneralFormEntry
         ));
     }
 
-    protected function _getGhostTmplVars($sName, $aContentInfo = array())
+    protected function _getGhostTmplVars($sName, $aContentInfo = [])
     {
-    	return array (
+    	return [
+            'js_object' => $this->_oModule->_oConfig->getJsObject('post'),
             'name' => $this->aInputs[$sName]['name'],
             'content_id' => (int)$this->aInputs[$sName]['content_id'],
-        );
+        ];
     }
-
-    
     
+    protected function _getPhotoGhostTmplVars($aContentInfo = [])
+    {
+        return array_merge(parent::_getPhotoGhostTmplVars($aContentInfo), [
+            'js_object' => $this->_oModule->_oConfig->getJsObject('post'),
+        ]);
+    }
+
     protected function _resetMode()
     {
         $this->_bPublicMode = false;

+ 10 - 1
modules/boonex/timeline/classes/BxTimelineMenuPostAttachments.php

@@ -75,7 +75,16 @@ class BxTimelineMenuPostAttachments extends BxTemplMenu
             ));
         }
 
-        return parent::_getMenuItem($a);
+        $aResult = parent::_getMenuItem($a);
+
+        switch($a['name']) {
+            case 'add-link': 
+                if($this->_oModule->_oConfig->isMediaPriority() && $this->_oModule->hasMedia($this->_iEvent))
+                    $aResult['class_link'] = 'bx-btn-disabled';
+                break;
+        }
+
+        return $aResult;
     }
 }
 

+ 54 - 0
modules/boonex/timeline/classes/BxTimelineModule.php

@@ -732,6 +732,29 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         echoJson($aResult);
     }
 
+    public function actionDeleteAttachLinks()
+    {
+    	$iUserId = $this->getUserId();
+        $iEventId = bx_process_input(bx_get('event_id'), BX_DATA_INT);
+
+        $aParams = $iEventId > 0 ? ['type' => 'event_id', 'event_id' => $iEventId] : ['type' => 'unused', 'profile_id' => $iUserId];
+        $aLinks = $this->_oDb->getLinksBy($aParams);
+
+        $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'));
+
+        $aUrls = [];
+        foreach($aLinks as $aLink) {
+            $aUrls[] = $aLink['url'];
+
+            if(!empty($aLink['media_id']))
+                $oStorage->deleteFile($aLink['media_id']);
+
+            $this->_oDb->deleteLink($aLink['id']);
+        }
+
+        echoJson(['code' => 0, 'urls' => $aUrls]);
+    }
+
     public function actionGetAttachLinkForm()
     {
         $iEventId = 0;
@@ -5021,6 +5044,37 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         return $aResult;
     }
 
+    public function hasMedia($iEventId, $iProfileId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!empty($iEventId))
+            return $this->_oDb->hasMedia($iEventId);
+
+        if(empty($iProfileId))
+            $iProfileId = $this->_iProfileId;
+
+        $aTypes = [
+            $CNF['FIELD_PHOTO'], 
+            $CNF['FIELD_VIDEO'], 
+            $CNF['FIELD_FILE']
+        ];
+
+        $bResult = false;
+        foreach($aTypes as $sType) {
+            $sStorage = $this->_oConfig->getObject('storage_' . strtolower($sType) . 's');
+            if(($oStorage = BxDolStorage::getObjectInstance($sStorage)) !== false) {
+                $aGhosts = $oStorage->getGhosts($iProfileId, 0);
+                if(!empty($aGhosts) && is_array($aGhosts)) {
+                    $bResult = true;
+                    break;
+                }
+            }
+        }
+
+        return $bResult;
+    }
+
     public function rebuildSlice()
     {
         if(!$this->_oConfig->isCacheTable())

+ 1 - 0
modules/boonex/timeline/classes/BxTimelineTemplate.php

@@ -139,6 +139,7 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
 
         return $this->getJsCode('post', array_merge(array(
             'bAutoAttach' => $this->_oConfig->isEditorAutoAttach(),
+            'bMediaPriority' => $this->_oConfig->isMediaPriority(),
             'iLimitAttachLinks' => $this->_oConfig->getLimitAttachLinks(),
             'sLimitAttachLinksErr' => bx_js_string(_t('_bx_timeline_txt_err_attach_links')),
             'oAttachedLinks' => $this->_oDb->getLinksBy(array(

+ 12 - 0
modules/boonex/timeline/classes/BxTimelineUploaderHTML5Attach.php

@@ -23,6 +23,18 @@ class BxTimelineUploaderHTML5Attach extends BxTemplUploaderHTML5
 
         $this->_sButtonTemplate = 'uploader_button_html5_attach.html';
     }
+
+    public function getUploaderJs($mixedGhostTemplate, $isMultiple = true, $aParams = [], $bDynamic = false)
+    {
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('post');
+
+        $aParams = array_merge($aParams, [
+            'on_upload' => 'function(iContentId) {' . $sJsObject . '.onAttachMediaUpload(iContentId);}',
+            'on_restore_ghosts' => 'function(aData) {' . $sJsObject . '.onAttachMediaRestoreGhosts(aData);}',
+        ]);
+
+        return parent::getUploaderJs($mixedGhostTemplate, $isMultiple, $aParams, $bDynamic);
+    }
 }
 
 /** @} */

+ 1 - 0
modules/boonex/timeline/install/langs/en.xml

@@ -61,6 +61,7 @@
     <string name="_bx_timeline_option_cache_table_interval"><![CDATA[Interval of time (in days) to get events for cache table]]></string>
     <string name="_bx_timeline_option_enable_editor_toolbar"><![CDATA[Enable post form editor toolbar]]></string>
     <string name="_bx_timeline_option_editor_auto_attach_insertion"><![CDATA[Treat images inserted in the editor as attachments]]></string>
+    <string name="_bx_timeline_option_enable_media_priority"><![CDATA[Enable priority of media content over links in attachments]]></string>
     <string name="_bx_timeline_option_limit_attach_links"><![CDATA[Limit number of attached links (0 - no limit)]]></string>
 
     <string name="_bx_timeline_form_post"><![CDATA[Post]]></string>

+ 1 - 0
modules/boonex/timeline/install/sql/enable.sql

@@ -362,6 +362,7 @@ SET @iCategId = LAST_INSERT_ID();
 INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_params`, `check_error`, `extra`, `order`) VALUES
 ('bx_timeline_enable_editor_toolbar', '', @iCategId, '_bx_timeline_option_enable_editor_toolbar', 'checkbox', '', '', '', '', 1),
 ('bx_timeline_editor_auto_attach_insertion', '', @iCategId, '_bx_timeline_option_editor_auto_attach_insertion', 'checkbox', '', '', '', '', 2),
+('bx_timeline_enable_media_priority', '', @iCategId, '_bx_timeline_option_enable_media_priority', 'checkbox', '', '', '', '', 3),
 ('bx_timeline_limit_attach_links', '0', @iCategId, '_bx_timeline_option_limit_attach_links', 'digit', '', '', '', '', 10);
 
 

+ 66 - 0
modules/boonex/timeline/js/post.js

@@ -18,6 +18,7 @@ function BxTimelinePost(oOptions) {
     this._bAutoAttach = oOptions.bAutoAttach == undefined ? false : oOptions.bAutoAttach;
     this._sAutoUploader = oOptions.sAutoUploader == undefined ? '' : oOptions.sAutoUploader;
     this._sAutoUploaderId = oOptions.sAutoUploaderId == undefined ? '' : oOptions.sAutoUploaderId;
+    this._bMediaPriority = oOptions.bMediaPriority == undefined ? false : oOptions.bMediaPriority;
     this._iLimitAttachLinks = oOptions.iLimitAttachLinks == undefined ? 0 : oOptions.iLimitAttachLinks;
     this._sLimitAttachLinksErr = oOptions.sLimitAttachLinksErr == undefined ? '' : oOptions.sLimitAttachLinksErr;
     this._oAttachedLinks = oOptions.oAttachedLinks == undefined ? {} : oOptions.oAttachedLinks;
@@ -214,6 +215,9 @@ BxTimelinePost.prototype.deleteAttachLink = function(oLink, iId)
 
 BxTimelinePost.prototype.showAttachLink = function(oLink, iEventId)
 {
+    if($(oLink).hasClass('bx-btn-disabled'))
+        return false;
+
     if(this._iLimitAttachLinks != 0 && Object.keys(this._oAttachedLinks).length >= this._iLimitAttachLinks) {
         bx_alert(this._sLimitAttachLinksErr);
         return false;
@@ -232,6 +236,68 @@ BxTimelinePost.prototype.showAttachLink = function(oLink, iEventId)
     return false;
 };
 
+BxTimelinePost.prototype.onAttachMediaUpload = function(iEventId)
+{
+    var $this = this;
+    var oData = this._getDefaultData();
+    oData['event_id'] = iEventId;
+
+    if(this._bMediaPriority) {
+        var oLinkFormField = $('#' + this._aHtmlIds['attach_link_form_field'] + iEventId);
+
+        oLinkFormField.parents('form:first').find('.bx-menu-item.add-link .bx-btn').addClass('bx-btn-disabled');
+
+        if(oLinkFormField.children().length > 0) {
+            oLinkFormField.hide();
+
+            jQuery.post (
+                this._sActionsUrl + 'delete_attach_links/',
+                oData,
+                function(oData) {
+                    if(!oData)
+                        return;
+
+                    var fContinue = function() {
+                        if(oData.code == undefined)
+                            return;
+
+                        if(oData.code == 0) {
+                            oLinkFormField.html('');
+
+                            if(oData.urls != undefined && oData.urls.length != 0)
+                                for(var i in oData.urls)
+                                    delete $this._oAttachedLinks[oData.urls[i]];
+                        }
+
+                        oLinkFormField.show();
+                    };
+
+                    if(oData.message != undefined)
+                        bx_alert(oData.message, fContinue);
+                    else
+                        fContinue();
+                },
+                'json'
+            );
+        }
+    }
+};
+
+BxTimelinePost.prototype.onAttachMediaRestoreGhosts = function(aData)
+{
+    //perform some action after attached media's ghosts restoration.
+};
+
+BxTimelinePost.prototype.onAttachMediaDeleteGhost = function(iEventId, sMsg)
+{
+    if(sMsg != 'ok') 
+        return;
+
+    var oForm = $('#' + this._aHtmlIds['attach_link_form_field'] + iEventId).parents('form:first');
+    if(!oForm.find('.bx-tl-uploader-file').length)
+        oForm.find('.bx-menu-item.add-link .bx-btn').removeClass('bx-btn-disabled');
+};
+
 BxTimelinePost.prototype._getForm = function(oElement)
 {
     var $this = this;

+ 2 - 2
modules/boonex/timeline/template/uploader_nfw.html

@@ -5,7 +5,7 @@
             <img src="<bx_image_url:spacer.gif />" style="background-image:url({file_icon})" />
         </div>
         <span class="bx-base-general-uploader-ghost">
-            <a class="bx-btn bx-btn-small" href="javascript:void(0);" title="<bx_text:_Delete />" onclick="{js_instance_name}.deleteGhost('{file_id}')"><i class="sys-icon times"></i></a>
+            <a class="bx-btn bx-btn-small" href="javascript:void(0);" title="<bx_text:_Delete />" onclick="{js_instance_name}.deleteGhost('{file_id}', function(sMsg){__js_object__.onAttachMediaDeleteGhost(__content_id__, sMsg);})"><i class="sys-icon times"></i></a>
         </span>
     </div>
-</div>
+</div>

+ 1 - 1
template/menu_buttons_icon_hor.html

@@ -1,5 +1,5 @@
 <ul class="bx-menu-btns-icon-hor bx-menu-object-__object__ flex flex-row flex-wrap">
-    <bx_repeat:menu_items><li class="bx-menu-item __name__ my-1 __class_add__"><a class="bx-btn __name__ mr-4" href="__link__" <bx_if:onclick>onclick="__onclick__"</bx_if:onclick> title="__title_attr__"__attrs__>
+    <bx_repeat:menu_items><li class="bx-menu-item __name__ my-1 __class_add__"><a class="bx-btn __name__ mr-4 __class_link__" href="__link__" <bx_if:onclick>onclick="__onclick__"</bx_if:onclick> title="__title_attr__"__attrs__>
         <bx_include_auto:menu_icon.html />
     </a></li></bx_repeat:menu_items>
 </ul>

+ 1 - 0
template/scripts/BxBaseMenu.php

@@ -226,6 +226,7 @@ class BxBaseMenu extends BxDolMenu
 
         $a['class_add'] = $this->_isSelected($a) ? 'bx-menu-tab-active' : '';
         $a['class_add'] .= $this->_getVisibilityClass($a);
+        $a['class_link'] = '';
 
         $a['link'] = isset($a['link']) ? $this->_oPermalinks->permalink($a['link']) : 'javascript:void(0);';
         $a['title_attr'] = bx_html_attribute(strip_tags($a['title']));

+ 3 - 1
template/uploader_button_crop_js.html

@@ -5,6 +5,8 @@ __uploader_instance_name__ = new BxDolUploaderCrop('__engine__', '__storage_obje
     'storage_private' : '__storage_private__',
     'template_error_msg': '<div class="bx-uploader-msg-err">{error}</div>',
     'template_ghost': __template_ghost__,
-    'reordering': __is_init_reordering__
+    'reordering': __is_init_reordering__,
+    'on_upload': __on_upload__,
+    'on_restore_ghosts': __on_restore_ghosts__
 });
 <bx_if:restore_ghosts>__uploader_instance_name__.restoreGhosts(__is_init_reordering__);</bx_if:restore_ghosts>

+ 2 - 0
template/uploader_button_html5_js.html

@@ -15,5 +15,7 @@ __uploader_instance_name__ = new BxDolUploaderHTML5('__engine__', '__storage_obj
     'dictFileTooBig': '<bx_text_js:_sys_uploader_html5_file_is_too_big />',
     'dictMaxFilesExceeded': '<bx_text_js:_sys_uploader_html5_number_of_files_exceeded />',
     'dictInvalidFileType': '<bx_text_js:_sys_uploader_html5_invalid_file_type />',
+    'on_upload': __on_upload__,
+    'on_restore_ghosts': __on_restore_ghosts__
 });
 <bx_if:restore_ghosts>__uploader_instance_name__.restoreGhosts(__is_init_reordering__);</bx_if:restore_ghosts>