Просмотр исходного кода

#24 - Video transcoder integration.

AntonLV 12 лет назад
Родитель
Сommit
cbfd06ec24

+ 2 - 2
inc/classes/BxDolMenu.php

@@ -130,7 +130,7 @@ class BxDolMenu extends BxDol implements iBxDolFactoryObject, iBxDolReplaceable
      * @param $sObject object name
      * @return object instance or false on error
      */
-    static public function getObjectInstance($sObject)
+    static public function getObjectInstance($sObject, $oTemplate = false)
     {
         if (isset($GLOBALS['bxDolClasses']['BxDolMenu!'.$sObject]))
             return $GLOBALS['bxDolClasses']['BxDolMenu!'.$sObject];
@@ -149,7 +149,7 @@ class BxDolMenu extends BxDol implements iBxDolFactoryObject, iBxDolReplaceable
                 bx_import($sClass);
         }
 
-        $o = new $sClass($aObject);
+        $o = new $sClass($aObject, $oTemplate);
 
         return ($GLOBALS['bxDolClasses']['BxDolMenu!'.$sObject] = $o);
     }

+ 4 - 8
inc/classes/BxDolTranscoderVideo.php

@@ -69,15 +69,11 @@ bx_import('BxDolTranscoderVideoQuery');
  * $oTranscoderPoster->registerHandlers(); 
  *
  * // get URLs of transcoded videos and video thumbnail, 33 is ID of original video file stored in specified storage object
- * $sUrlMp4 = $oTranscoder->getFileUrl(33);
- * $sUrlWebM = $oTranscoder->getFileUrl(33);
- * $sUrlPoster = $oTranscoder->getFileUrl(33);
+ * $sUrlMp4 = $oTranscoderMp4->getFileUrl(33);
+ * $sUrlWebM = $oTranscoderWebm->getFileUrl(33);
+ * $sUrlPoster = $oTranscoderPoster->getFileUrl(33);
  *
- * echo 'My cat:
- *     <video poster="' . $sUrlPoster . '">
- *         <source type="video/webm; codecs="vp8, vorbis" src="' . $sUrlWebM . '" />
- *         <source type="video/mp4" src="' . $sUrlMp4 . '" />
- *     </video>'; 
+ * echo 'My cat:' . BxTemplFunctions::getInstance()->videoPlayer($sUrlPoster, $sUrlMP4, $sUrlWebM); 
  * @endcode
  *
  * Also @see transcoder_videos sample for complete example.

+ 5 - 0
modules/base/notifications/classes/BxBaseModNotificationsModule.php

@@ -80,6 +80,11 @@ class BxBaseModNotificationsModule extends BxDolModule
 		return true;
     }
 
