AntonLV 6 éve
szülő
commit
d191b61d2c

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

@@ -79,6 +79,7 @@
 
     <string name="_bx_timeline_form_attach_link"><![CDATA[Прикрепить ссылку]]></string>
     <string name="_bx_timeline_form_attach_link_display_add"><![CDATA[Прикрепить ссылку]]></string>
+    <string name="_bx_timeline_form_attach_link_input_sys_event_id"><![CDATA[ID события]]></string>
     <string name="_bx_timeline_form_attach_link_input_sys_url"><![CDATA[Url]]></string>
     <string name="_bx_timeline_form_attach_link_input_url"><![CDATA[Добавить ссылку]]></string>
     <string name="_bx_timeline_form_attach_link_input_url_err"><![CDATA[Необходима правильная ссылка. Пожалуйста, заполните это поле.]]></string>

+ 29 - 5
modules/boonex/timeline/classes/BxTimelineConfig.php

@@ -55,6 +55,7 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
     protected $_sTranscoderObjectView;
     protected $_aPhotoUploaders;
     protected $_aVideoUploaders;
+    protected $_aItemToUploader;
 
     protected $_sMenuItemManage;
     protected $_sMenuItemActions;
@@ -87,6 +88,10 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
             'FIELD_PUBLISHED' => 'published',
             'FIELD_TITLE' => 'title',
             'FIELD_TEXT' => 'description',
+            'FIELD_ATTACHMENTS' => 'attachments',
+            'FIELD_LINK' => 'link',
+            'FIELD_PHOTO' => 'photo',
+            'FIELD_VIDEO' => 'video',
             'FIELD_STATUS' => 'status',
             'FIELD_STICKED' => 'sticked',
             'FIELD_DATE' => 'date',
@@ -111,6 +116,10 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
             	'mp4' => 'bx_timeline_videos_mp4', 
             	'mp4_hd' => 'bx_timeline_videos_mp4_hd'
             ),
+            'OBJECT_UPLOADER_PHOTO_SIMPLE' => $this->_sName . '_simple_photo',
+            'OBJECT_UPLOADER_PHOTO_HTML5' => $this->_sName . '_html5_photo',
+            'OBJECT_UPLOADER_VIDEO_SIMPLE' => $this->_sName . '_simple_video',
+            'OBJECT_UPLOADER_VIDEO_HTML5' => $this->_sName . '_html5_video',
             'OBJECT_GRID_ADMINISTRATION' => $this->_sName . '_administration',
             'OBJECT_MENU_ENTRY_ATTACHMENTS' => $this->_sName . '_menu_post_attachments',
             'OBJECT_METATAGS' => $this->_sName,
@@ -207,8 +216,15 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
         $this->_aHandlerDescriptor = array('module_name' => '', 'module_method' => '', 'module_class' => '', 'groupable' => '', 'group_by' => '');
         $this->_sHandlersMethod = 'get_timeline_data';
 
-        $this->_aPhotoUploaders = array($this->_sName . '_simple_photo');
-        $this->_aVideoUploaders = array($this->_sName . '_simple_video');
+        $this->_aPhotoUploaders = array($this->CNF['OBJECT_UPLOADER_PHOTO_SIMPLE']);
+        $this->_aVideoUploaders = array($this->CNF['OBJECT_UPLOADER_VIDEO_SIMPLE']);
+
+        $this->_aItemToUploader = array(
+            'add-photo-simple' => $this->CNF['OBJECT_UPLOADER_PHOTO_SIMPLE'],
+            'add-photo-html5' => $this->CNF['OBJECT_UPLOADER_PHOTO_HTML5'],
+            'add-video-simple' => $this->CNF['OBJECT_UPLOADER_VIDEO_SIMPLE'],
+            'add-video-html5' => $this->CNF['OBJECT_UPLOADER_VIDEO_HTML5'],
+        );
 
         $this->_bJsMode = false;
         $this->_aJsClasses = array(
@@ -245,7 +261,7 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
             ),
             'post' => array(
                 'attach_link_popup' =>  $sHp . '-attach-link-popup',
-                'attach_link_form_field' => $sHp . '-attach-link-form_field',
+                'attach_link_form_field' => $sHp . '-attach-link-form-field-',
                 'attach_link_item' => $sHp . '-attach-link-item-',
                 'textarea' => $sHp . '-textarea-',
 
@@ -508,11 +524,11 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
         return $this->_aTypeToFormDisplay[$sType];
     }
 
