Skip to content

Commit

Permalink
Ticket #2754 - Reorder storage ghosts.
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonLV committed Sep 9, 2021
1 parent e65aa69 commit f621811
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 34 deletions.
2 changes: 1 addition & 1 deletion inc/classes/BxDolSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ function getJoins ($bRenameMode = true)
if (isset($aValue['groupTable']))
$aSql['groupBy'] = "GROUP BY `{$aValue['groupTable']}`.`{$aValue['groupField']}`, ";
$sOn = isset($aValue['mainTable']) ? $aValue['mainTable'] : $this->aCurrent['table'];
$aSql['join'] .= " {$aValue['type']} JOIN `{$aValue['table']}` $sTableAlias ON `{$sAlias}`.`{$aValue['onField']}`=`$sOn`.`{$aValue['mainField']}`";
$aSql['join'] .= " {$aValue['type']} JOIN `{$aValue['table']}` $sTableAlias ON " . (!empty($aValue['on_sql']) ? $aValue['on_sql'] : "`{$sAlias}`.`{$aValue['onField']}`=`$sOn`.`{$aValue['mainField']}`");
$aSql['ownFields'] .= $this->setFieldUnit($aValue['mainField'], $sOn, '', $bRenameMode);
}
$aSql['joinFields'] = trim($aSql['joinFields'], ', ');
Expand Down
18 changes: 18 additions & 0 deletions inc/classes/BxDolStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,24 @@ public function getGhosts($iProfileId, $iContentId = false, $isCheckAllAccountPr

return $this->_oDb->getGhosts($iProfileId, $iContentId, $isAdmin);
}

/**
* Reorder ghost/orphaned files for particular content/user.
* @param $iProfileId profile id
* @param $iContentId content id, or false to not consider content id at all
* @param $aGhosts an ordered list of ghost/orphaned files' IDs.
* @return boolean result of operation
*/
public function reorderGhosts($iProfileId, $iContentId, $aGhosts)
{
$bResult = true;

$iGhosts = count($aGhosts);
for($i = 0; $i < $iGhosts; $i++)
$bResult &= $this->_oDb->updateGhostOrder($iProfileId, $iContentId, (int)$aGhosts[$i], $i);

return $bResult;
}

/**
* Update ghosts' content id.
Expand Down
22 changes: 21 additions & 1 deletion inc/classes/BxDolStorageQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,26 @@ public function insertGhosts($mixedFileIds, $iProfileId, $iContentId = 0)
return $iCount;
}

public function updateGhostOrder($iProfileId, $iContentId, $iFileId, $iOrder)
{
$aBindings = array(
'object' => $this->_aObject['object'],
'content_id' => $iContentId,
'id' => $iFileId,
'order' => $iOrder,
);

$sWhereClause = " AND `object`=:object AND `content_id`=:content_id AND `id`=:id";

if(!empty($iProfileId)) {
$aBindings['profile_id'] = $iProfileId;

$sWhereClause .= " AND `profile_id`=:profile_id";
}

return $this->query("UPDATE `sys_storage_ghosts` SET `order`=:order WHERE 1" . $sWhereClause, $aBindings) !== false;
}

public function updateGhostsContentId($mixedFileIds, $iProfileId, $iContentId, $aProfiles = array(), $isAdmin = false)
{
$aBindings = array(
Expand Down Expand Up @@ -325,7 +345,7 @@ public function getFiles($mixedProfileId, $isGhostsOnly = false, $iContentId = f
}
}

$sQuery = "SELECT `f`.* FROM " . $this->_sTableFiles . " AS `f` " . $sJoin . $sWhere;
$sQuery = "SELECT `f`.* FROM " . $this->_sTableFiles . " AS `f` " . $sJoin . $sWhere . " ORDER BY `g`.`order` ASC";
return $this->getAll($sQuery, $aBindings);
}

Expand Down
36 changes: 36 additions & 0 deletions inc/classes/BxDolUploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,12 +341,48 @@ public function getGhosts($iProfileId, $sFormat, $sImagesTranscoder = false, $iC
$a[$aFile['id']] = array_merge($aVars, $this->getGhostTemplateVars($aFile, $iProfileId, $iContentId, $oStorage, $oImagesTranscoder));
}

if ('array' == $sFormat) {
return $a;
}
else if ('json' == $sFormat) {
return json_encode($a);
} else { // html format is not suported for this data type
return false;
}
}

public function getGhostsWithOrder($iProfileId, $sFormat, $sImagesTranscoder = false, $iContentId = false)
{
$a = $this->getGhosts($iProfileId, 'array', $sImagesTranscoder, $iContentId);
if(!empty($a) && is_array($a))
$a = ['g' => $a, 'o' => array_keys($a)];

if ('json' == $sFormat) {
return json_encode($a);
} else { // html format is not suported for this data type
return false;
}
}

/**
* Reorder uploaded ghosts.
* @param $iProfileId - profile id to get orphaned files from
* @param $sFormat - output format, only 'json' output formt is supported
* @param $aGhosts - an array of ordered ghosts' IDs.
* @param $iContentId - content id to order orphaned files for, false by default
* @return JSON string
*/
public function reorderGhosts($iProfileId, $sFormat, $aGhosts, $iContentId = false)
{
$bResult = true;
if(($oStorage = BxDolStorage::getObjectInstance($this->_sStorageObject)) !== false)
$bResult = $oStorage->reorderGhosts($this->isAdmin($iContentId) && $iContentId ? false : $iProfileId, $iContentId, $aGhosts);

if($sFormat == 'json')
return json_encode($bResult ? [] : ['msg' => _t('_error occured')]);
else
return $bResult;
}

