Uploading and preparing the repository to the dev version.

Original unminified source code (dev folder - js, css, less) (fixes #6)
Grunt build system
Multiple identities correction (fixes #9)
Compose html editor (fixes #12)
New general settings - Loading Description
New warning about default admin password
Split general and login screen settings
This commit is contained in:
RainLoop Team 2013-11-16 02:21:12 +04:00
parent afad45137e
commit 4cc2207513
846 changed files with 99453 additions and 2123 deletions

View file

@ -0,0 +1,338 @@
<?php
namespace RainLoop\Plugins;
abstract class AbstractPlugin
{
/**
* @var \RainLoop\Plugins\Manager
*/
private $oPluginManager;
/**
* @var \RainLoop\Config\Plugin
*/
private $oPluginConfig;
/**
* @var bool
*/
private $bLangs;
/**
* @var string
*/
private $sName;
/**
* @var string
*/
private $sPath;
/**
* @var string
*/
private $sVersion;
/**
* @var array
*/
private $aConfigMap;
/**
* @var bool
*/
private $bPluginConfigLoaded;
public function __construct()
{
$this->sName = '';
$this->sPath = '';
$this->sVersion = '0.0';
$this->aConfigMap = null;
$this->oPluginManager = null;
$this->oPluginConfig = null;
$this->bPluginConfigLoaded = false;
$this->bLangs = false;
}
/**
* @return \RainLoop\Config\Plugin
*/
public function Config()
{
if (!$this->bPluginConfigLoaded && $this->oPluginConfig)
{
$this->bPluginConfigLoaded = true;
if ($this->oPluginConfig->IsInited())
{
if (!$this->oPluginConfig->Load())
{
$this->oPluginConfig->Save();
}
}
}
return $this->oPluginConfig;
}
/**
* @return \RainLoop\Plugins\Manager
*/
public function Manager()
{
return $this->oPluginManager;
}
/**
* @return string
*/
public function Path()
{
return $this->sPath;
}
/**
* @return string
*/
public function Name()
{
return $this->sName;
}
/**
* @return string
*/
public function Version()
{
return $this->sVersion;
}
/**
* @param bool | null $bLangs = null
* @return bool
*/
public function UseLangs($bLangs = null)
{
if (null !== $bLangs)
{
$this->bLangs = (bool) $bLangs;
}
return $this->bLangs;
}
/**
* @return array
*/
protected function configMapping()
{
return array();
}
/**
* @return string
*/
public function Hash()
{
return \md5($this->sVersion);
}
/**
* @return string
*/
public function Supported()
{
return '';
}
/**
* @final
* @return array
*/
final public function ConfigMap()
{
if (null === $this->aConfigMap)
{
$this->aConfigMap = $this->configMapping();
if (!is_array($this->aConfigMap))
{
$this->aConfigMap = array();
}
}
return $this->aConfigMap;
}
/**
* @param string $sPath
* @param string $sName
* @param string $sVersion = ''
*
* @return self
*/
public function SetValues($sPath, $sName, $sVersion = '')
{
$this->sName = $sName;
$this->sPath = $sPath;
if (0 < \strlen($sVersion))
{
$this->sVersion = $sVersion;
}
return $this;
}
/**
* @param \RainLoop\Plugins\Manager $oPluginManager
*
* @return self
*/
public function SetPluginManager(\RainLoop\Plugins\Manager $oPluginManager)
{
$this->oPluginManager = $oPluginManager;
return $this;
}
/**
* @param \RainLoop\Config\Plugin $oPluginConfig
*
* @return self
*/
public function SetPluginConfig(\RainLoop\Config\Plugin $oPluginConfig)
{
$this->oPluginConfig = $oPluginConfig;
return $this;
}
/**
* @return void
*/
public function PreInit()
{
}
/**
* @return void
*/
public function Init()
{
}
/**
* @param bool $bAdmin
* @param bool $bAuth
* @param array $aConfig
*
* @return void
*/
public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aConfig)
{
}
/**
* @param string $sHookName
* @param string $sFunctionName
*
* @return self
*/
protected function addHook($sHookName, $sFunctionName)
{
if ($this->oPluginManager)
{
$this->oPluginManager->AddHook($sHookName, array(&$this, $sFunctionName));
}
return $this;
}
/**
* @param string $sFile
* @param bool $bAdminScope = false
*
* @return self
*/
protected function addJs($sFile, $bAdminScope = false)
{
if ($this->oPluginManager)
{
$this->oPluginManager->AddJs($this->sPath.'/'.$sFile, $bAdminScope);
}
return $this;
}
/**
* @param string $sFile
* @param bool $bAdminScope = false
*
* @return self
*/
protected function addTemplate($sFile, $bAdminScope = false)
{
if ($this->oPluginManager)
{
$this->oPluginManager->AddTemplate($this->sPath.'/'.$sFile, $bAdminScope);
}
return $this;
}
/**
* @param string $sActionName
* @param string $sFunctionName
*
* @return self
*/
protected function addPartHook($sActionName, $sFunctionName)
{
if ($this->oPluginManager)
{
$this->oPluginManager->AddAdditionalPartAction($sActionName, array(&$this, $sFunctionName));
}
return $this;
}
/**
* @param string $sActionName
* @param string $sFunctionName
*
* @return self
*/
protected function addAjaxHook($sActionName, $sFunctionName)
{
if ($this->oPluginManager)
{
$this->oPluginManager->AddAdditionalAjaxAction($sActionName, array(&$this, $sFunctionName));
}
return $this;
}
/**
* @param string $sName
* @param string $sPlace
* @param string $sHtml
* @param bool $bPrepend = false
*
* @return self
*/
protected function addTemplateHook($sName, $sPlace, $sLocalTemplateName, $bPrepend = false)
{
if ($this->oPluginManager)
{
$this->oPluginManager->AddProcessTemplateAction($sName, $sPlace,
'<!-- ko template: \''.$sLocalTemplateName.'\' --><!-- /ko -->', $bPrepend);
}
return $this;
}
}

View file

@ -0,0 +1,669 @@
<?php
namespace RainLoop\Plugins;
class Manager
{
/**
* @var \RainLoop\Actions
*/
private $oActions;
/**
* @var array
*/
private $aHooks;
/**
* @var array
*/
private $aJs;
/**
* @var array
*/
private $aAdminJs;
/**
* @var array
*/
private $aTemplates;
/**
* @var array
*/
private $aAdminTemplates;
/**
* @var array
*/
private $aProcessTemplate;
/**
* @var array
*/
private $aAdditionalParts;
/**
* @var array
*/
private $aAdditionalAjax;
/**
* @var array
*/
private $aPlugins;
/**
* @var bool
*/
private $bIsEnabled;
/**
* @var \MailSo\Log\Logger
*/
private $oLogger;
/**
* @param \RainLoop\Actions $oActions
*/
public function __construct(\RainLoop\Actions $oActions)
{
$this->oLogger = null;
$this->oActions = $oActions;
$this->aPlugins = array();
$this->aHooks = array();
$this->aJs = array();
$this->aAdminJs = array();
$this->aTemplates = array();
$this->aAdminTemplates = array();
$this->aAjaxFilters = array();
$this->aAdditionalAjax = array();
$this->aProcessTemplate = array();
$this->bIsEnabled = (bool) $this->oActions->Config()->Get('plugins', 'enable', false);
if ($this->bIsEnabled)
{
$sList = \strtolower($this->oActions->Config()->Get('plugins', 'enabled_list', ''));
if (0 < \strlen($sList))
{
$aList = \explode(',', $sList);
$aList = \array_map('trim', $aList);
foreach ($aList as $sName)
{
if (0 < \strlen($sName))
{
$oPlugin = $this->CreatePluginByName($sName);
if ($oPlugin)
{
$oPlugin->PreInit();
$oPlugin->Init();
$this->aPlugins[] = $oPlugin;
}
}
}
}
}
}
/**
* @param string $sName
*
* @return \RainLoop\Plugins\AbstractPlugin | null
*/
public function CreatePluginByName($sName)
{
$oPlugin = null;
if (\preg_match('/^[a-z0-9\-]+$/', $sName) &&
\file_exists(APP_PLUGINS_PATH.$sName.'/index.php'))
{
$sClassName = $this->convertPluginFolderNameToClassName($sName);
if (!\class_exists($sClassName))
{
include APP_PLUGINS_PATH.$sName.'/index.php';
}
if (\class_exists($sClassName))
{
$oPlugin = new $sClassName();
if ($oPlugin instanceof \RainLoop\Plugins\AbstractPlugin)
{
$oPlugin
->SetValues(APP_PLUGINS_PATH.$sName, $sName,
\file_exists(APP_PLUGINS_PATH.$sName.'/VERSION') ?
\file_get_contents(APP_PLUGINS_PATH.$sName.'/VERSION') : '')
->SetPluginManager($this)
->SetPluginConfig(new \RainLoop\Config\Plugin($sName, $oPlugin->ConfigMap()))
;
}
else
{
$oPlugin = null;
}
}
}
return $oPlugin;
}
/**
* @return array
*/
public function InstalledPlugins()
{
$aList = array();
$aGlob = @\glob(APP_PLUGINS_PATH.'*', GLOB_ONLYDIR|GLOB_NOSORT);
if (\is_array($aGlob))
{
foreach ($aGlob as $sPathName)
{
$sName = \basename($sPathName);
if (\preg_match('/^[a-z0-9\-]+$/', $sName) &&
\file_exists($sPathName.'/index.php'))
{
$sVersion = @\file_get_contents($sPathName.'/VERSION');
$aList[] = array(
$sName, $sVersion
);
}
}
}
else
{
$this->Actions()->Logger()->Write('Cannot get installed plugins from '.APP_PLUGINS_PATH,
\MailSo\Log\Enumerations\Type::ERROR);
}
return $aList;
}
/**
* @param string $sFolderName
*
* @return string
*/
private function convertPluginFolderNameToClassName($sFolderName)
{
$aParts = array_map('ucfirst', array_map('strtolower',
explode(' ', preg_replace('/[^a-z0-9]+/', ' ', $sFolderName))));
return implode($aParts).'Plugin';
}
/**
* @return \RainLoop\Actions
*/
public function Actions()
{
return $this->oActions;
}
/**
* @return \RainLoop\Actions
*/
public function Hash()
{
$sResult = \md5(APP_VERSION);
foreach ($this->aPlugins as $oPlugin)
{
$sResult = \md5($sResult.$oPlugin->Path().$oPlugin->Hash());
}
return $sResult;
}
/**
* @param bool $bAdminScope = false
*
* @return string
*/
public function CompileJs($bAdminScope = false)
{
$aResult = array();
if ($this->bIsEnabled)
{
$aJs = $bAdminScope ? $this->aAdminJs : $this->aJs;
foreach ($aJs as $sFile)
{
if (file_exists($sFile))
{
$aResult[] = file_get_contents($sFile);
}
}
}
return implode("\n", $aResult);
}
/**
* @todo
* @param bool $bAdminScope = false
*
* @return string
*/
public function CompileCss($bAdminScope = false)
{
return '';
}
/**
* @param bool $bAdminScope = false
* @return string
*/
public function CompileTemplate($bAdminScope = false)
{
$sResult = '';
if ($this->bIsEnabled)
{
$aTemplates = $bAdminScope ? $this->aAdminTemplates : $this->aTemplates;
foreach ($aTemplates as $sFile)
{
if (file_exists($sFile))
{
$sTemplateName = substr(basename($sFile), 0, -5);
$sResult .= '<script id="'.preg_replace('/[^a-zA-Z0-9]/', '', $sTemplateName).'" type="text/html">'.
$this->Actions()->ProcessTemplate($sTemplateName, file_get_contents($sFile)).'</script>';
}
}
}
return $sResult;
}
/**
* @param bool $bAdmin
* @param array $aAppData
*
* @return \RainLoop\Plugins\Manager
*/
public function InitAppData($bAdmin, &$aAppData)
{
if ($this->bIsEnabled && isset($aAppData['Plugins']) && is_array($aAppData['Plugins']))
{
$bAuth = isset($aAppData['Auth']) && !!$aAppData['Auth'];
foreach ($this->aPlugins as $oPlugin)
{
if ($oPlugin)
{
$aConfig = array();
$aMap = $oPlugin->ConfigMap();
if (\is_array($aMap))
{
foreach ($aMap as /* @var $oPluginProperty \RainLoop\Plugins\Property */$oPluginProperty)
{
if ($oPluginProperty && $oPluginProperty->AllowedInJs())
{
$aConfig[$oPluginProperty->Name()] =
$oPlugin->Config()->Get('plugin',
$oPluginProperty->Name(),
$oPluginProperty->DefaultValue());
}
}
}
$oPlugin->FilterAppDataPluginSection($bAdmin, $bAuth, $aConfig);
if (0 < \count($aConfig))
{
$aAppData['Plugins'][$oPlugin->Name()] = $aConfig;
}
}
}
$this->RunHook('filter.app-data', array($bAdmin, &$aAppData));
}
return $this;
}
/**
* @param string $sHookName
* @param mixed $mCallbak
*
* @return \RainLoop\Plugins\Manager
*/
public function AddHook($sHookName, $mCallbak)
{
if ($this->bIsEnabled && is_callable($mCallbak))
{
if (!isset($this->aHooks[$sHookName]))
{
$this->aHooks[$sHookName] = array();
}
$this->aHooks[$sHookName][] = $mCallbak;
}
return $this;
}
/**
* @param string $sHookName
* @param bool $bAdminScope = false
*
* @return \RainLoop\Plugins\Manager
*/
public function AddJs($sFile, $bAdminScope = false)
{
if ($this->bIsEnabled)
{
if ($bAdminScope)
{
$this->aAdminJs[$sFile] = $sFile;
}
else
{
$this->aJs[$sFile] = $sFile;
}
}
return $this;
}
/**
* @param string $sHookName
* @param bool $bAdminScope = false
*
* @return \RainLoop\Plugins\Manager
*/
public function AddTemplate($sFile, $bAdminScope = false)
{
if ($this->bIsEnabled)
{
if ($bAdminScope)
{
$this->aAdminTemplates[$sFile] = $sFile;
}
else
{
$this->aTemplates[$sFile] = $sFile;
}
}
return $this;
}
/**
* @param string $sHookName
* @param array $aArg = array()
* @param bool $bLogHook = true
*
* @return \RainLoop\Plugins\Manager
*/
public function RunHook($sHookName, $aArg = array(), $bLogHook = true)
{
if ($this->bIsEnabled)
{
if (isset($this->aHooks[$sHookName]))
{
if ($bLogHook)
{
$this->WriteLog('Hook: '.$sHookName, \MailSo\Log\Enumerations\Type::NOTE);
}
foreach ($this->aHooks[$sHookName] as $mCallbak)
{
call_user_func_array($mCallbak, $aArg);
}
}
}
return $this;
}
/**
* @param string $sActionName
* @param mixed $mCallbak
*
* @return \RainLoop\Plugins\Manager
*/
public function AddAdditionalPartAction($sActionName, $mCallbak)
{
if ($this->bIsEnabled && is_callable($mCallbak))
{
$sActionName = strtolower($sActionName);
if (!isset($this->aAdditionalParts[$sActionName]))
{
$this->aAdditionalParts[$sActionName] = array();
}
$this->aAdditionalParts[$sActionName][] = $mCallbak;
}
return $this;
}
/**
* @param string $sActionName
* @param array $aParts = array()
*
* @return \RainLoop\Plugins\Manager
*/
public function RunAdditionalPart($sActionName, $aParts = array())
{
$bResult = false;
if ($this->bIsEnabled)
{
$sActionName = strtolower($sActionName);
if (isset($this->aAdditionalParts[$sActionName]))
{
foreach ($this->aAdditionalParts[$sActionName] as $mCallbak)
{
$bCallResult = call_user_func_array($mCallbak, $aParts);
if ($bCallResult && !$bResult)
{
$bResult = true;
}
}
}
}
return $bResult;
}
/**
* @param string $sName
* @param string $sPlace
* @param string $sHtml
* @param bool $bPrepend = false
*
* @return \RainLoop\Plugins\Manager
*/
public function AddProcessTemplateAction($sName, $sPlace, $sHtml, $bPrepend = false)
{
if ($this->bIsEnabled)
{
if (!isset($this->aProcessTemplate[$sName]))
{
$this->aProcessTemplate[$sName] = array();
}
if (!isset($this->aProcessTemplate[$sName][$sPlace]))
{
$this->aProcessTemplate[$sName][$sPlace] = array();
}
if ($bPrepend)
{
array_unshift($this->aProcessTemplate[$sName][$sPlace], $sHtml);
}
else
{
array_push($this->aProcessTemplate[$sName][$sPlace], $sHtml);
}
}
return $this;
}
/**
* @param string $sActionName
* @param mixed $mCallbak
*
* @return \RainLoop\Plugins\Manager
*/
public function AddAdditionalAjaxAction($sActionName, $mCallbak)
{
if ($this->bIsEnabled && is_callable($mCallbak) && 0 < strlen($sActionName))
{
$sActionName = 'Do'.$sActionName;
if (!isset($this->aAdditionalAjax[$sActionName]))
{
$this->aAdditionalAjax[$sActionName] = $mCallbak;
}
}
return $this;
}
/**
* @param string $sActionName
*
* @return bool
*/
public function HasAdditionalAjax($sActionName)
{
return $this->bIsEnabled && isset($this->aAdditionalAjax[$sActionName]);
}
/**
* @param string $sActionName
*
* @return mixed
*/
public function RunAdditionalAjax($sActionName)
{
if ($this->bIsEnabled)
{
if (isset($this->aAdditionalAjax[$sActionName]))
{
return call_user_func($this->aAdditionalAjax[$sActionName]);
}
}
return false;
}
/**
* @param string $sLang
* @param array $sActionName
*
* @return \RainLoop\Plugins\Manager
*/
public function ReadLang($sLang, &$aLang)
{
if ($this->bIsEnabled)
{
foreach ($this->aPlugins as $oPlugin)
{
if ($oPlugin->UseLangs())
{
$sPath = $oPlugin->Path();
\RainLoop\Utils::ReadAndAddLang($sPath.'/langs/en.ini', $aLang);
if ('en' !== $sLang)
{
\RainLoop\Utils::ReadAndAddLang($sPath.'/langs/'.$sLang.'.ini', $aLang);
}
}
}
}
return $this;
}
/**
* @param string $sName
* @param string $sHtml
*
* @return string
*/
public function ProcessTemplate($sName, $sHtml)
{
if (isset($this->aProcessTemplate[$sName]))
{
foreach ($this->aProcessTemplate[$sName] as $sPlace => $aAddHtml)
{
if (is_array($aAddHtml) && 0 < count($aAddHtml))
{
foreach ($aAddHtml as $sAddHtml)
{
$sHtml = str_replace('{{INCLUDE/'.$sPlace.'/PLACE}}', $sAddHtml.'{{INCLUDE/'.$sPlace.'/PLACE}}', $sHtml);
}
}
}
}
return $sHtml;
}
/**
* @return bool
*/
public function bIsEnabled()
{
return $this->bIsEnabled;
}
/**
* @return int
*/
public function Count()
{
return $this->bIsEnabled ? \count($this->aPlugins) : 0;
}
/**
* @param \MailSo\Log\Logger $oLogger
*
* @return \RainLoop\Plugins\Manager
*
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function SetLogger($oLogger)
{
if (!($oLogger instanceof \MailSo\Log\Logger))
{
throw new \MailSo\Base\Exceptions\InvalidArgumentException();
}
$this->oLogger = $oLogger;
return $this;
}
/**
* @param string $sDesc
* @param int $iDescType = \MailSo\Log\Enumerations\Type::INFO
*
* @return void
*/
public function WriteLog($sDesc, $iDescType = \MailSo\Log\Enumerations\Type::INFO)
{
if ($this->oLogger)
{
$this->oLogger->Write($sDesc, $iDescType, 'PLUGIN');
}
}
/**
* @param string $sDesc
* @param int $iDescType = \MailSo\Log\Enumerations\Type::INFO
*
* @return void
*/
public function WriteException($sDesc, $iDescType = \MailSo\Log\Enumerations\Type::INFO)
{
if ($this->oLogger)
{
$this->oLogger->WriteException($sDesc, $iDescType, 'PLUGIN');
}
}
}

View file

@ -0,0 +1,178 @@
<?php
namespace RainLoop\Plugins;
class Property
{
/**
* @var string
*/
private $sName;
/**
* @var string
*/
private $sLabel;
/**
* @var string
*/
private $sDesc;
/**
* @var int
*/
private $iType;
/**
* @var bool
*/
private $bAllowedInJs;
/**
* @var mixed
*/
private $mDefaultValue;
private function __construct($sName)
{
$this->sName = $sName;
$this->iType = \RainLoop\Enumerations\PluginPropertyType::STRING;
$this->mDefaultValue = '';
$this->sLabel = '';
$this->sDesc = '';
$this->bAllowedInJs = false;
}
/**
* @param string $sName
*
* @return \RainLoop\Plugins\Property
*/
public static function NewInstance($sName)
{
return new self($sName);
}
/**
* @param int $iType
*
* @return \RainLoop\Plugins\Property
*/
public function SetType($iType)
{
$this->iType = (int) $iType;
return $this;
}
/**
* @param mixed $mDefaultValue
*
* @return \RainLoop\Plugins\Property
*/
public function SetDefaultValue($mDefaultValue)
{
$this->mDefaultValue = $mDefaultValue;
return $this;
}
/**
* @param string $sLabel
*
* @return \RainLoop\Plugins\Property
*/
public function SetLabel($sLabel)
{
$this->sLabel = $sLabel;
return $this;
}
/**
* @param string $sDesc
*
* @return \RainLoop\Plugins\Property
*/
public function SetDescription($sDesc)
{
$this->sDesc = $sDesc;
return $this;
}
/**
* @param bool $bValue = true
* @return \RainLoop\Plugins\Property
*/
public function SetAllowedInJs($bValue = true)
{
$this->bAllowedInJs = !!$bValue;
return $this;
}
/**
* @return string
*/
public function Name()
{
return $this->sName;
}
/**
* @return bool
*/
public function AllowedInJs()
{
return $this->bAllowedInJs;
}
/**
* @return string
*/
public function Description()
{
return $this->sDesc;
}
/**
* @return string
*/
public function Label()
{
return $this->sLabel;
}
/**
* @return int
*/
public function Type()
{
return $this->iType;
}
/**
* @return mixed
*/
public function DefaultValue()
{
return $this->mDefaultValue;
}
/**
* @return array
*/
public function ToArray()
{
return array(
'',
$this->sName,
$this->iType,
$this->sLabel,
$this->mDefaultValue,
$this->sDesc
);
}
}