-    public function getUploaders($sType)
+    public function getUploaders($sField)
     {
         $aResult = array();
 
-        switch($sType) {
+        switch($sField) {
             case 'photo':
                 $aResult = $this->_aPhotoUploaders;
                 break;
@@ -524,6 +540,14 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
         return $aResult;
     }
 
+    public function getUploaderByMenuItem($sMenuItem)
+    {
+        if(!isset($this->_aItemToUploader[$sMenuItem]))
+            return false;
+    
+        return $this->_aItemToUploader[$sMenuItem];
+    }
+
     public function getPerPage($sType = 'default')
     {
         if($this->isInfiniteScroll())

+ 94 - 57
modules/boonex/timeline/classes/BxTimelineDb.php

@@ -26,6 +26,9 @@ class BxTimelineDb extends BxBaseModNotificationsDb
     function __construct(&$oConfig)
     {
         parent::__construct($oConfig);
+
+        $CNF = &$this->_oConfig->CNF;
+
         $this->_sTableCache = $this->_sPrefix . 'cache';
 
         $this->_sTableEvent2User = $this->_sPrefix . 'events2users';
@@ -33,12 +36,12 @@ class BxTimelineDb extends BxBaseModNotificationsDb
         $this->_sTableHotTrack = $this->_sPrefix . 'hot_track';
 
         $this->_aTablesMedia = array(
-        	BX_TIMELINE_MEDIA_PHOTO => $this->_sPrefix . 'photos',
-        	BX_TIMELINE_MEDIA_VIDEO => $this->_sPrefix . 'videos' 
+            $CNF['FIELD_PHOTO'] => $this->_sPrefix . 'photos',
+            $CNF['FIELD_VIDEO'] => $this->_sPrefix . 'videos' 
         );
         $this->_aTablesMedia2Events = array(
-        	BX_TIMELINE_MEDIA_PHOTO => $this->_sPrefix . 'photos2events',
-        	BX_TIMELINE_MEDIA_VIDEO => $this->_sPrefix . 'videos2events'
+            $CNF['FIELD_PHOTO'] => $this->_sPrefix . 'photos2events',
+            $CNF['FIELD_VIDEO'] => $this->_sPrefix . 'videos2events'
         );
     }
 
@@ -186,18 +189,17 @@ class BxTimelineDb extends BxBaseModNotificationsDb
     //--- Photo uploader related methods ---//
     public function saveMedia($sType, $iEventId, $iItemId)
     {
-    	$sTable = $this->_aTablesMedia2Events[$sType];
-
-        $sQuery = $this->prepare("INSERT INTO `" . $sTable . "` SET `event_id`=?, `media_id`=?", $iEventId, $iItemId);
-        return (int)$this->query($sQuery) > 0;
+        return (int)$this->query("INSERT INTO `" . $this->_aTablesMedia2Events[$sType] . "` SET `event_id`=:event_id, `media_id`=:media_id", array(
+            'event_id' => $iEventId,
+            'media_id' => $iItemId
+        )) > 0;
     }
 
     public function deleteMedia($sType, $iEventId)
     {
-    	$sTable = $this->_aTablesMedia2Events[$sType];
-
-        $sQuery = $this->prepare("DELETE FROM `" . $sTable . "` WHERE `event_id` = ?", $iEventId);
-        return (int)$this->query($sQuery) > 0;
+        return (int)$this->query("DELETE FROM `" . $this->_aTablesMedia2Events[$sType] . "` WHERE `event_id`=:event_id", array(
+            'event_id' => $iEventId
+        )) > 0;
     }
 
     public function getMedia($sType, $iEventId, $iOffset = 0)
@@ -229,35 +231,12 @@ class BxTimelineDb extends BxBaseModNotificationsDb
     }
 
     //--- Link attach related methods ---//
-    public function getUnusedLinks($iUserId, $iLinkId = 0)
+    public function getUnusedLinks($iUserId)
     {
-        $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
-        $aMethod['params'][1] = array(
-			'profile_id' => $iUserId
-		);
-
-        $sWhereAddon = '';
-        if(!empty($iLinkId)) {
-            $aMethod['name'] = 'getRow';
-            $aMethod['params'][1]['id'] = $iLinkId;
-
-            $sWhereAddon = " AND `tl`.`id`=:id";
-        }
-
-        $aMethod['params'][0] = "SELECT
-                `tl`.`id` AS `id`,
-                `tl`.`profile_id` AS `profile_id`,
-                `tl`.`media_id` AS `media_id`,
-                `tl`.`url` AS `url`,
-                `tl`.`title` AS `title`,
-                `tl`.`text` AS `text`,
-                `tl`.`added` AS `added`
-            FROM `" . $this->_sPrefix . "links` AS `tl`
-            LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id`
-            WHERE `tl`.`profile_id`=:profile_id AND ISNULL(`tle`.`event_id`)" . $sWhereAddon . "
-            ORDER BY `tl`.`added` DESC";
-
-        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);;
+        return $this->getLinksBy(array(
+            'type' => 'unused',
+            'profile_id' => $iUserId
+        ));
     }
 
     public function deleteUnusedLinks($iUserId, $iLinkId = 0)
@@ -278,31 +257,89 @@ class BxTimelineDb extends BxBaseModNotificationsDb
 
     public function saveLink($iEventId, $iLinkId)
     {
-        $sQuery = $this->prepare("INSERT INTO `" . $this->_sPrefix . "links2events` SET `event_id`=?, `link_id`=?", $iEventId, $iLinkId);
-        return (int)$this->query($sQuery) > 0;
+        $aBindings = array(
+            'event_id' => $iEventId,
+            'link_id' => $iLinkId
+        );
+
+        $iId = $this->getOne("SELECT `id` FROM `" . $this->_sPrefix . "links2events` WHERE `event_id`=:event_id AND `link_id`=:link_id LIMIT 1", $aBindings);
+        if(!empty($iId))
+            return true;
+
+        return (int)$this->query("INSERT INTO `" . $this->_sPrefix . "links2events` SET `event_id`=:event_id, `link_id`=:link_id", $aBindings) > 0;
+    }
+
+    public function deleteLink($iId)
+    {
+        return (int)$this->query("DELETE FROM `tl`, `tle` USING `" . $this->_sPrefix . "links` AS `tl` LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id` WHERE `tl`.`id` = :id", array(
+            'id' => $iId
+        )) > 0;
     }
 
     public function deleteLinks($iEventId)
     {
-        $sQuery = $this->prepare("DELETE FROM `tl`, `tle` USING `" . $this->_sPrefix . "links` AS `tl` LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id` WHERE `tle`.`event_id` = ?", $iEventId);
-        return (int)$this->query($sQuery) > 0;
+        return (int)$this->query("DELETE FROM `tl`, `tle` USING `" . $this->_sPrefix . "links` AS `tl` LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id` WHERE `tle`.`event_id` = :event_id", array(
+            'event_id' => $iEventId
+        )) > 0;
     }
 
     public function getLinks($iEventId)
     {
-        $sQuery = $this->prepare("SELECT
-                `tl`.`id` AS `id`,
-                `tl`.`profile_id` AS `profile_id`,
-                `tl`.`media_id` AS `media_id`,
-                `tl`.`url` AS `url`,
-                `tl`.`title` AS `title`,
-                `tl`.`text` AS `text`,
-                `tl`.`added` AS `added`
-            FROM `" . $this->_sPrefix . "links` AS `tl`
-            LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id`
-            WHERE `tle`.`event_id`=?", $iEventId);
-
-        return $this->getAll($sQuery);
+        return $this->getLinksBy(array('type' => 'event_id', 'event_id' => $iEventId));
+    }
+
+    public function getLinksBy($aParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+
+    	$sSelectClause = "`tl`.*";
+    	$sJoinClause = $sWhereClause = $sGroupClause = $sOrderClause = $sLimitClause = "";
+        switch($aParams['type']) {
+            case 'id':
+            	$aMethod['name'] = 'getRow';
+            	$aMethod['params'][1] = array(
+                    'id' => $aParams['id']
+                );
+
+                $sWhereClause = " AND `tl`.`id`=:id";
+
+                if(!empty($aParams['profile_id'])) {
+                    $aMethod['params'][1]['profile_id'] = $aParams['profile_id'];
+
+                    $sWhereClause .= " AND `tl`.`profile_id`=:profile_id";
+                }
+                break;
+
+            case 'event_id':
+            	$aMethod['params'][1] = array(
+                    'event_id' => $aParams['event_id']
+                );
+
+                $sJoinClause = "LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id`";
+                $sWhereClause = " AND `tle`.`event_id`=:event_id";
+                break;
+
+            case 'unused':
+                $aMethod['params'][1] = array(
+                    'profile_id' => $aParams['profile_id']
+                );
+
+                $sJoinClause = "LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id`";
+                $sWhereClause = " AND `tl`.`profile_id`=:profile_id AND ISNULL(`tle`.`event_id`)";
+                $sOrderClause = "`tl`.`added` DESC";
+                break;
+        }
+
+        $sOrderClause = !empty($sOrderClause) ? "ORDER BY " . $sOrderClause : $sOrderClause;
+        $sLimitClause = !empty($sLimitClause) ? "LIMIT " . $sLimitClause : $sLimitClause;
+
+        $aMethod['params'][0] = "SELECT
+                " . $sSelectClause . "
+            FROM `" . $this->_sPrefix . "links` AS `tl` " . $sJoinClause . "
+            WHERE 1" . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
+
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
     }
 
     public function getHot()

+ 80 - 46
modules/boonex/timeline/classes/BxTimelineFormPost.php

@@ -20,31 +20,53 @@ class BxTimelineFormPost extends BxBaseModGeneralFormEntry
 
     protected $_bVisibilityAutoselect;
 
+    protected $_aUploadersInfo;
+
     public function __construct($aInfo, $oTemplate = false)
     {
         $this->MODULE = 'bx_timeline';
 
         parent::__construct($aInfo, $oTemplate);
 
+        $this->_sGhostTemplate = 'uploader_nfw.html';
+
         $this->_bAccountMode = isset($this->aParams['display']) && $this->aParams['display'] == $this->_oModule->_oConfig->getObject('form_display_post_add');
         $this->_bPublicMode = isset($this->aParams['display']) && $this->aParams['display'] == $this->_oModule->_oConfig->getObject('form_display_post_add_public');
         $this->_bProfileMode = isset($this->aParams['display']) && $this->aParams['display'] == $this->_oModule->_oConfig->getObject('form_display_post_add_profile');
 
         $this->_bVisibilityAutoselect = true;
-    }
 