+    public function getOwnerId()
+    {
+    	return $this->_iOwnerId;
+    }
+
 	public function getUserId()
     {
         return isLogged() ? bx_get_logged_profile_id() : 0;

+ 23 - 9
modules/boonex/timeline/classes/BxTimelineConfig.php

@@ -22,7 +22,8 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
     protected $_sStorageObject;
     protected $_sTranscoderObjectPreview;
     protected $_sTranscoderObjectView;
-    protected $_aImageUploaders;
+    protected $_aPhotoUploaders;
+    protected $_aVideoUploaders;
 
     protected $_sMenuItemManage;
     protected $_sMenuItemActions;
@@ -67,13 +68,22 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
         	'alert' => $this->_sName,
         	'comment' => $this->CNF['OBJECT_COMMENTS'],
         	'vote' => $this->_sName,
-        	'storage' => $this->_sName . '_photos',
-        	'transcoder_preview' => $this->_sName . '_photos_preview',
-        	'transcoder_view' => $this->_sName . '_photos_view',
+        	'metatags' => $this->_sName,
+
+        	'storage_photos' => $this->_sName . '_photos',
+        	'storage_videos' => $this->_sName . '_videos',
+        	'transcoder_photos_preview' => $this->_sName . '_photos_preview',
+        	'transcoder_photos_view' => $this->_sName . '_photos_view',
+        	'transcoder_videos_poster' => $this->_sName . '_videos_poster',
+        	'transcoder_videos_mp4' => $this->_sName . '_videos_mp4',
+        	'transcoder_videos_webm' => $this->_sName . '_videos_webm',
+
         	'conn_subscriptions' => 'sys_profiles_subscriptions',
+
         	'menu_item_manage' => $this->_sName . '_menu_item_manage',
         	'menu_item_actions' => $this->_sName . '_menu_item_actions',
-        	'metatags' => $this->_sName,
+        	'menu_post_attachments' => $this->_sName . '_menu_post_attachments',
+
         	'form_post' => $this->_sName . '_post',
         	'form_attach_link' => $this->_sName . '_attach_link',
         	'form_display_post_add' => $this->_sName . '_post_add',
@@ -83,7 +93,8 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
         $this->_aHandlerDescriptor = array('module_name' => '', 'module_method' => '', 'module_class' => '', 'groupable' => '', 'group_by' => '');
         $this->_sHandlersMethod = 'get_timeline_data';
 
-        $this->_aImageUploaders = array($this->_sName . '_simple');
+        $this->_aPhotoUploaders = array($this->_sName . '_simple_photo');
+        $this->_aVideoUploaders = array($this->_sName . '_simple_video');
 
         $this->_bJsMode = false;
         $this->_aJsClass = array(
@@ -161,11 +172,14 @@ class BxTimelineConfig extends BxBaseModNotificationsConfig
 
     public function getUploaders($sType)
     {
-        $aResult = '';
+        $aResult = array();
 
         switch($sType) {
-            case 'image':
-                $aResult = $this->_aImageUploaders;
+            case 'photo':
+                $aResult = $this->_aPhotoUploaders;
+                break;
+			case 'video':
+                $aResult = $this->_aVideoUploaders;
                 break;
         }
 

+ 28 - 9
modules/boonex/timeline/classes/BxTimelineDb.php

@@ -15,6 +15,9 @@ class BxTimelineDb extends BxBaseModNotificationsDb
 {
     protected $_sTablesShareTrack;
 
+    protected $_aTablesMedia;
+    protected $_aTablesMedia2Events;
+
     /*
      * Constructor.
      */
@@ -22,6 +25,15 @@ class BxTimelineDb extends BxBaseModNotificationsDb
     {
         parent::__construct($oConfig);
         $this->_sTableSharesTrack = $this->_sPrefix . 'shares_track';
+
+        $this->_aTablesMedia = array(
+        	BX_TIMELINE_MEDIA_PHOTO => $this->_sPrefix . 'photos',
+        	BX_TIMELINE_MEDIA_VIDEO => $this->_sPrefix . 'videos' 
+        );
+        $this->_aTablesMedia2Events = array(
+        	BX_TIMELINE_MEDIA_PHOTO => $this->_sPrefix . 'photos2events',
+        	BX_TIMELINE_MEDIA_VIDEO => $this->_sPrefix . 'videos2events'
+        );
     }
 
     public function getMaxDuration($aParams)
@@ -94,29 +106,36 @@ class BxTimelineDb extends BxBaseModNotificationsDb
     }
 
     //--- Photo uploader related methods ---//
-    public function savePhoto($iEventId, $iPhId)
+    public function saveMedia($sType, $iEventId, $iItemId)
     {
-        $sQuery = $this->prepare("INSERT INTO `" . $this->_sPrefix . "photos2events` SET `event_id`=?, `photo_id`=?", $iEventId, $iPhId);
+    	$sTable = $this->_aTablesMedia2Events[$sType];
+
+        $sQuery = $this->prepare("INSERT INTO `" . $sTable . "` SET `event_id`=?, `media_id`=?", $iEventId, $iItemId);
         return (int)$this->query($sQuery) > 0;
     }
 
-    public function deletePhotos($iEventId)
+    public function deleteMedia($sType, $iEventId)
     {
-        $sQuery = $this->prepare("DELETE FROM `" . $this->_sPrefix . "photos2events` WHERE `event_id` = ?", $iEventId);
+    	$sTable = $this->_aTablesMedia2Events[$sType];
+
+        $sQuery = $this->prepare("DELETE FROM `" . $sTable . "` WHERE `event_id` = ?", $iEventId);
         return (int)$this->query($sQuery) > 0;
     }
 
-    public function getPhotos($iEventId, $iOffset = 0)
+    public function getMedia($sType, $iEventId, $iOffset = 0)
     {
+    	$sTableMedia = $this->_aTablesMedia[$sType];
+    	$sTableMedia2Events = $this->_aTablesMedia2Events[$sType];
+
         $sLimitAddon = '';
         if($iOffset != 0)
             $sLimitAddon = $this->prepare(" OFFSET ?", $iOffset);
 
         $sQuery = $this->prepare("SELECT
-                 `tpe`.`photo_id` AS `id`
-            FROM `" . $this->_sPrefix . "photos2events` AS `tpe`
-            LEFT JOIN `" . $this->_sPrefix . "photos` AS `tp` ON `tpe`.`photo_id` = `tp`.`id`
-            WHERE `tpe`.`event_id` = ?" . $sLimitAddon, $iEventId);
+                 `tme`.`media_id` AS `id`
+            FROM `" . $sTableMedia2Events . "` AS `tme`
+            LEFT JOIN `" . $sTableMedia . "` AS `tm` ON `tme`.`media_id`=`tm`.`id`
+            WHERE `tme`.`event_id`=?" . $sLimitAddon, $iEventId);
 
         return $this->getColumn($sQuery);
     }

+ 0 - 27
modules/boonex/timeline/classes/BxTimelineForm.php

@@ -1,27 +0,0 @@
-<?php defined('BX_DOL') or die('hack attempt');
-/**
- * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
- * CC-BY License - http://creativecommons.org/licenses/by/3.0/
- *
- * @defgroup    Timeline Timeline
- * @ingroup     DolphinModules
- *
- * @{
- */
-
-bx_import('BxBaseModGeneralFormEntry');
-
-/**
- * Create/Edit entry form
- */
-class BxTimelineForm extends BxBaseModGeneralFormEntry
-{
-    public function __construct($aInfo, $oTemplate = false)
-    {
-        $this->MODULE = 'bx_timeline';
-
-        parent::__construct($aInfo, $oTemplate);
-    }
-}
-
-/** @} */

+ 86 - 0
modules/boonex/timeline/classes/BxTimelineFormPost.php

@@ -0,0 +1,86 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Timeline Timeline
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModGeneralFormEntry');
+
+/**
+ * Create/Edit entry form
+ */
+class BxTimelineFormPost extends BxBaseModGeneralFormEntry
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_timeline';
+
+        parent::__construct($aInfo, $oTemplate);
+
+        $iUserId = $this->_oModule->getUserId();
+        $iOwnerId = $this->_oModule->getOwnerId();
+
+		$this->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oModule->_oConfig->getBaseUri() . 'post/';
+        $this->aInputs['owner_id']['value'] = $iOwnerId;
+
+        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(),
+            );
+
+            bx_import('BxDolFormNested');
+            $oFormNested = new BxDolFormNested('photo', $aFormNested, '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'] = $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['video'])) {
+            $aFormNested = array(
+                'params' =>array(
+                    'nested_form_template' => 'uploader_nfw.html'
+                ),
+                'inputs' => array(),
+            );
+
+            bx_import('BxDolFormNested');
+            $oFormNested = new BxDolFormNested('video', $aFormNested, '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'] = $this->_oModule->_oConfig->getUploaders('video');
+            $this->aInputs['video']['upload_buttons_titles'] = array('Simple' => 'video-camera');
+            $this->aInputs['video']['multiple'] = true;
+            $this->aInputs['video']['ghost_template'] = $oFormNested;
+        }
+
+        if(isset($this->aInputs['attachments']))
+            $this->aInputs['attachments']['content'] = '__attachments_menu__';
+    }
+
+    public function getCode($bDynamicMode = false)
+    {
+    	$sResult = parent::getCode($bDynamicMode);
+
+    	return $this->_oModule->_oTemplate->parseHtmlByContent($sResult, array(
+    		'attachments_menu' => $this->_oModule->getAttachmentsMenuObject()->getCode()
+    	));
+    }
+}
+
+/** @} */