/**
* Delete file by file id, usually ghost file
Expand Down
71 changes: 54 additions & 17 deletions inc/js/classes/BxDolUploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ BxDolUploaderSimple.prototype.cancelAll = function () {
this.onUploadCompleted(_t('_sys_uploader_upload_canceled'));
}

BxDolUploaderSimple.prototype.restoreGhosts = function () {
BxDolUploaderSimple.prototype.restoreGhosts = function (bInitReordering, onComplete) {
var sUrl = this._getUrlWithStandardParams() + '&img_trans=' + this._sImagesTranscoder + '&a=restore_ghosts&f=json' + '&c=' + this._iContentId + '&_t=' + escape(new Date());
var $this = this;

Expand All @@ -146,28 +146,65 @@ BxDolUploaderSimple.prototype.restoreGhosts = function () {
$('#' + $this._sResultContainerId + ' .bx-uploader-ghost').remove();

if ('object' === typeof(aData)) {
$.each(aData, function(iFileId, oVars) {
var oFileContainer = $('#' + $this._getFileContainerId(iFileId));
if (oFileContainer.length > 0)
return;
var sHTML;
if (typeof $this._sTemplateGhost == 'object')
sHTML = $this._sTemplateGhost[iFileId];
else
sHTML = $this._sTemplateGhost;
for (var i in oVars)
sHTML = sHTML.replace (new RegExp('{'+i+'}', 'g'), oVars[i]);

$('#' + $this._sResultContainerId).prepend(sHTML);

oFileContainer.find('.bx-uploader-ghost-preview img').hide().fadeIn(1000);
});
if('object' === typeof(aData.g) && 'object' === typeof(aData.o))
for(var i in aData.o) {
var iFileId = aData.o[i];
$this.showGhost(iFileId, aData.g[iFileId]);
}
else
$.each(aData, function(iFileId, oVars) {
$this.showGhost(iFileId, oVars);
});

$('#' + $this._sResultContainerId).bx_show_more_check_overflow();

if(bInitReordering) {
$('#' + $this._sResultContainerId).sortable({
items: '.bx-uploader-ghost',
start: function(oEvent, oUi) {
oUi.item.addClass('bx-uploader-ghost-dragging');
},
stop: function(oEvent, oUi) {
oUi.item.removeClass('bx-uploader-ghost-dragging');

$this.reorderGhosts(oUi.item);
}
});
}

if(typeof onComplete === 'function')
return onComplete(aData);
}
});
};

BxDolUploaderSimple.prototype.reorderGhosts = function(oDraggable) {
var sUrl = this._getUrlWithStandardParams() + '&a=reorder_ghosts&f=json' + '&c=' + this._iContentId + '&' + $('#' + this._sResultContainerId).sortable('serialize', {key: 'ghosts[]'}) + '&_t=' + escape(new Date());

$.getJSON(sUrl, function (aData) {
processJsonData(aData);
});
};

BxDolUploaderSimple.prototype.showGhost = function(iId, oVars) {
var oFileContainer = $('#' + this._getFileContainerId(iId));
if(oFileContainer.length > 0)
return;

var sHTML;
if (typeof this._sTemplateGhost == 'object')
sHTML = this._sTemplateGhost[iId];
else
sHTML = this._sTemplateGhost;

for(var i in oVars)
sHTML = sHTML.replace (new RegExp('{' + i + '}', 'g'), oVars[i]);

$('#' + this._sResultContainerId).append(sHTML);

oFileContainer.find('.bx-uploader-ghost-preview img').hide().fadeIn(1000);
};

BxDolUploaderSimple.prototype.deleteGhost = function (iFileId) {
var sUrl = this._getUrlWithStandardParams() + '&a=delete&id=' + iFileId;
var $this = this;
Expand Down
1 change: 1 addition & 0 deletions install/sql/system.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,7 @@ CREATE TABLE IF NOT EXISTS `sys_storage_ghosts` (
`object` varchar(64) NOT NULL,
`content_id` int(11) NOT NULL,
`created` int(10) unsigned NOT NULL,
`order` int(11) NOT NULL default '0',
UNIQUE KEY `id` (`id`,`object`),
KEY `created` (`created`),
KEY `profile_object_content` (`profile_id`,`object`,`content_id`)
Expand Down
3 changes: 3 additions & 0 deletions modules/base/general/template/css/forms.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@

/* uploader */
.bx-form-input-files-result.ui-sortable .bx-uploader-ghost {
cursor: move;
}