-    public function getCode($bDynamicMode = false)
-    {
-    	$sResult = parent::getCode($bDynamicMode);
-
-    	return $this->_oModule->_oTemplate->parseHtmlByContent($sResult, array(
-            'attachments_menu' => $this->_oModule->getAttachmentsMenuObject()->getCode()
-    	));
+        $this->_aUploadersInfo = array();
     }
 
     function initChecker($aValues = array (), $aSpecificValues = array())
     {
         $CNF = &$this->_oModule->_oConfig->CNF;
+        
+        $iUserId = $this->_oModule->getUserId();
+        $bValueId = $aValues && !empty($aValues['id']);
+        $iValueId = $bValueId ? (int)$aValues['id'] : 0;
+
+        if(isset($this->aInputs[$CNF['FIELD_ATTACHMENTS']])) {
+            $oMenu = $this->_oModule->getAttachmentsMenuObject();
+            $oMenu->setEventById($iValueId);
+            $oMenu->setUploadersInfo($this->_aUploadersInfo);
+
+            $this->aInputs['attachments']['content'] = $oMenu->getCode();
+        }
+
+        if(isset($this->aInputs[$CNF['FIELD_LINK']]))
+            $this->aInputs[$CNF['FIELD_LINK']]['content'] = $this->_oModule->_oTemplate->getAttachLinkField($iUserId, $iValueId);
+
+        if(isset($CNF['FIELD_VIDEO']) && isset($this->aInputs[$CNF['FIELD_VIDEO']])) {
+            $aContentInfo = false;
+            if($bValueId) {
+                $aContentInfo = $this->_oModule->_oDb->getContentInfoById ($iValueId);
+                $this->aInputs[$CNF['FIELD_VIDEO']]['content_id'] = $iValueId;
+            }
+
+            $this->aInputs[$CNF['FIELD_VIDEO']]['ghost_template'] = $this->_oModule->_oTemplate->parseHtmlByName($this->_sGhostTemplate, $this->_getVideoGhostTmplVars($aContentInfo));
+        }
 
         if($this->aParams['display'] == $this->_oModule->_oConfig->getObject('form_display_post_edit') && isset($CNF['FIELD_PUBLISHED']) && isset($this->aInputs[$CNF['FIELD_PUBLISHED']]))
             if(isset($aValues[$CNF['FIELD_STATUS']]) && in_array($aValues[$CNF['FIELD_STATUS']], array(BX_TIMELINE_STATUS_ACTIVE, BX_TIMELINE_STATUS_HIDDEN)))
@@ -135,6 +157,8 @@ class BxTimelineFormPost extends BxBaseModGeneralFormEntry
 
     public function init()
     {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
         $iUserId = $this->_oModule->getUserId();
         $iOwnerId = $this->_oModule->getOwnerId();
 
@@ -153,48 +177,48 @@ class BxTimelineFormPost extends BxBaseModGeneralFormEntry
         foreach($aPrivacyFields as $sField => $sPrivacyObject)
             $this->_initPrivacyField($sField, $sPrivacyObject);
 
-        if(isset($this->aInputs['link']))
-            $this->aInputs['link']['content'] = $this->_oModule->_oTemplate->getAttachLinkField($iUserId);
-
-        if(isset($this->aInputs['photo'])) {
-            $aFormNested = array(
-                'params' =>array(
-                    'nested_form_template' => 'uploader_nfw.html'
-                ),
-                'inputs' => array(),
-            );
-
-            $oFormNested = new BxDolFormNestedGhost('photo', $aFormNested, 'tlb_do_submit', $this->_oModule->_oTemplate);
-
-            $this->aInputs['photo']['storage_object'] = $this->_oModule->_oConfig->getObject('storage_photos');
-            $this->aInputs['photo']['images_transcoder'] = $this->_oModule->_oConfig->getObject('transcoder_photos_preview');
-            $this->aInputs['photo']['uploaders'] = !empty($this->aInputs['photo']['value']) ? unserialize($this->aInputs['photo']['value']) : $this->_oModule->_oConfig->getUploaders('photo');
-            $this->aInputs['photo']['upload_buttons_titles'] = array('Simple' => 'camera');
-            $this->aInputs['photo']['multiple'] = true;
-            $this->aInputs['photo']['ghost_template'] = $oFormNested;
+        if(isset($this->aInputs[$CNF['FIELD_PHOTO']])) {
+            $sStorage = $this->_oModule->_oConfig->getObject('storage_photos');
+            $sUploadersId = genRndPwd(8, false);
+            $aUploaders = !empty($this->aInputs[$CNF['FIELD_PHOTO']]['value']) ? unserialize($this->aInputs[$CNF['FIELD_PHOTO']]['value']) : $this->_oModule->_oConfig->getUploaders($CNF['FIELD_PHOTO']);
+
+            foreach($aUploaders as $sUploader)
+                $this->_aUploadersInfo[$sUploader] = array(
+                    'id' => $sUploadersId, 
+                    'js_object' => BxDolUploader::getObjectInstance($sUploader, $sStorage, $sUploadersId)->getNameJsInstanceUploader()
+                );
+
+            $this->aInputs[$CNF['FIELD_PHOTO']]['storage_object'] = $sStorage;
+            $this->aInputs[$CNF['FIELD_PHOTO']]['images_transcoder'] = $this->_oModule->_oConfig->getObject('transcoder_photos_preview');
+            $this->aInputs[$CNF['FIELD_PHOTO']]['uploaders_id'] = $sUploadersId;
+            $this->aInputs[$CNF['FIELD_PHOTO']]['uploaders'] = $aUploaders;
+            $this->aInputs[$CNF['FIELD_PHOTO']]['upload_buttons_titles'] = array('Simple' => 'camera');
+            $this->aInputs[$CNF['FIELD_PHOTO']]['multiple'] = true;
+            $this->aInputs[$CNF['FIELD_PHOTO']]['content_id'] = 0;
+            $this->aInputs[$CNF['FIELD_PHOTO']]['ghost_template'] = '';
         }
 
-        if(isset($this->aInputs['video'])) {
-            $aFormNested = array(
-                'params' =>array(
-                    'nested_form_template' => 'uploader_nfw.html'
-                ),
-                'inputs' => array(),
-            );
-
-            $oFormNested = new BxDolFormNestedGhost('video', $aFormNested, 'tlb_do_submit', $this->_oModule->_oTemplate);
-
-            $this->aInputs['video']['storage_object'] = $this->_oModule->_oConfig->getObject('storage_videos');
-            $this->aInputs['video']['images_transcoder'] = $this->_oModule->_oConfig->getObject('transcoder_videos_poster');
-            $this->aInputs['video']['uploaders'] = !empty($this->aInputs['video']['value']) ? unserialize($this->aInputs['video']['value']) : $this->_oModule->_oConfig->getUploaders('video');
-            $this->aInputs['video']['upload_buttons_titles'] = array('Simple' => 'video');
-            $this->aInputs['video']['multiple'] = true;
-            $this->aInputs['video']['ghost_template'] = $oFormNested;
+        if(isset($this->aInputs[$CNF['FIELD_VIDEO']])) {
+            $sStorage = $this->_oModule->_oConfig->getObject('storage_videos');
+            $sUploadersId = genRndPwd(8, false);
+            $aUploaders = !empty($this->aInputs[$CNF['FIELD_VIDEO']]['value']) ? unserialize($this->aInputs[$CNF['FIELD_VIDEO']]['value']) : $this->_oModule->_oConfig->getUploaders($CNF['FIELD_VIDEO']);
+
+            foreach($aUploaders as $sUploader)
+                $this->_aUploadersInfo[$sUploader] = array(
+                    'id' => $sUploadersId, 
+                    'js_object' => BxDolUploader::getObjectInstance($sUploader, $sStorage, $sUploadersId)->getNameJsInstanceUploader()
+                );
+
+            $this->aInputs[$CNF['FIELD_VIDEO']]['storage_object'] = $sStorage;
+            $this->aInputs[$CNF['FIELD_VIDEO']]['images_transcoder'] = $this->_oModule->_oConfig->getObject('transcoder_videos_poster');
+            $this->aInputs[$CNF['FIELD_VIDEO']]['uploaders_id'] = $sUploadersId;
+            $this->aInputs[$CNF['FIELD_VIDEO']]['uploaders'] = $aUploaders;
+            $this->aInputs[$CNF['FIELD_VIDEO']]['upload_buttons_titles'] = array('Simple' => 'video');
+            $this->aInputs[$CNF['FIELD_VIDEO']]['multiple'] = true;
+            $this->aInputs[$CNF['FIELD_VIDEO']]['content_id'] = 0;
+            $this->aInputs[$CNF['FIELD_VIDEO']]['ghost_template'] = '';
         }
 
-        if(isset($this->aInputs['attachments']))
-            $this->aInputs['attachments']['content'] = '__attachments_menu__';
-
         if (isset($this->_oModule->_oConfig->CNF['FIELD_LOCATION_PREFIX']) && isset($this->aInputs[$this->_oModule->_oConfig->CNF['FIELD_LOCATION_PREFIX']]))
             $this->aInputs[$this->_oModule->_oConfig->CNF['FIELD_LOCATION_PREFIX']]['manual_input'] = false;
     }
@@ -316,6 +340,16 @@ class BxTimelineFormPost extends BxBaseModGeneralFormEntry
             )
         ));
     }