+ 56 - 49
modules/boonex/timeline/classes/BxTimelineModule.php

@@ -23,6 +23,9 @@ define('BX_TIMELINE_PARSE_TYPE_POST', 'post');
 define('BX_TIMELINE_PARSE_TYPE_SHARE', 'share');
 define('BX_TIMELINE_PARSE_TYPE_DEFAULT', BX_TIMELINE_PARSE_TYPE_POST);
 
+define('BX_TIMELINE_MEDIA_PHOTO', 'photo');
+define('BX_TIMELINE_MEDIA_VIDEO', 'video');
+
 class BxTimelineModule extends BxBaseModNotificationsModule
 {
     protected $_sJsPostObject;
@@ -483,30 +486,6 @@ class BxTimelineModule extends BxBaseModNotificationsModule
 
         bx_import('BxDolForm');
         $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_post'), $this->_oConfig->getObject('form_display_post_add'), $this->_oTemplate);
-        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'post/';
-        $oForm->aInputs['owner_id']['value'] = $this->_iOwnerId;
-
-        if(isset($oForm->aInputs['link']))
-            $oForm->aInputs['link']['content'] = $this->_oTemplate->getAttachLinkField($iUserId);
-
-        if(isset($oForm->aInputs['photo'])) {
-            $aFormNested = array(
-                'params' =>array(
-                    'nested_form_template' => 'uploader_nfw.html'
-                ),
-                'inputs' => array(),
-            );
-
-            bx_import('BxDolFormNested');
-            $oFormNested = new BxDolFormNested('photo', $aFormNested, 'do_submit', $this->_oTemplate);
-
-            $oForm->aInputs['photo']['storage_object'] = $this->_oConfig->getObject('storage');
-            $oForm->aInputs['photo']['images_transcoder'] = $this->_oConfig->getObject('transcoder_preview');
-            $oForm->aInputs['photo']['uploaders'] = $this->_oConfig->getUploaders('image');
-            $oForm->aInputs['photo']['upload_buttons_titles'] = array('Simple' => 'camera');
-            $oForm->aInputs['photo']['multiple'] = true;
-            $oForm->aInputs['photo']['ghost_template'] = $oFormNested;
-        }
 
         $oForm->initChecker();
         if($oForm->isSubmittedAndValid()) {
@@ -526,11 +505,10 @@ class BxTimelineModule extends BxBaseModNotificationsModule
 
             //--- Process Link ---//
             $aLinkIds = $oForm->getCleanValue('link');
-            unset($oForm->aInputs['link']);
 
-            //--- Process Photos ---//
-            $aPhotoIds = $oForm->getCleanValue('photo');
-            unset($oForm->aInputs['photo']);
+            //--- Process Media ---//
+            $aPhotoIds = $oForm->getCleanValue(BX_TIMELINE_MEDIA_PHOTO);
+            $aVideoIds = $oForm->getCleanValue(BX_TIMELINE_MEDIA_VIDEO);
 
             $sTitle = _t('_bx_timeline_txt_user_added_sample', $sUserName, _t('_bx_timeline_txt_sample'));
             $sDescription = !empty($aContent['text']) ? $aContent['text'] : '';
@@ -550,18 +528,14 @@ class BxTimelineModule extends BxBaseModNotificationsModule
  				$oMetatags->keywordsAdd($iId, $aContent['text']);
  				$oMetatags->locationsAddFromForm($iId, $this->_oConfig->CNF['FIELD_LOCATION_PREFIX']);
 
+				//--- Process Link ---//
                 if(!empty($aLinkIds) && is_array($aLinkIds))
                     foreach($aLinkIds as $iLinkId)
                         $this->_oDb->saveLink($iId, $iLinkId);
 
-                if(!empty($aPhotoIds) && is_array($aPhotoIds)) {
-                    bx_import('BxDolStorage');
-                    $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage'));
-
-                    foreach($aPhotoIds as $iPhotoId)
-                        if($this->_oDb->savePhoto($iId, $iPhotoId))
-                            $oStorage->afterUploadCleanup($iPhotoId, $iUserId);
-                }
+				//--- Process Media ---// 
+				$this->_saveMedia(BX_TIMELINE_MEDIA_PHOTO, $iId, $aPhotoIds);
+				$this->_saveMedia(BX_TIMELINE_MEDIA_VIDEO, $iId, $aVideoIds);
 
                 $this->onPost($iId);
 
@@ -600,13 +574,24 @@ class BxTimelineModule extends BxBaseModNotificationsModule
         return $oVote;
     }
 
+    public function getAttachmentsMenuObject()
+    {
+		bx_import('BxDolMenu');
+        $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_post_attachments'), $this->_oTemplate);
+        $oMenu->addMarkers(array(
+            'js_object' => $this->_oConfig->getJsObject('post'),
+        ));
+
+        return $oMenu;
+    }
+
     public function getManageMenuObject($mixedEvent)
     {
     	if(!is_array($mixedEvent))
     		$mixedEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => (int)$mixedEvent));
 
         bx_import('BxDolMenu');
-        $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_item_manage'));
+        $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_item_manage'), $this->_oTemplate);
         $oMenu->setEvent($mixedEvent);
         return $oMenu;
     }