.bx-uploader-ghost .bx-base-general-icon-wrapper {
float:left;
Expand Down
1 change: 1 addition & 0 deletions modules/boonex/albums/classes/BxAlbumsConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function __construct($aModule)
'PARAM_NUM_RSS' => 'bx_albums_rss_num',
'PARAM_SEARCHABLE_FIELDS' => 'bx_albums_searchable_fields',
'PARAM_PER_PAGE_FOR_FAVORITES_LISTS' => 'bx_albums_per_page_for_favorites_lists',
'PARAM_ORDER_BY_GHOSTS' => true,

// objects
'OBJECT_STORAGE' => 'bx_albums_files',
Expand Down
12 changes: 11 additions & 1 deletion modules/boonex/albums/classes/BxAlbumsDb.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,17 @@ public function getFileTitle($iFileId)

public function getMediaInfoById($iMediaId)
{
$sQuery = $this->prepare ("SELECT `f2e`.*, `f`.`added` FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` AS `f2e` INNER JOIN `" . $this->_oConfig->CNF['TABLE_FILES'] . "` AS `f` ON (`f`.`id` = `f2e`.`file_id`) INNER JOIN `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` AS `e` ON (`e`.`id` = `f2e`.`content_id`) WHERE `f2e`.`id` = ?", $iMediaId);
$CNF = &$this->_oConfig->CNF;

$sSelectClause = "`f2e`.*, `f`.`added`";
$sJoinClause = "INNER JOIN `" . $CNF['TABLE_FILES'] . "` AS `f` ON (`f`.`id` = `f2e`.`file_id`) INNER JOIN `" . $CNF['TABLE_ENTRIES'] . "` AS `e` ON (`e`.`id` = `f2e`.`content_id`)";

if($CNF['PARAM_ORDER_BY_GHOSTS']) {
$sSelectClause .= ", `g`.`order` as `gorder`";
$sJoinClause .= $this->prepareAsString("INNER JOIN `sys_storage_ghosts` AS `g` ON `g`.`id`=`f2e`.`file_id` AND `g`.`content_id`=`f2e`.`content_id` AND `g`.`object`=?", $CNF['OBJECT_STORAGE']);
}

$sQuery = $this->prepare("SELECT " . $sSelectClause . " FROM `" . $CNF['TABLE_FILES2ENTRIES'] . "` AS `f2e` " . $sJoinClause . " WHERE `f2e`.`id` = ?", $iMediaId);
return $this->getRow($sQuery);
}

Expand Down
5 changes: 5 additions & 0 deletions modules/boonex/albums/classes/BxAlbumsFormEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public function __construct($aInfo, $oTemplate = false)
{
$this->MODULE = 'bx_albums';
parent::__construct($aInfo, $oTemplate);

$CNF = &$this->_oModule->_oConfig->CNF;

if (isset($CNF['FIELD_PHOTO']) && isset($this->aInputs[$CNF['FIELD_PHOTO']]))
$this->aInputs[$CNF['FIELD_PHOTO']]['init_reordering'] = true;
}

public function processFiles ($sFieldFile, $iContentId = 0, $isAssociateWithContent = false)
Expand Down
45 changes: 37 additions & 8 deletions modules/boonex/albums/classes/BxAlbumsSearchResultMedia.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ class BxAlbumsSearchResultMedia extends BxBaseModTextSearchResult

function __construct($sMode = '', $aParams = array())
{

$this->sUnitTemplateLiveSearch = 'unit_media_live_search.html';
$aParams['unit_views'] = array('gallery' => 'unit_media.html', 'showcase' => 'unit_showcase.html');

$aParams['unit_views'] = array('gallery' => 'unit_media.html', 'showcase' => 'unit_showcase.html');
parent::__construct($sMode, $aParams);

$this->aCurrent = array(
Expand All @@ -33,7 +32,7 @@ function __construct($sMode = '', $aParams = array())
'restriction' => array(
'author' => array('value' => '', 'field' => 'author', 'operator' => '='),
'album' => array('value' => '', 'field' => 'content_id', 'operator' => '='),
'featured' => array('value' => '', 'field' => 'featured', 'operator' => '<>'),
'featured' => array('value' => '', 'field' => 'featured', 'operator' => '<>'),
),
'join' => array(
'albums' => array(
Expand Down Expand Up @@ -79,13 +78,17 @@ function __construct($sMode = '', $aParams = array())

switch ($sMode) {
case 'album':
$this->aCurrent['restriction']['album']['value'] = (int)$aParams['album_id'];
$this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . (int)$aParams['album_id']);
$iAlbumId = (int)$aParams['album_id'];
$this->aCurrent['restriction']['album']['value'] = $iAlbumId;
$this->sBrowseUrl = BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iAlbumId);
$this->aCurrent['title'] = _t('_bx_albums_page_title_browse_media_in_album');
$this->aCurrent['rss']['link'] = 'modules/?r=albums/rss_media/' . $sMode . '/' . (int)$aParams['album_id'];
$this->aCurrent['rss']['link'] = 'modules/?r=albums/rss_media/' . $sMode . '/' . $iAlbumId;
$this->aCurrent['sorting'] = 'order';
$this->sOrderDirection = 'ASC';
$this->setProcessPrivateContent(true);

if($CNF['PARAM_ORDER_BY_GHOSTS'])
$this->_updateCurrentForOrderByGhosts();
break;

case 'favorite':
Expand Down Expand Up @@ -159,6 +162,10 @@ function getAlterOrder()
$aSql['order'] = " ORDER BY `" . $sTable . "`.`order` " . $sWay . ", `" . $sTable . "`.`id` " . $sWay . " ";
break;

case 'order_by_ghosts':
$aSql['order'] = " ORDER BY `g`.`order` " . $sWay . ", `" . $sTable . "`.`id` " . $sWay . " ";
break;

case 'last':
$aSql['order'] = " ORDER BY `f`.`added` " . $sWay . ", `" . $sTable . "`.`id` " . $sWay . " ";
break;
Expand Down Expand Up @@ -212,13 +219,18 @@ public function getNextPrevItem($aMediaInfo, $isNext)
foreach ($aRestrictions as $sKey)
if (0 === strpos($sKey, 'privacy_'))
unset($this->aCurrent['restriction'][$sKey]);

switch ($this->aCurrent['sorting']) {
case 'order':
$this->sOrderDirection = $isNext ? 'ASC' : 'DESC';
$sOper = $isNext ? '>' : '<';
$this->aCurrent['restriction_sql'] = " AND (`{$this->aCurrent['table']}`.`order` {$sOper} {$aMediaInfo['order']} OR (`{$this->aCurrent['table']}`.`order` = {$aMediaInfo['order']} AND `{$this->aCurrent['table']}`.`id` {$sOper} {$aMediaInfo['id']})) ";
break;
case 'order_by_ghosts':
$this->sOrderDirection = $isNext ? 'ASC' : 'DESC';
$sOper = $isNext ? '>' : '<';
$this->aCurrent['restriction_sql'] = " AND (`g`.`order` {$sOper} {$aMediaInfo['gorder']} OR (`g`.`order` = {$aMediaInfo['gorder']} AND `{$this->aCurrent['table']}`.`id` {$sOper} {$aMediaInfo['id']})) ";
break;
case 'last':
$this->aCurrent['restriction_sql'] = " AND (`f`.`added` {$sOper} {$aMediaInfo['added']} OR (`f`.`added` = {$aMediaInfo['added']} AND `{$this->aCurrent['table']}`.`id` {$sOper} {$aMediaInfo['id']})) ";
break;
Expand All @@ -241,6 +253,23 @@ function getRssUnitLink (&$a)
{
return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $this->oModule->_oConfig->CNF['URI_VIEW_MEDIA'] . '&id=' . $a['id']);
}

protected function _updateCurrentForOrderByGhosts()
{
$CNF = &$this->oModule->_oConfig->CNF;

$this->aCurrent['join']['ghosts'] = [
'type' => 'INNER',
'table' => 'sys_storage_ghosts',
'table_alias' => 'g',
'mainField' => 'file_id',
'on_sql' => $this->oModule->_oDb->prepareAsString(" `g`.`id`=`bx_albums_files2albums`.`file_id` AND `g`.`content_id`=`bx_albums_files2albums`.`content_id` AND `g`.`object`=? ", $CNF['OBJECT_STORAGE']),
'joinFields' => array('order'),
];
$this->aCurrent['sorting'] = 'order_by_ghosts';
$this->sOrderDirection = 'ASC';
}

/*
function displaySearchUnit ($aData)
{
Expand Down
8 changes: 7 additions & 1 deletion storage_uploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@
case 'restore_ghosts':
header('Content-Type: application/json; charset=utf-8');
$sImagesTranscoder = bx_process_input(bx_get('img_trans'));
echo $oUploader->getGhosts((int)bx_get_logged_profile_id(), $sFormat, $sImagesTranscoder, $iContentId);
echo $oUploader->getGhostsWithOrder((int)bx_get_logged_profile_id(), $sFormat, $sImagesTranscoder, $iContentId);
break;

case 'reorder_ghosts':
header('Content-Type: application/json; charset=utf-8');
$aGhosts = bx_process_input(bx_get('ghosts'));
echo $oUploader->reorderGhosts((int)bx_get_logged_profile_id(), $sFormat, $aGhosts, $iContentId);
break;

case 'delete':
Expand Down
8 changes: 3 additions & 5 deletions template/form_field_uploader.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

<div class="bx-form-input-files-uploaders bx-def-margin-sec-top">
__uploaders_buttons__
<div class="bx-clear"></div>
Expand All @@ -8,9 +7,8 @@
<div id="__id_container_errors__" class="bx-form-input-files-errors"></div>
<div id="__id_container_result__" class="bx-form-input-files-result bx-clearfix"></div>
<script>
$(document).ready(function(){
$(document).ready(function() {
if (__is_init_ghosts__)
__uploader_instance_name__.restoreGhosts();
__uploader_instance_name__.restoreGhosts(__is_init_reordering__);
});
</script>

</script>
Loading

0 comments on commit f621811

Please sign in to comment.