+
+    protected function _getVideoGhostTmplVars($aContentInfo = array())
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	return array (
+            'name' => $this->aInputs[$CNF['FIELD_VIDEO']]['name'],
+            'content_id' => (int)$this->aInputs[$CNF['FIELD_VIDEO']]['content_id'],
+        );
+    }
 }
 
 /** @} */

+ 46 - 0
modules/boonex/timeline/classes/BxTimelineMenuPostAttachments.php

@@ -13,11 +13,37 @@ class BxTimelineMenuPostAttachments extends BxTemplMenu
 {
     protected $_oModule;
 
+    protected $_iEvent;
+    
+    /**
+     * An array with uploaders, which are 
+     * available (active) in create form.
+     */
+    protected $_aUploadersInfo;
+
     public function __construct($aObject, $oTemplate = false)
     {
         parent::__construct($aObject, $oTemplate);
 
         $this->_oModule = BxDolModule::getInstance('bx_timeline');
+
+        $this->addMarkers(array(
+            'js_object' => $this->_oModule->_oConfig->getJsObject('post'),
+        ));
+    }
+
+    public function setEventById($iEventId, $aBrowseParams = array())
+    {
+        $this->_iEvent = $iEventId;
+
+        $this->addMarkers(array(
+            'content_id' => $this->_iEvent,
+        ));
+    }
+
+    public function setUploadersInfo($aUploadersInfo)
+    {
+        $this->_aUploadersInfo = $aUploadersInfo;
     }
 
     public function isMenuItem($sName)
@@ -31,6 +57,26 @@ class BxTimelineMenuPostAttachments extends BxTemplMenu
 
         return $this->_isVisible($aMenuItem);
     }
+    
+    protected function _getMenuItem($a)
+    {
+        if(isset($a['active']) && !$a['active'])
+            return false;
+
+        if(isset($a['visible_for_levels']) && !$this->_isVisible($a))
+            return false;
+        
+        if(($sUploader = $this->_oModule->_oConfig->getUploaderByMenuItem($a['name'])) !== false) {
+            if(!isset($this->_aUploadersInfo[$sUploader]))
+                return false;
+
+            $this->addMarkers(array(
+                'js_object_' . str_replace('-', '_', $a['name']) => $this->_aUploadersInfo[$sUploader]['js_object']
+            ));
+        }
+
+        return parent::_getMenuItem($a);
+    }
 }
 
 /** @} */

+ 145 - 74
modules/boonex/timeline/classes/BxTimelineModule.php

@@ -40,9 +40,6 @@ define('BX_TIMELINE_STATUS_FAILED', 'failed');
 define('BX_TIMELINE_STATUS_HIDDEN', 'hidden');
 define('BX_TIMELINE_STATUS_DELETED', 'deleted');
 
-define('BX_TIMELINE_MEDIA_PHOTO', 'photo');
-define('BX_TIMELINE_MEDIA_VIDEO', 'video');
-
 //--- Video Auto Play 
 define('BX_TIMELINE_VAP_OFF', 'off');
 define('BX_TIMELINE_VAP_ON_MUTE', 'on_mute');
@@ -380,7 +377,12 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         if(empty($sUrl))
             return echoJson(array());
 
+        $iEventId = 0;
+        if(bx_get('event_id') !== false)
+            $iEventId = (int)bx_get('event_id');
+
         echoJson($this->addAttachLink(array(
+            'event_id' => $iEventId,
             'url' => $sUrl
         )));
     }
@@ -389,22 +391,18 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
     {
     	$iUserId = $this->getUserId();
         $iLinkId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if(empty($iLinkId)) {
-            echoJson(array());
-            return;
-        }
+        if(empty($iLinkId))
+            return echoJson(array());
 
-        $aLink = $this->_oDb->getUnusedLinks($iUserId, $iLinkId);
-    	if(empty($aLink) || !is_array($aLink)) {
-            echoJson(array());
-            return;
-        }
+        $aLink = $this->_oDb->getLinksBy(array('type' => 'id', 'id' => $iLinkId, 'profile_id' => $iUserId));
+    	if(empty($aLink) || !is_array($aLink))
+            return echoJson(array());
 
-		if(!empty($aLink['media_id']))
-			BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'))->deleteFile($aLink['media_id']);
+        if(!empty($aLink['media_id']))
+            BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'))->deleteFile($aLink['media_id']);
 
         $aResult = array();
-        if($this->_oDb->deleteUnusedLinks($iUserId, $iLinkId))
+        if($this->_oDb->deleteLink($iLinkId))
             $aResult = array('code' => 0);
         else
             $aResult = array('code' => 1, 'message' => _t('_bx_timeline_form_post_input_link_err_delete'));
@@ -414,7 +412,11 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
     public function actionGetAttachLinkForm()
     {
-        echo $this->_oTemplate->getAttachLinkForm();
+        $iEventId = 0;
+        if(bx_get('event_id') !== false)
+            $iEventId = (int)bx_get('event_id');
+
+        echo $this->_oTemplate->getAttachLinkForm($iEventId);
     }
 
     public function actionSubmitAttachLinkForm()
@@ -2590,10 +2592,11 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         return $this->_addLink($oForm);
     }
 