@@ -737,19 +722,11 @@ class BxTimelineModule extends BxBaseModNotificationsModule
     {
     	$sCommonPostPrefix = $this->_oConfig->getPrefix('common_post');
 
-    	//--- Delete attached photos and links when common event was deleted.
+    	//--- Delete attached photos, videos and links when common event was deleted.
     	if($aEvent['type'] == $sCommonPostPrefix . BX_TIMELINE_PARSE_TYPE_POST) {
-	        $aPhotos = $this->_oDb->getPhotos($aEvent['id']);
-	        if(!empty($aPhotos) && is_array($aPhotos)) {
-	            bx_import('BxDolStorage');
-	            $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage'));
-	
-	            foreach($aPhotos as $iPhotoId)
-	                $oStorage->deleteFile($iPhotoId);
-	
-	            $this->_oDb->deletePhotos($aEvent['id']);
-	        }
-	
+    		$this->_deleteMedia(BX_TIMELINE_MEDIA_PHOTO, $aEvent['id']);
+    		$this->_deleteMedia(BX_TIMELINE_MEDIA_VIDEO, $aEvent['id']);
+
 	        $this->_oDb->deleteLinks($aEvent['id']);
     	}
 
@@ -812,6 +789,36 @@ class BxTimelineModule extends BxBaseModNotificationsModule
         return array($sSystem, $iObjectId, $iCount);
     }
 
+    protected function _saveMedia($sType, $iId, $aItemIds)
+    {
+    	if(empty($aItemIds) || !is_array($aItemIds))
+    		return; 
+
+    	$iUserId = $this->getUserId();
+
+		bx_import('BxDolStorage');
+		$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);
+    }
+
+    protected function _deleteMedia($sType, $iId)
+    {
+	    $aItems = $this->_oDb->getMedia($sType, $iId);
+	    if(empty($aItems) || !is_array($aItems))
+	    	return;
+
+		bx_import('BxDolStorage');
+		$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . strtolower($sType) . 's'));
+
+		foreach($aItems as $iItemId)
+			$oStorage->deleteFile($iItemId);
+
+		$this->_oDb->deleteMedia($sType, $iId);
+    }
+
     protected function _prepareParams($sType, $iOwnerId, $iStart, $iPerPage, $sFilter, $aModules, $iTimeline)
     {
         $aParams = array();

+ 36 - 4
modules/boonex/timeline/classes/BxTimelineTemplate.php

@@ -691,6 +691,16 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
             }
         }
 
+    	//--- Process Videos ---//
+        $aTmplVarsVideos = array();
+        if(!empty($aContent['videos']))
+            foreach($aContent['videos'] as $aVideo) {
+                $aTmplVarsVideos[] = array(
+                    'style_prefix' => $sStylePrefix,
+                	'video' => BxTemplFunctions::getInstance()->videoPlayer($aVideo['src_poster'], $aVideo['src_mp4'], $aVideo['src_webm']) 
+                );
+            }
+
         return array(
             'style_prefix' => $sStylePrefix,
             'bx_if:show_title' => array(
@@ -728,6 +738,13 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
                     'style_prefix' => $sStylePrefix,
                     'bx_repeat:images' => $aTmplVarsImages
                 )
+            ),
+            'bx_if:show_videos' => array(
+                'condition' => !empty($aTmplVarsVideos),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'bx_repeat:videos' => $aTmplVarsVideos
+                )
             )
         );
     }
@@ -826,16 +843,15 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
                             'text' => $aLink['text']
                         );
 
-                $aPhotos = $this->_oDb->getPhotos($aEvent['id']);
+                $aPhotos = $this->_oDb->getMedia(BX_TIMELINE_MEDIA_PHOTO, $aEvent['id']);
                 if(!empty($aPhotos) && is_array($aPhotos)) {
                     bx_import('BxDolStorage');
-                    $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage'));
+                    $oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'));
 
                     bx_import('BxDolTranscoderImage');
-                    $oTranscoder = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_view'));
+                    $oTranscoder = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_view'));
 
                     foreach($aPhotos as $iPhotoId) {
-                        $iPhotoIndex = array_search($iPhotoId, $aPhotos);
                         $sPhotoSrcOrig = $oStorage->getFileUrlById($iPhotoId);
 
                         $aResult['content']['images'][] = array(
@@ -846,6 +862,22 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
                         );
                     }
                 }
+
+                $aVideos = $this->_oDb->getMedia(BX_TIMELINE_MEDIA_VIDEO, $aEvent['id']);
+                if(!empty($aVideos) && is_array($aVideos)) {
+                	bx_import('BxDolTranscoderVideo');
+                    $oTranscoderPoster = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_poster'));
+                    $oTranscoderMp4 = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_mp4'));
+                    $oTranscoderWebm = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_webm'));
+
+                    foreach($aVideos as $iVideoId) {
+                        $aResult['content']['videos'][] = array(
+                            'src_poster' => $oTranscoderPoster->getFileUrl($iVideoId),
+                        	'src_mp4' => $oTranscoderMp4->getFileUrl($iVideoId),
+                        	'src_webm' => $oTranscoderWebm->getFileUrl($iVideoId),
+                        );
+                    }
+                }
                 break;
 
             case BX_TIMELINE_PARSE_TYPE_SHARE:

+ 0 - 42
modules/boonex/timeline/classes/BxTimelineUploaderSimple.php

@@ -1,42 +0,0 @@
-<?php defined('BX_DOL') or die('hack attempt');
-/**
- * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
- * CC-BY License - http://creativecommons.org/licenses/by/3.0/
- *
- * @defgroup    Timeline Timeline
- * @ingroup     DolphinModules
- *
- * @{
- */
-
-bx_import ('BxTemplUploaderSimple');
-bx_import('BxDolModule');
-
-/**
- * Upload files using standard HTML forms.
- * @see BxBaseUploaderSimple, BxDolUploader
- */
-class BxTimelineUploaderSimple extends BxTemplUploaderSimple
-{
-    public function __construct ($aObject, $sStorageObject, $sUniqId)
-    {
-        parent::__construct($aObject, $sStorageObject, $sUniqId);
-
-        $oModule = BxDolModule::getInstance('bx_timeline');
-
-        $this->_oTemplate = $oModule->_oTemplate;
-        $this->_sButtonTemplate = 'uploader_bs.html';
-    }
-
-    public function getUploaderButton($mixedGhostTemplate, $isMultiple = true, $aParams = array())
-    {
-        $sResult = parent::getUploaderButton($mixedGhostTemplate, $isMultiple, $aParams);
-
-        $oModule = BxDolModule::getInstance('bx_timeline');
-        return $this->_oTemplate->parseHtmlByContent($sResult, array(
-            'js_object' => $oModule->_oConfig->getJsObject('post'),
-        ));
-    }
-}
-
-/** @} */