-    public function getFormAttachLink()
+    public function getFormAttachLink($iEventId = 0)
     {
         $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_attach_link'), $this->_oConfig->getObject('form_display_attach_link_add'), $this->_oTemplate);
         $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'submit_attach_link_form/';
+        $oForm->aInputs['event_id']['value'] = $iEventId;
         $oForm->aInputs['url']['checker']['params']['preg'] = $this->_oConfig->getPregPattern('url');
 
         $oForm->initChecker();
@@ -2605,6 +2608,8 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
     public function getFormPost($aParams = array())
     {
+        $CNF = &$this->_oConfig->CNF;
+
         $iUserId = $this->getUserId();
 
         $oForm = $this->getFormPostObject($aParams);
@@ -2648,14 +2653,14 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
                 $iOwnerId = abs($iObjectPrivacyView);
 
             //--- Process Link ---//
-            $aLinkIds = $oForm->getCleanValue('link');
+            $aLinkIds = $oForm->getCleanValue($CNF['FIELD_LINK']);
             $bLinkIds = !empty($aLinkIds) && is_array($aLinkIds);
 
             //--- Process Media ---//
-            $aPhotoIds = $oForm->getCleanValue(BX_TIMELINE_MEDIA_PHOTO);
+            $aPhotoIds = $oForm->getCleanValue($CNF['FIELD_PHOTO']);
             $bPhotoIds = !empty($aPhotoIds) && is_array($aPhotoIds);
 
-            $aVideoIds = $oForm->getCleanValue(BX_TIMELINE_MEDIA_VIDEO);
+            $aVideoIds = $oForm->getCleanValue($CNF['FIELD_VIDEO']);
             $bVideoIds = !empty($aVideoIds) && is_array($aVideoIds);
 
             if(!$bText && !$bLinkIds && !$bPhotoIds && !$bVideoIds) {
@@ -2706,11 +2711,8 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
                         $this->_oDb->saveLink($iId, $iLinkId);
 
                 //--- Process Media ---//
-                if($bPhotoIds) 
-                    $this->_saveMedia(BX_TIMELINE_MEDIA_PHOTO, $iId, $aPhotoIds);
-
-                if($bVideoIds)
-                    $this->_saveMedia(BX_TIMELINE_MEDIA_VIDEO, $iId, $aVideoIds);
+                $this->_saveMedia($CNF['FIELD_PHOTO'], $iId, $aPhotoIds, $iUserId, true);
+                $this->_saveMedia($CNF['FIELD_VIDEO'], $iId, $aVideoIds, $iUserId, true);
 
                 $this->onPost($iId);
 
@@ -2730,6 +2732,8 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         $CNF = &$this->_oConfig->CNF;
         $sJsObjectView = $this->_oConfig->getJsObjectView($aBrowseParams);
 
+        $iUserId = $this->getUserId();
+
         $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
         if(empty($aEvent) || !is_array($aEvent))
             return array();
@@ -2738,10 +2742,12 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         if(is_array($aContent) && !empty($aContent['text']))
             $aEvent['text'] = $aContent['text'];
 
-        $bDynamicMode = isset($aParams['dynamic_mode']) ? (bool)$aParams['dynamic_mode'] : false;
-        $sFormObject = !empty($aParams['form_object']) ? $aParams['form_object'] : 'form_post';
-        $sFormDisplay = !empty($aParams['form_display']) ? $aParams['form_display'] : 'form_display_post_edit';
-        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject($sFormObject), $this->_oConfig->getObject($sFormDisplay), $this->_oTemplate);
+        if(empty($aParams['form_object']))
+            $aParams['form_object'] = 'form_post';
+        if(empty($aParams['form_display']))
+            $aParams['form_display'] = 'form_display_post_edit';
+
+        $oForm = $this->getFormPostObject($aParams);
         $oForm->setId($this->_oConfig->getHtmlIds('view', 'edit_form') . $iId);
         $aFormInitCheckerParams = array();
 
@@ -2771,6 +2777,10 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         }
 
         call_user_func_array(array($oForm, 'initChecker'), $aFormInitCheckerParams);
+
+        $bAjaxMode = $oForm->isAjaxMode();
+        $bDynamicMode = $bAjaxMode;
+
         if($oForm->isSubmittedAndValid()) {
             $aContent = array();
 
@@ -2800,7 +2810,25 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
                     'object_privacy_view' => $iObjectPrivacyViewDefault
                 ));
 
-            if(!$oForm->update($iId, $aValsToAdd))
+            //--- Process Link ---//
+            $aLinkIds = $oForm->getCleanValue($CNF['FIELD_LINK']);
+            $bLinkIds = !empty($aLinkIds) && is_array($aLinkIds);
+
+            //--- Process Media ---//
+            $aPhotoIds = $oForm->getCleanValue($CNF['FIELD_PHOTO']);
+            $bPhotoIds = !empty($aPhotoIds) && is_array($aPhotoIds);
+
+            $aVideoIds = $oForm->getCleanValue($CNF['FIELD_VIDEO']);
+            $bVideoIds = !empty($aVideoIds) && is_array($aVideoIds);
+
+            if(!$bText && !$bLinkIds && !$bPhotoIds && !$bVideoIds) {
+                $oForm->aInputs['text']['error'] =  _t('_bx_timeline_txt_err_empty_post');
+                $oForm->setValid(false);
+
+            	return $this->_prepareResponse(array('form' => $oForm->getCode($bDynamicMode), 'form_id' => $oForm->id), $bAjaxMode);
+            }
+
+            if($oForm->update($iId, $aValsToAdd) === false)
                 return array('message' => _t('_bx_timeline_txt_err_cannot_perform_action'));
 
             $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
@@ -2808,6 +2836,15 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
                 $oMetatags->metaAdd($iId, $sText);
             $oMetatags->locationsAddFromForm($iId, $this->_oConfig->CNF['FIELD_LOCATION_PREFIX']);
 
+            //--- Process Link ---//
+            if($bLinkIds)
+                foreach($aLinkIds as $iLinkId)
+                    $this->_oDb->saveLink($iId, $iLinkId);
+
+            //--- Process Media ---//
+            $this->_saveMedia($CNF['FIELD_PHOTO'], $iId, $aPhotoIds, $iUserId);
+            $this->_saveMedia($CNF['FIELD_VIDEO'], $iId, $aVideoIds, $iUserId);
+
             $this->getCacheItemObject()->removeAllByPrefix($this->_oConfig->getPrefix('cache_item') . $iId);
             $this->_oDb->deleteCache(array('event_id' => $iId));
 
@@ -2917,12 +2954,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
     public function getAttachmentsMenuObject()
     {
-        $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_post_attachments'), $this->_oTemplate);
-        $oMenu->addMarkers(array(
-            'js_object' => $this->_oConfig->getJsObject('post'),
-        ));
-
-        return $oMenu;
+        return BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_post_attachments'), $this->_oTemplate);
     }
 
     public function getManageMenuObject()
@@ -3350,6 +3382,18 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
         return CHECK_ACTION_RESULT_ALLOWED;
     }
 
+    public function checkAllowedEditAnyEntryForProfile ($isPerformAction = false, $iProfileId = false)
+    {
+        if(!$iProfileId)
+            $iProfileId = $this->_iProfileId;
+
+    	$aCheck = checkActionModule($iProfileId, 'edit', $this->getName(), $isPerformAction);
+    	if($aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED)
+    		return CHECK_ACTION_RESULT_ALLOWED;
+
+    	return _t('_sys_txt_access_denied');
+    }
+
     public function onPost($iContentId)
     {
         $CNF = &$this->_oConfig->CNF;
@@ -3467,10 +3511,10 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
     	//--- Delete attached photos, videos and links when common event was deleted.
     	if($aEvent['type'] == $sCommonPostPrefix . BX_TIMELINE_PARSE_TYPE_POST) {
-    		$this->_deleteMedia(BX_TIMELINE_MEDIA_PHOTO, $aEvent[$CNF['FIELD_ID']]);
-    		$this->_deleteMedia(BX_TIMELINE_MEDIA_VIDEO, $aEvent[$CNF['FIELD_ID']]);
+            $this->_deleteMedia($CNF['FIELD_PHOTO'], $aEvent[$CNF['FIELD_ID']]);
+            $this->_deleteMedia($CNF['FIELD_VIDEO'], $aEvent[$CNF['FIELD_ID']]);
 
-	        $this->_deleteLinks($aEvent[$CNF['FIELD_ID']]);
+            $this->_deleteLinks($aEvent[$CNF['FIELD_ID']]);
     	}
 
     	//--- Update parent event when repost event was deleted.
@@ -3646,7 +3690,9 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
     public function getEventImages($iEventId)
     {
-        $aPhotos = $this->_oDb->getMedia(BX_TIMELINE_MEDIA_PHOTO, $iEventId);
+        $CNF = &$this->_oConfig->CNF;
+
+        $aPhotos = $this->_oDb->getMedia($CNF['FIELD_PHOTO'], $iEventId);
         if(empty($aPhotos) || !is_array($aPhotos))
             return array();
 
@@ -3677,7 +3723,9 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
     public function getEventVideos($iEventId)
     {
-        $aVideos = $this->_oDb->getMedia(BX_TIMELINE_MEDIA_VIDEO, $iEventId);
+        $CNF = &$this->_oConfig->CNF;
+
+        $aVideos = $this->_oDb->getMedia($CNF['FIELD_VIDEO'], $iEventId);
         if(empty($aVideos) || !is_array($aVideos))
             return array();
 
@@ -3925,6 +3973,7 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
     {
         $iUserId = $this->getUserId();
 
+        $iEventId = (int)$oForm->getCleanValue('event_id');
         $sLink = $oForm->getCleanValue('url');
 
         $aMatches = array();
@@ -3941,67 +3990,89 @@ class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolCon
 
         $sMediaUrl = '';
         if(!empty($aSiteInfo['thumbnailUrl']))
-        	$sMediaUrl = $aSiteInfo['thumbnailUrl'];
+            $sMediaUrl = $aSiteInfo['thumbnailUrl'];
         else if(!empty($aSiteInfo['OGImage']))
-        	$sMediaUrl = $aSiteInfo['OGImage'];
+            $sMediaUrl = $aSiteInfo['OGImage'];
 
-		$iMediaId = 0;
-		$oStorage = null;
+        $iMediaId = 0;
+        $oStorage = null;
         if(!empty($sMediaUrl)) {
-        	$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . BX_TIMELINE_MEDIA_PHOTO . 's'));
+            $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'));
 
-        	$iMediaId = $oStorage->storeFileFromUrl($sMediaUrl, true, $iUserId);
+            $iMediaId = $oStorage->storeFileFromUrl($sMediaUrl, true, $iUserId);
         }
 
         $iId = (int)$oForm->insert(array('profile_id' => $iUserId, 'media_id' => $iMediaId, 'url' => $sLink, 'title' => $sTitle, 'text' => $sDescription, 'added' => time()));
         if(!empty($iId)) {
-        	if(!empty($oStorage) && !empty($iMediaId))
-        		$oStorage->afterUploadCleanup($iMediaId, $iUserId);
+            if(!empty($oStorage) && !empty($iMediaId))
+                $oStorage->afterUploadCleanup($iMediaId, $iUserId);
 
-            return array('id' => $iId, 'item' => $this->_oTemplate->getAttachLinkItem($iUserId, $iId));
+            return array('id' => $iId, 'event_id' => $iEventId, 'item' => $this->_oTemplate->getAttachLinkItem($iUserId, $iId));
         }
 
         return array('message' => _t('_bx_timeline_txt_err_cannot_perform_action'));
     }
 
-	protected function _deleteLinks($iId)
+    protected function _deleteLinks($iId)
     {
-	    $aLinks = $this->_oDb->getLinks($iId);
-	    if(empty($aLinks) || !is_array($aLinks))
-	    	return;
+        $aLinks = $this->_oDb->getLinks($iId);
+        if(empty($aLinks) || !is_array($aLinks))
+            return;
 
-		$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'));
-		foreach($aLinks as $aLink)
-			if(!empty($aLink['media_id']))
-				$oStorage->deleteFile($aLink['media_id']);
+        $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'));
+        foreach($aLinks as $aLink)
+            if(!empty($aLink['media_id']))
+                $oStorage->deleteFile($aLink['media_id']);
 
-		$this->_oDb->deleteLinks($iId);
+        $this->_oDb->deleteLinks($iId);
     }
 
-    protected function _saveMedia($sType, $iId, $aItemIds)
+    protected function _saveMedia($sType, $iContentId, $aItemIds, $iProfileId = 0, $isAssociateWithContent = false)
     {
+        if(empty($iContentId))
+            return;
+
+        if(!$isAssociateWithContent)
+            $this->_oDb->deleteMedia($sType, $iContentId);
+
     	if(empty($aItemIds) || !is_array($aItemIds))
-    		return; 
+            return; 
 
-    	$iUserId = $this->getUserId();
+        if(empty($iProfileId))
+            $iProfileId = $this->_iProfileId;
 
-		$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . strtolower($sType) . 's'));
-		foreach($aItemIds as $iItemId)
-        	if($this->_oDb->saveMedia($sType, $iId, $iItemId))
-            	$oStorage->afterUploadCleanup($iItemId, $iUserId);
+        $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . strtolower($sType) . 's'));
+
+        $aGhostFiles = $oStorage->getGhosts ($iProfileId, !$isAssociateWithContent ? $iContentId : 0, true, $this->_isModerator());
+        if(empty($aGhostFiles) || !is_array($aGhostFiles))
+            return;
+
+        foreach($aGhostFiles as $aFile) {
+            if(is_array($aItemIds) && !in_array($aFile['id'], $aItemIds))
+                continue;
+
+            $iFileId = (int)$aFile['id'];
+
+            if($aFile['private'])
+                $oStorage->setFilePrivate($iFileId, 1);
+
+            $oStorage->updateGhostsContentId($iFileId, $iProfileId, $iContentId, $this->_isModerator());
+
+            $this->_oDb->saveMedia($sType, $iContentId, $iFileId);
+        }
     }
 
-    protected function _deleteMedia($sType, $iId)
+    protected function _deleteMedia($sType, $iContentId)
     {
-	    $aItems = $this->_oDb->getMedia($sType, $iId);
-	    if(empty($aItems) || !is_array($aItems))
-	    	return;
+        $aItems = $this->_oDb->getMedia($sType, $iContentId);
+        if(empty($aItems) || !is_array($aItems))
+            return;
 
-		$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . strtolower($sType) . 's'));
-		foreach($aItems as $iItemId)
-			$oStorage->deleteFile($iItemId);
+        $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . strtolower($sType) . 's'));
+        foreach($aItems as $iItemId)
+            $oStorage->deleteFile($iItemId);
 
-		$this->_oDb->deleteMedia($sType, $iId);
+        $this->_oDb->deleteMedia($sType, $iContentId);
     }
 
     protected function _prepareParams($aParams)

+ 2 - 2
modules/boonex/timeline/classes/BxTimelineResponse.php

@@ -203,7 +203,7 @@ class BxTimelineResponse extends BxBaseModNotificationsResponse
         if(!isset($CNF['FIELD_STATUS']))
             return;
 
-        $aMedia = $this->_oModule->_oDb->getMediaById(BX_TIMELINE_MEDIA_VIDEO, $iMediaId);
+        $aMedia = $this->_oModule->_oDb->getMediaById($CNF['FIELD_VIDEO'], $iMediaId);
         if(empty($aMedia) || !is_array($aMedia))
             return;
 
@@ -238,7 +238,7 @@ class BxTimelineResponse extends BxBaseModNotificationsResponse
             return;
 
         $oTranscoder = BxDolTranscoder::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['mp4']);
-        $aMediasToCheck = $this->_oModule->_oDb->getMedia(BX_TIMELINE_MEDIA_VIDEO, $iContentId);
+        $aMediasToCheck = $this->_oModule->_oDb->getMedia($CNF['FIELD_VIDEO'], $iContentId);
         foreach($aMediasToCheck as $iMediaToCheck)
             if(!$oTranscoder->isFileReady($iMediaToCheck))
                 return;