+ 30 - 0
modules/boonex/timeline/classes/BxTimelineUploaderSimplePhoto.php

@@ -0,0 +1,30 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Timeline Timeline
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import ('BxTemplUploaderSimple');
+bx_import('BxDolModule');
+
+class BxTimelineUploaderSimplePhoto extends BxTemplUploaderSimple
+{
+    public function __construct ($aObject, $sStorageObject, $sUniqId)
+    {
+        parent::__construct($aObject, $sStorageObject, $sUniqId);
+
+        $oModule = BxDolModule::getInstance('bx_timeline');
+		$oModule->getAttachmentsMenuObject()->addMarkers(array(
+			'js_object_uploader_photo' => $this->getNameJsInstanceUploader()
+		));
+
+		$this->_oTemplate = $oModule->_oTemplate;
+    }
+}
+
+/** @} */

+ 30 - 0
modules/boonex/timeline/classes/BxTimelineUploaderSimpleVideo.php

@@ -0,0 +1,30 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Timeline Timeline
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import ('BxTemplUploaderSimple');
+bx_import('BxDolModule');
+
+class BxTimelineUploaderSimpleVideo extends BxTemplUploaderSimple
+{
+    public function __construct ($aObject, $sStorageObject, $sUniqId)
+    {
+        parent::__construct($aObject, $sStorageObject, $sUniqId);
+
+        $oModule = BxDolModule::getInstance('bx_timeline');
+		$oModule->getAttachmentsMenuObject()->addMarkers(array(
+			'js_object_uploader_video' => $this->getNameJsInstanceUploader()
+		));
+
+		$this->_oTemplate = $oModule->_oTemplate;
+    }
+}
+
+/** @} */

+ 6 - 2
modules/boonex/timeline/install/config.php

@@ -51,7 +51,8 @@ $aConfig = array(
      * Storages.
      */
     'storages' => array(
-    	'bx_timeline_photos'
+    	'bx_timeline_photos',
+    	'bx_timeline_videos'
     ),
 
     /**
@@ -59,7 +60,10 @@ $aConfig = array(
      */
     'transcoders' => array(
     	'bx_timeline_photos_preview',
-    	'bx_timeline_photos_view'
+    	'bx_timeline_photos_view',
+    	'bx_timeline_videos_poster',
+    	'bx_timeline_videos_mp4',
+    	'bx_timeline_videos_webm'
     ),
 
     /**

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

@@ -24,9 +24,13 @@
 	<string name="_bx_timeline_form_post_input_sys_link"><![CDATA[Link]]></string>
 	<string name="_bx_timeline_form_post_input_link_alt"><![CDATA[Add Link]]></string>
 	<string name="_bx_timeline_form_post_input_link_err_delete"><![CDATA[Cannot remove the link. Please report.]]></string>
-	<string name="_bx_timeline_form_post_input_sys_photo"><![CDATA[Content]]></string>
+	<string name="_bx_timeline_form_post_input_sys_photo"><![CDATA[Photo]]></string>
 	<string name="_bx_timeline_form_post_input_photo"><![CDATA[]]></string>
 	<string name="_bx_timeline_form_post_input_photo_alt"><![CDATA[Add Photo]]></string>
+	<string name="_bx_timeline_form_post_input_sys_video"><![CDATA[Video]]></string>
+	<string name="_bx_timeline_form_post_input_video"><![CDATA[]]></string>
+	<string name="_bx_timeline_form_post_input_video_alt"><![CDATA[Add Video]]></string>
+	<string name="_bx_timeline_form_post_input_sys_attachments"><![CDATA[Attachments]]></string>
 	<string name="_bx_timeline_form_post_input_sys_do_submit"><![CDATA[Post]]></string>
 	<string name="_bx_timeline_form_post_input_do_submit"><![CDATA[Post]]></string>
 
@@ -79,6 +83,15 @@
     <string name="_bx_timeline_menu_item_title_system_item_share"><![CDATA[Share]]></string>
     <string name="_bx_timeline_menu_item_title_item_share"><![CDATA[Share]]></string>
 
+	<string name="_bx_timeline_menu_title_post_attachments"><![CDATA[Form Attachments]]></string>
+    <string name="_bx_timeline_menu_set_title_post_attachments"><![CDATA[Form Attachments]]></string>
+    <string name="_bx_timeline_menu_item_title_system_add_link"><![CDATA[Add Link]]></string>
+    <string name="_bx_timeline_menu_item_title_add_link"><![CDATA[Add Link]]></string>
+    <string name="_bx_timeline_menu_item_title_system_add_photo"><![CDATA[Add Photo]]></string>
+    <string name="_bx_timeline_menu_item_title_add_photo"><![CDATA[Add Photo]]></string>
+    <string name="_bx_timeline_menu_item_title_system_add_video"><![CDATA[Add Video]]></string>
+    <string name="_bx_timeline_menu_item_title_add_video"><![CDATA[Add Video]]></string>
+
     <string name="_bx_timeline_menu_item_title_system_timeline"><![CDATA[Timeline]]></string>
     <string name="_bx_timeline_menu_item_title_timeline"><![CDATA[Timeline]]></string>
 

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

@@ -53,6 +53,18 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 ('bx_timeline_menu_item_actions', 'bx_timeline', 'item-vote', '_bx_timeline_menu_item_title_system_item_vote', '', 'javascript:void(0)', '', '', '', '', '', 2147483647, 1, 0, 0, 2),
 ('bx_timeline_menu_item_actions', 'bx_timeline', 'item-share', '_bx_timeline_menu_item_title_system_item_share', '_bx_timeline_menu_item_title_item_share', 'javascript:void(0)', 'javascript:{share_onclick}', '_self', 'share', 'a:3:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:25:"get_menu_item_addon_share";s:6:"params";a:3:{i:0;s:12:"{share_type}";i:1;s:14:"{share_action}";i:2;s:14:"{share_object}";}}', '', 2147483647, 1, 0, 1, 3);
 
+-- MENU: Post form attachments (Link, Photo, Video)
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_timeline_menu_post_attachments', '_bx_timeline_menu_title_post_attachments', 'bx_timeline_menu_post_attachments', 'bx_timeline', 9, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_timeline_menu_post_attachments', 'bx_timeline', '_bx_timeline_menu_set_title_post_attachments', 0);
+
+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-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', '_bx_timeline_menu_item_title_system_add_photo', '_bx_timeline_menu_item_title_add_photo', 'javascript:void(0)', 'javascript:{js_object_uploader_photo}.showUploaderForm();', '_self', 'camera', '', '', 2147483647, 1, 0, 1, 2),
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-video', '_bx_timeline_menu_item_title_system_add_video', '_bx_timeline_menu_item_title_add_video', 'javascript:void(0)', 'javascript:{js_object_uploader_video}.showUploaderForm();', '_self', 'video-camera', '', '', 2147483647, 1, 0, 1, 3);
+
 
 -- SETTINGS
 SET @iTypeOrder = (SELECT MAX(`order`) FROM `sys_options_types` WHERE `group` = 'modules');

+ 58 - 19
modules/boonex/timeline/install/sql/install.sql

@@ -37,7 +37,7 @@ INSERT INTO `bx_timeline_handlers`(`type`, `alert_unit`, `alert_action`, `conten
 ('insert', 'timeline_common_share', '', ''),
 ('delete', 'profile', 'delete', '');
 
--- TABLES: UPLOADERS
+-- TABLES: STORAGES, TRANSCODERS, UPLOADERS
 CREATE TABLE IF NOT EXISTS `bx_timeline_photos` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `profile_id` int(10) unsigned NOT NULL,
@@ -54,7 +54,7 @@ CREATE TABLE IF NOT EXISTS `bx_timeline_photos` (
   UNIQUE KEY `remote_id` (`remote_id`)
 );
 
-CREATE TABLE IF NOT EXISTS `bx_timeline_photos_preview` (
+CREATE TABLE IF NOT EXISTS `bx_timeline_photos_processed` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `profile_id` int(10) unsigned NOT NULL,
   `remote_id` varchar(255) NOT NULL,
@@ -70,7 +70,15 @@ CREATE TABLE IF NOT EXISTS `bx_timeline_photos_preview` (
   UNIQUE KEY `remote_id` (`remote_id`)
 );
 
-CREATE TABLE IF NOT EXISTS `bx_timeline_photos_view` (
+CREATE TABLE IF NOT EXISTS `bx_timeline_photos2events` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `event_id` int(11) NOT NULL DEFAULT '0',
+  `media_id` int(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `media` (`event_id`, `media_id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `bx_timeline_videos` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `profile_id` int(10) unsigned NOT NULL,
   `remote_id` varchar(255) NOT NULL,
@@ -86,12 +94,28 @@ CREATE TABLE IF NOT EXISTS `bx_timeline_photos_view` (
   UNIQUE KEY `remote_id` (`remote_id`)
 );
 
-CREATE TABLE IF NOT EXISTS `bx_timeline_photos2events` (
+CREATE TABLE IF NOT EXISTS `bx_timeline_videos_processed` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(255) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_timeline_videos2events` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `event_id` int(11) NOT NULL DEFAULT '0',
-  `photo_id` int(11) NOT NULL DEFAULT '0',
+  `media_id` int(11) NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`),
-  UNIQUE KEY `photo` (`event_id`, `photo_id`)
+  UNIQUE KEY `media` (`event_id`, `media_id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 -- TABLES: LINKS
@@ -157,14 +181,14 @@ CREATE TABLE IF NOT EXISTS `bx_timeline_votes_track` (
 ) ENGINE=MYISAM DEFAULT CHARSET=utf8;
 
 -- TABLE: metas
-CREATE TABLE `bx_timeline_meta_keywords` (
+CREATE TABLE IF NOT EXISTS `bx_timeline_meta_keywords` (
   `object_id` int(10) unsigned NOT NULL,
   `keyword` varchar(255) NOT NULL,
   KEY `object_id` (`object_id`),
   KEY `keyword` (`keyword`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
-CREATE TABLE `bx_timeline_meta_locations` (
+CREATE TABLE IF NOT EXISTS `bx_timeline_meta_locations` (
   `object_id` int(10) unsigned NOT NULL,
   `lat` double NOT NULL,
   `lng` double NOT NULL,
@@ -178,25 +202,36 @@ CREATE TABLE `bx_timeline_meta_locations` (
 
 -- STORAGES, TRANSCODERS, UPLOADERS
 INSERT INTO `sys_objects_uploader` (`object`, `active`, `override_class_name`, `override_class_file`) VALUES
-('bx_timeline_simple', 1, 'BxTimelineUploaderSimple', 'modules/boonex/timeline/classes/BxTimelineUploaderSimple.php');
+('bx_timeline_simple_photo', 1, 'BxTimelineUploaderSimplePhoto', 'modules/boonex/timeline/classes/BxTimelineUploaderSimplePhoto.php'),
+('bx_timeline_simple_video', 1, 'BxTimelineUploaderSimpleVideo', 'modules/boonex/timeline/classes/BxTimelineUploaderSimpleVideo.php');
 
 INSERT INTO `sys_objects_storage` (`object`, `engine`, `params`, `token_life`, `cache_control`, `levels`, `table_files`, `ext_mode`, `ext_allow`, `ext_deny`, `quota_size`, `current_size`, `quota_number`, `current_number`, `max_file_size`, `ts`) VALUES
 ('bx_timeline_photos', 'Local', '', 360, 2592000, 3, 'bx_timeline_photos', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0),
-('bx_timeline_photos_preview', 'Local', '', 360, 2592000, 3, 'bx_timeline_photos_preview', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0),
-('bx_timeline_photos_view', 'Local', '', 360, 2592000, 3, 'bx_timeline_photos_view', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0);
+('bx_timeline_photos_processed', 'Local', '', 360, 2592000, 3, 'bx_timeline_photos_processed', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0),
 
-INSERT INTO `sys_objects_transcoder` (`object`, `storage_object`, `source_type`, `source_params`, `private`, `atime_tracking`, `atime_pruning`, `ts`) VALUES
-('bx_timeline_photos_preview', 'bx_timeline_photos_preview', 'Storage', 'a:1:{s:6:"object";s:18:"bx_timeline_photos";}', 'no', '1', '2592000', '0'),
-('bx_timeline_photos_view', 'bx_timeline_photos_view', 'Storage', 'a:1:{s:6:"object";s:18:"bx_timeline_photos";}', 'no', '1', '2592000', '0');
+('bx_timeline_videos', 'Local', '', 360, 2592000, 3, 'bx_timeline_videos', 'allow-deny', 'avi,flv,mpg,mpeg,wmv,mp4,m4v,mov,divx,xvid,3gp,webm,jpg', '', 0, 0, 0, 0, 0, 0),
+('bx_timeline_videos_processed', 'Local', '', 360, 2592000, 3, 'bx_timeline_videos_processed', 'allow-deny', 'avi,flv,mpg,mpeg,wmv,mp4,m4v,mov,divx,xvid,3gp,webm,jpg', '', 0, 0, 0, 0, 0, 0);
+
+INSERT INTO `sys_objects_transcoder` (`object`, `storage_object`, `source_type`, `source_params`, `private`, `atime_tracking`, `atime_pruning`, `ts`, `override_class_name`, `override_class_file`) VALUES
+('bx_timeline_photos_preview', 'bx_timeline_photos_processed', 'Storage', 'a:1:{s:6:"object";s:18:"bx_timeline_photos";}', 'no', '1', '2592000', '0', '', ''),
+('bx_timeline_photos_view', 'bx_timeline_photos_processed', 'Storage', 'a:1:{s:6:"object";s:18:"bx_timeline_photos";}', 'no', '1', '2592000', '0', '', ''),
+
+('bx_timeline_videos_poster', 'bx_timeline_videos_processed', 'Storage', 'a:1:{s:6:"object";s:18:"bx_timeline_videos";}', 'no', '0', '0', '0', 'BxDolTranscoderVideo', ''),
+('bx_timeline_videos_mp4', 'bx_timeline_videos_processed', 'Storage', 'a:1:{s:6:"object";s:18:"bx_timeline_videos";}', 'no', '0', '0', '0', 'BxDolTranscoderVideo', ''),
+('bx_timeline_videos_webm', 'bx_timeline_videos_processed', 'Storage', 'a:1:{s:6:"object";s:18:"bx_timeline_videos";}', 'no', '0', '0', '0', 'BxDolTranscoderVideo', '');
 
 INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES
 ('bx_timeline_photos_preview', 'Resize', 'a:4:{s:1:"w";s:3:"100";s:1:"h";s:3:"100";s:13:"square_resize";s:1:"1";s:10:"force_type";s:3:"jpg";}', '0'),
-('bx_timeline_photos_view', 'Resize', 'a:4:{s:1:"w";s:3:"318";s:1:"h";s:3:"318";s:13:"square_resize";s:1:"1";s:10:"force_type";s:3:"jpg";}', '0');
+('bx_timeline_photos_view', 'Resize', 'a:4:{s:1:"w";s:3:"318";s:1:"h";s:3:"318";s:13:"square_resize";s:1:"1";s:10:"force_type";s:3:"jpg";}', '0'),
+
+('bx_timeline_videos_poster', 'Poster', 'a:2:{s:1:"h";s:3:"318";s:10:"force_type";s:3:"jpg";}', 0),
+('bx_timeline_videos_mp4', 'Mp4', 'a:2:{s:1:"h";s:3:"318";s:10:"force_type";s:3:"mp4";}', 0),
+('bx_timeline_videos_webm', 'Webm', 'a:2:{s:1:"h";s:3:"318";s:10:"force_type";s:4:"webm";}', 0);
 
 
 -- Forms -> Post
 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
-('bx_timeline_post', @sName, '_bx_timeline_form_post', '', '', 'do_submit', 'bx_timeline_events', 'id', '', '', '', 0, 1, 'BxTimelineForm', 'modules/boonex/timeline/classes/BxTimelineForm.php');
+('bx_timeline_post', @sName, '_bx_timeline_form_post', '', '', 'do_submit', 'bx_timeline_events', 'id', '', '', '', 0, 1, 'BxTimelineFormPost', 'modules/boonex/timeline/classes/BxTimelineFormPost.php');
 
 INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `view_mode`) VALUES
 ('bx_timeline_post_add', @sName, 'bx_timeline_post', '_bx_timeline_form_post_display_add', 0);
@@ -207,8 +242,10 @@ INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `c
 ('bx_timeline_post', @sName, 'owner_id', '0', '', 0, 'hidden', '_bx_timeline_form_post_input_sys_owner_id', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
 ('bx_timeline_post', @sName, 'text', '', '', 0, 'textarea', '_bx_timeline_form_post_input_sys_text', '_bx_timeline_form_post_input_text', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
 ('bx_timeline_post', @sName, 'location', '', '', 0, 'custom', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
-('bx_timeline_post', @sName, 'link', '', '', 0, 'custom', '_bx_timeline_form_post_input_sys_link', '', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
-('bx_timeline_post', @sName, 'photo', '', '', 0, 'files', '_bx_timeline_form_post_input_sys_photo', '_bx_timeline_form_post_input_photo', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_timeline_post', @sName, 'link', '', '', 0, 'custom', '_bx_timeline_form_post_input_sys_link', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_timeline_post', @sName, 'photo', '', '', 0, 'files', '_bx_timeline_form_post_input_sys_photo', '_bx_timeline_form_post_input_photo', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_timeline_post', @sName, 'video', '', '', 0, 'files', '_bx_timeline_form_post_input_sys_video', '_bx_timeline_form_post_input_video', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_timeline_post', @sName, 'attachments', '', '', 0, 'custom', '_bx_timeline_form_post_input_sys_attachments', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_timeline_post', @sName, 'do_submit', '_bx_timeline_form_post_input_do_submit', '', 0, 'submit', '_bx_timeline_form_post_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0);
 
 INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
@@ -219,7 +256,9 @@ INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_fo
 ('bx_timeline_post_add', 'location', 2147483647, 1, 5),
 ('bx_timeline_post_add', 'link', 2147483647, 1, 6),
 ('bx_timeline_post_add', 'photo', 2147483647, 1, 7),
-('bx_timeline_post_add', 'do_submit', 2147483647, 1, 8);
+('bx_timeline_post_add', 'video', 2147483647, 1, 8),
+('bx_timeline_post_add', 'attachments', 2147483647, 1, 9),
+('bx_timeline_post_add', 'do_submit', 2147483647, 1, 10);
 
 -- 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

+ 9 - 6
modules/boonex/timeline/install/sql/uninstall.sql

@@ -4,10 +4,13 @@ DROP TABLE IF EXISTS `bx_timeline_events`;
 DROP TABLE IF EXISTS `bx_timeline_handlers`;
 
 DROP TABLE IF EXISTS `bx_timeline_photos`;
-DROP TABLE IF EXISTS `bx_timeline_photos_preview`;
-DROP TABLE IF EXISTS `bx_timeline_photos_view`;
+DROP TABLE IF EXISTS `bx_timeline_photos_processed`;
 DROP TABLE IF EXISTS `bx_timeline_photos2events`;
 
+DROP TABLE IF EXISTS `bx_timeline_videos`;
+DROP TABLE IF EXISTS `bx_timeline_videos_processed`;
+DROP TABLE IF EXISTS `bx_timeline_videos2events`;
+
 DROP TABLE IF EXISTS `bx_timeline_links`;
 DROP TABLE IF EXISTS `bx_timeline_links2events`;
 
@@ -21,10 +24,10 @@ DROP TABLE IF EXISTS `bx_timeline_meta_locations`;
 
 
 -- STORAGES, TRANSCODERS, UPLOADERS
-DELETE FROM `sys_objects_uploader` WHERE `object` = 'bx_timeline_simple';
-DELETE FROM `sys_objects_storage` WHERE `object` IN ('bx_timeline_photos', 'bx_timeline_photos_preview', 'bx_timeline_photos_view');
-DELETE FROM `sys_objects_transcoder` WHERE `object` IN ('bx_timeline_photos_preview', 'bx_timeline_photos_view');
-DELETE FROM `sys_transcoder_filters` WHERE `transcoder_object` IN ('bx_timeline_photos_preview', 'bx_timeline_photos_view');
+DELETE FROM `sys_objects_uploader` WHERE `object` LIKE 'bx_timeline%';
+DELETE FROM `sys_objects_storage` WHERE `object`  LIKE 'bx_timeline%';
+DELETE FROM `sys_objects_transcoder` WHERE `object`  LIKE 'bx_timeline%';
+DELETE FROM `sys_transcoder_filters` WHERE `transcoder_object` LIKE 'bx_timeline%';
 
 
 -- Forms All

+ 3 - 4
modules/boonex/timeline/template/css/post.css

@@ -13,16 +13,15 @@ div#bx-timeline-post div.input_wrapper_textarea {
 }
 div#bx-timeline-post div#bx-form-element-link,
 div#bx-timeline-post div#bx-form-element-photo,
+div#bx-timeline-post div#bx-form-element-video,
+
 div#bx-timeline-post .bx-form-input-files-uploaders {
 	margin-top: 0px;
 }
-div.bx-tl-uploader-buttons {
+div#bx-timeline-post div#bx-form-element-attachments {
 	position: absolute;
 	right: 0px;
 }
-a.bx-tl-uploader-button {
-	text-decoration: none;
-}
 div.bx-tl-uploader-file {
 	position: relative;
 	float: left;

+ 10 - 0
modules/boonex/timeline/template/menu_buttons_hor.html

@@ -0,0 +1,10 @@
+<ul class="bx-menu-btns-hor bx-menu-object-__object__ bx-clearfix">
+    <bx_repeat:menu_items>
+        <li class="bx-def-margin-sec-left-auto __class_add__">
+            <a class="bx-btn" href="__link__" target="__target__" onclick="__onclick__" title="__title__">
+                <bx_if:image><i style="background-image:url(__icon_url__)"></i></bx_if:image>
+                <bx_if:icon><i class="sys-icon __icon__"></i></bx_if:icon>
+            </a>
+        </li>
+    </bx_repeat:menu_items>
+</ul>

+ 8 - 1
modules/boonex/timeline/template/type_post.html

@@ -26,4 +26,11 @@
 	   		<div class="__style_prefix__-item-image bx-def-margin-top-auto">__image__</div>
 	   	</bx_repeat:images>
 	</div>
-</bx_if:show_images>
+</bx_if:show_images>
+<bx_if:show_videos>
+	<div class="__style_prefix__-item-videos bx-def-margin-top bx-def-margin-leftright-neg">
+		<bx_repeat:videos>
+	   		<div class="__style_prefix__-item-video bx-def-margin-top-auto">__video__</div>
+	   	</bx_repeat:videos>
+	</div>
+</bx_if:show_videos>

+ 1 - 0
modules/boonex/timeline/template/uploader_button_simple.html

@@ -0,0 +1 @@
+<bx_include_auto:uploader_button_simple_js.html />