+ 9 - 6
modules/boonex/timeline/classes/BxTimelineTemplate.php

@@ -1022,12 +1022,12 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
         return $sResult;
     }
 
-    public function getAttachLinkForm()
+    public function getAttachLinkForm($iEventId = 0)
     {
         $sStylePrefix = $this->_oConfig->getPrefix('style');
         $sJsObject = $this->_oConfig->getJsObject('post');
 
-        $aForm = $this->getModule()->getFormAttachLink();
+        $aForm = $this->getModule()->getFormAttachLink($iEventId);
 
         return $this->parseHtmlByName('attach_link_form.html', array(
             'style_prefix' => $sStylePrefix,
@@ -1037,18 +1037,21 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
         ));
     }
 
-    public function getAttachLinkField($iUserId)
+    public function getAttachLinkField($iUserId, $iEventId = 0)
     {
         $sStylePrefix = $this->_oConfig->getPrefix('style');
 
-        $aLinks = $this->_oDb->getUnusedLinks($iUserId);
+        if(!$iEventId)
+            $aLinks = $this->_oDb->getUnusedLinks($iUserId);
+        else
+            $aLinks = $this->_oDb->getLinks($iEventId);
 
         $sLinks = '';
         foreach($aLinks as $aLink)
             $sLinks .= $this->getAttachLinkItem($iUserId, $aLink);
 
         return $this->parseHtmlByName('attach_link_form_field.html', array(
-            'html_id' => $this->_oConfig->getHtmlIds('post', 'attach_link_form_field'),
+            'html_id' => $this->_oConfig->getHtmlIds('post', 'attach_link_form_field') . $iEventId,
             'style_prefix' => $sStylePrefix,
             'links' => $sLinks
         ));
@@ -1056,7 +1059,7 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
 
     public function getAttachLinkItem($iUserId, $mixedLink)
     {
-        $aLink = is_array($mixedLink) ? $mixedLink : $this->_oDb->getUnusedLinks($iUserId, (int)$mixedLink);
+        $aLink = is_array($mixedLink) ? $mixedLink : $this->_oDb->getLinksBy(array('type' => 'id', 'id' => (int)$mixedLink, 'profile_id' => $iUserId));
         if(empty($aLink) || !is_array($aLink))
             return '';
 

+ 7 - 1
modules/boonex/timeline/classes/BxTimelineUploaderHTML5Attach.php

@@ -9,13 +9,19 @@
  * @{
  */
 
-class BxTimelineUploaderHTML5Attach extends BxBaseModTextUploaderHTML5Attach
+class BxTimelineUploaderHTML5Attach extends BxTemplUploaderHTML5
 {
+    protected $_sModule;
+    protected $_oModule;
+
     public function __construct ($aObject, $sStorageObject, $sUniqId, $oTemplate)
     {
         $this->_sModule = 'bx_timeline';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
 
         parent::__construct($aObject, $sStorageObject, $sUniqId, $oTemplate);
+
+        $this->_sButtonTemplate = 'uploader_button_html5_attach.html';
     }
 }
 

+ 8 - 2
modules/boonex/timeline/classes/BxTimelineUploaderSimpleAttach.php

@@ -9,13 +9,19 @@
  * @{
  */
 
-class BxTimelineUploaderSimpleAttach extends BxBaseModTextUploaderSimpleAttach
+class BxTimelineUploaderSimpleAttach extends BxTemplUploaderSimple
 {
+    protected $_sModule;
+    protected $_oModule;
+
     public function __construct ($aObject, $sStorageObject, $sUniqId, $oTemplate)
     {
         $this->_sModule = 'bx_timeline';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);        
+
+        parent::__construct($aObject, $sStorageObject, $sUniqId, $this->_oModule->_oTemplate);
 
-        parent::__construct($aObject, $sStorageObject, $sUniqId, $oTemplate);
+        $this->_sButtonTemplate = 'uploader_button_simple_attach.html';
     }
 }
 

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

@@ -79,6 +79,7 @@
 
     <string name="_bx_timeline_form_attach_link"><![CDATA[Attach Link]]></string>
     <string name="_bx_timeline_form_attach_link_display_add"><![CDATA[Attach Link]]></string>
+    <string name="_bx_timeline_form_attach_link_input_sys_event_id"><![CDATA[Event ID]]></string>
     <string name="_bx_timeline_form_attach_link_input_sys_url"><![CDATA[Url]]></string>
     <string name="_bx_timeline_form_attach_link_input_url"><![CDATA[Add Link]]></string>
     <string name="_bx_timeline_form_attach_link_input_url_err"><![CDATA[Correct Link is essential. Please, fill in this field.]]></string>

+ 5 - 5
modules/boonex/timeline/install/sql/enable.sql

@@ -203,11 +203,11 @@ INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES
 
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
 ('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-emoji', '_bx_timeline_menu_item_title_system_add_emoji', '_bx_timeline_menu_item_title_add_emoji', 'javascript:void(0)', '', '_self', 'far smile', '', '', 2147483647, 0, 0, 1, 0),
-('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-link', '_bx_timeline_menu_item_title_system_add_link', '_bx_timeline_menu_item_title_add_link', 'javascript:void(0)', 'javascript:{js_object}.showAttachLink(this);', '_self', 'link', '', '', 2147483647, 1, 0, 1, 1),
-('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-photo-simple', '_bx_timeline_menu_item_title_system_add_photo_simple', '_bx_timeline_menu_item_title_add_photo', 'javascript:void(0)', 'javascript:{js_object_uploader_simple_photo}.showUploaderForm();', '_self', 'camera', '', '', 2147483647, 0, 0, 1, 2),
-('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-photo-html5', '_bx_timeline_menu_item_title_system_add_photo_html5', '_bx_timeline_menu_item_title_add_photo', 'javascript:void(0)', 'javascript:{js_object_uploader_html5_photo}.showUploaderForm();', '_self', 'camera', '', '', 2147483647, 1, 0, 1, 3),
-('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-video-simple', '_bx_timeline_menu_item_title_system_add_video_simple', '_bx_timeline_menu_item_title_add_video', 'javascript:void(0)', 'javascript:{js_object_uploader_simple_video}.showUploaderForm();', '_self', 'video', '', '', 2147483647, 0, 0, 1, 4),
-('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-video-html5', '_bx_timeline_menu_item_title_system_add_video_html5', '_bx_timeline_menu_item_title_add_video', 'javascript:void(0)', 'javascript:{js_object_uploader_html5_video}.showUploaderForm();', '_self', 'video', '', '', 2147483647, 1, 0, 1, 5);
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-link', '_bx_timeline_menu_item_title_system_add_link', '_bx_timeline_menu_item_title_add_link', 'javascript:void(0)', 'javascript:{js_object}.showAttachLink(this, {content_id});', '_self', 'link', '', '', 2147483647, 1, 0, 1, 1),
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-photo-simple', '_bx_timeline_menu_item_title_system_add_photo_simple', '_bx_timeline_menu_item_title_add_photo', 'javascript:void(0)', 'javascript:{js_object_add_photo_simple}.showUploaderForm();', '_self', 'camera', '', '', 2147483647, 0, 0, 1, 2),
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-photo-html5', '_bx_timeline_menu_item_title_system_add_photo_html5', '_bx_timeline_menu_item_title_add_photo', 'javascript:void(0)', 'javascript:{js_object_add_photo_html5}.showUploaderForm();', '_self', 'camera', '', '', 2147483647, 1, 0, 1, 3),
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-video-simple', '_bx_timeline_menu_item_title_system_add_video_simple', '_bx_timeline_menu_item_title_add_video', 'javascript:void(0)', 'javascript:{js_object_add_video_simple}.showUploaderForm();', '_self', 'video', '', '', 2147483647, 0, 0, 1, 4),
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-video-html5', '_bx_timeline_menu_item_title_system_add_video_html5', '_bx_timeline_menu_item_title_add_video', 'javascript:void(0)', 'javascript:{js_object_add_video_html5}.showUploaderForm();', '_self', 'video', '', '', 2147483647, 1, 0, 1, 5);
 
 -- MENU: add to "add content" menu
 SET @iAddMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_add_content_links' AND `active` = 1 ORDER BY `order` DESC LIMIT 1);

+ 15 - 9
modules/boonex/timeline/install/sql/install.sql

@@ -433,11 +433,15 @@ INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_fo
 ('bx_timeline_post_edit', 'action', 2147483647, 1, 2),
 ('bx_timeline_post_edit', 'owner_id', 2147483647, 1, 3),
 ('bx_timeline_post_edit', 'text', 2147483647, 1, 4),
-('bx_timeline_post_edit', 'published', 192, 1, 5),
-('bx_timeline_post_edit', 'location', 2147483647, 1, 6),
-('bx_timeline_post_edit', 'controls', 2147483647, 1, 7),
-('bx_timeline_post_edit', 'tlb_do_submit', 2147483647, 1, 8),
-('bx_timeline_post_edit', 'tlb_do_cancel', 2147483647, 1, 9);
+('bx_timeline_post_edit', 'attachments', 2147483647, 1, 5),
+('bx_timeline_post_edit', 'published', 192, 1, 6),
+('bx_timeline_post_edit', 'location', 2147483647, 1, 7),
+('bx_timeline_post_edit', 'link', 2147483647, 1, 8),
+('bx_timeline_post_edit', 'photo', 2147483647, 1, 9),
+('bx_timeline_post_edit', 'video', 2147483647, 1, 10),
+('bx_timeline_post_edit', 'controls', 2147483647, 1, 11),
+('bx_timeline_post_edit', 'tlb_do_submit', 2147483647, 1, 12),
+('bx_timeline_post_edit', 'tlb_do_cancel', 2147483647, 1, 13);
 
 -- Forms -> Attach link
 INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_attrs`, `submit_name`, `table`, `key`, `uri`, `uri_title`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
@@ -447,16 +451,18 @@ INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `v
 ('bx_timeline_attach_link_add', @sName, 'bx_timeline_attach_link', '_bx_timeline_form_attach_link_display_add', 0);
 
 INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES
+('bx_timeline_attach_link', @sName, 'event_id', '0', '', 0, 'hidden', '_bx_timeline_form_attach_link_input_sys_event_id', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_timeline_attach_link', @sName, 'url', '', '', 0, 'text', '_bx_timeline_form_attach_link_input_sys_url', '_bx_timeline_form_attach_link_input_url', '', 0, 0, 0, '', '', '', 'Preg', 'a:1:{s:4:"preg";s:0:"";}', '_bx_timeline_form_attach_link_input_url_err', '', '', 0, 0),
 ('bx_timeline_attach_link', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_timeline_attach_link', @sName, 'do_submit', '_bx_timeline_form_attach_link_input_do_submit', '', 0, 'submit', '_bx_timeline_form_attach_link_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_timeline_attach_link', @sName, 'do_cancel', '_bx_timeline_form_attach_link_input_do_cancel', '', 0, 'button', '_bx_timeline_form_attach_link_input_do_cancel', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0);
 
 INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
-('bx_timeline_attach_link_add', 'url', 2147483647, 1, 1),
-('bx_timeline_attach_link_add', 'controls', 2147483647, 1, 2),
-('bx_timeline_attach_link_add', 'do_submit', 2147483647, 1, 3),
-('bx_timeline_attach_link_add', 'do_cancel', 2147483647, 1, 4);
+('bx_timeline_attach_link_add', 'event_id', 2147483647, 1, 1),
+('bx_timeline_attach_link_add', 'url', 2147483647, 1, 2),
+('bx_timeline_attach_link_add', 'controls', 2147483647, 1, 3),
+('bx_timeline_attach_link_add', 'do_submit', 2147483647, 1, 4),
+('bx_timeline_attach_link_add', 'do_cancel', 2147483647, 1, 5);
 
 
 -- COMMENTS

+ 8 - 3
modules/boonex/timeline/js/post.js

@@ -191,8 +191,12 @@ BxTimelinePost.prototype.afterFormAttachLinkSubmit = function (oForm, oData)
             if(!$.trim(oData.item).length)
                 return;
 
+            var iEventId = 0;
+            if(oData && oData.event_id != undefined)
+                iEventId = parseInt(oData.event_id);
+
             var oItem = $(oData.item).hide();
-            $('#' + $this._aHtmlIds['attach_link_form_field']).prepend(oItem).find('#' + oItem.attr('id')).bx_anim('show', $this._sAnimationEffect, $this._sAnimationSpeed);
+            $('#' + $this._aHtmlIds['attach_link_form_field'] + iEventId).prepend(oItem).find('#' + oItem.attr('id')).bx_anim('show', $this._sAnimationEffect, $this._sAnimationSpeed);
 
             return;
         }
@@ -279,9 +283,10 @@ BxTimelinePost.prototype.addAttachLink = function(oElement, sUrl)
     );
 };
 
-BxTimelinePost.prototype.showAttachLink = function(oLink)
+BxTimelinePost.prototype.showAttachLink = function(oLink, iEventId)
 {
-    var oData = this._getDefaultData();    
+    var oData = this._getDefaultData();
+    oData['event_id'] = iEventId;
 
     $(window).dolPopupAjax({
         id: {value: this._aHtmlIds['attach_link_popup'], force: true},

+ 2 - 0
modules/boonex/timeline/js/view.js

@@ -1159,6 +1159,8 @@ BxTimelineView.prototype._onGetPost = function(oData)
     this.oView.find(sItem).find('.bx-tl-item-text .bx-tl-content').checkOverflowHeight(this.sSP + '-overflow', function(oElement) {
         $this.onFindOverflow(oElement);
     });
+
+    this.initFlickity();
 };
 
 BxTimelineView.prototype._markPost = function(oLink, iId, iWay, sAction)

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

@@ -1,9 +1,9 @@
 <div id="bx-uploader-file-{storage_object}-{file_id}" class="bx-tl-uploader-file bx-def-margin-sec-top bx-def-margin-sec-left-auto">
+    <input type="hidden" name="__name__[]" value="{file_id}" />
     <div class="bx-tl-uploader-file-preview bx-def-round-corners">
     	<img src="<bx_image_url:spacer.gif />" style="background-image:url({file_icon})" />
     </div>
     <div class="bx-tl-uploader-file-actions bx-def-margin-thd-top bx-clearfix">
     	<a class="bx-btn bx-btn-small" href="javascript:void(0);" onclick="{js_instance_name}.deleteGhost('{file_id}')"><bx_text:_Delete /></a>
-    	__nested_form__
     </div>
 </div>

+ 2 - 1
template/scripts/BxBaseFormView.php

@@ -1313,7 +1313,8 @@ BLAH;
      */
     function genInputFiles(&$aInput, $sInfo = '', $sError = '')
     {
-        $sUniqId = genRndPwd (8, false);
+        $sUniqId = !empty($aInput['uploaders_id']) ? $aInput['uploaders_id'] : genRndPwd (8, false);
+
         $sUploaders = '';
         $oUploader = null;
         foreach ($aInput['uploaders'] as $sUploaderObject) {