<?php
/**
* [PHPFOX_HEADER]
*/
defined('PHPFOX') or exit('NO DICE!');
/**
*
*
* @copyright [PHPFOX_COPYRIGHT]
* @author Raymond Benc
* @package Module_Admincp
* @version $Id: module.class.php 5840 2013-05-09 06:14:35Z Raymond_Benc $
*/
class Admincp_Service_Module_Module extends Phpfox_Service
{
/**
* Class constructor
*/
public function __construct()
{
$this->_sTable = Phpfox::getT('module');
}
/**
* @return array
*/
public function getAdminMenu()
{
$sCacheId = $this->cache()->set('module_menu_' . Phpfox::getUserId());
if (!($aRows = $this->cache()->get($sCacheId))) {
$aPrivacyCache = [];
$aRows = $this->database()->select('*')
->from(Phpfox::getT('admincp_privacy'))
->order('time_stamp DESC')
->execute('getSlaveRows');
foreach ($aRows as $aRow) {
foreach ((array)json_decode($aRow['user_group'], true) as $iGroup) {
$aPrivacyCache[ $iGroup ][ str_replace('admincp.', '', $aRow['url']) ] = ($aRow['wildcard'] ? true : false);
}
}
$aRows = $this->database()->select('m.module_id, m.is_menu, m.menu')
->from($this->_sTable, 'm')
->where('m.is_active = 1 AND m.is_menu = 1')
->order('m.module_id ASC')
->execute('getSlaveRows');
$oFilter = Phpfox::getLib('parse.input');
foreach ($aRows as $iKey => $aRow) {
if (!$aRow['is_menu']) {
unset($aRows[ $iKey ]);
}
if ($aRow['menu']) {
$aRows[ $iKey ]['menu'] = unserialize($aRow['menu']);
foreach ($aRows[ $iKey ]['menu'] as $iSubKey => $aSubMenu) {
if (isset($aPrivacyCache[ Phpfox::getUserBy('user_group_id') ][ implode('.', $aSubMenu['url']) ])) {
if ($aPrivacyCache[ Phpfox::getUserBy('user_group_id') ][ implode('.', $aSubMenu['url']) ]) {
unset($aRows[ $iKey ]);
break;
}
unset($aRows[ $iKey ]['menu'][ $iSubKey ]);
continue;
}
$aRows[ $iKey ]['menu'][ $iSubKey ]['url'] = implode('/', $aSubMenu['url']);
}
}
$aRows[ $iKey ]['url_name'] = $oFilter->cleanTitle($aRow['module_id']);
if (file_exists(PHPFOX_DIR_MODULE . $aRow['module_id'] . PHPFOX_DS . 'static' . PHPFOX_DS . 'module.png')) {
$aRows[ $iKey ]['module_image'] = Phpfox::getParam('core.path') . 'module/' . $aRow['module_id'] . PHPFOX_DS . 'static' . PHPFOX_DS . 'module.png';
}
}
$this->cache()->save($sCacheId, $aRows);
}
foreach ($aRows as $iKey => $aRow) {
if (isset($aRow['module_id']) && !Phpfox::isModule($aRow['module_id'])) {
unset($aRows[ $iKey ]);
}
}
return $aRows;
}
/**
* @return array
*/
public function getModules()
{
return Phpfox_Module::instance()->getModules();
}
/**
* @param bool $bUninstalled
*
* @return array
*/
public function get($bUninstalled = false)
{
$aProductCache = [];
$aProducts = $this->database()->select('product_id, title')
->from(Phpfox::getT('product'))
->execute('getSlaveRows');
foreach ($aProducts as $aProduct) {
$aProductCache[ $aProduct['product_id'] ] = $aProduct['title'];
}
$this->database()->select('m_sub.module_id, COUNT(s.setting_id) AS total_setting')
->from($this->_sTable, 'm_sub')
->leftJoin(Phpfox::getT('setting'), 's', 's.module_id = m_sub.module_id')
->group('m_sub.module_id')
->union();
$aRows = $this->database()->select('m.*, p.title AS product_title, m_sub.total_setting')
->unionFrom('m_sub')
->join($this->_sTable, 'm', 'm.module_id = m_sub.module_id')
->leftJoin(Phpfox::getT('product'), 'p', 'p.product_id = m.product_id')
->order('m.module_id ASC')
->execute('getSlaveRows');
$aModules = [];
$aCache = [];
foreach ($aRows as $aRow) {
$aCache[ $aRow['module_id'] ] = true;
$aModules[ ($aRow['is_core'] ? 'core' : '3rdparty') ][] = $aRow;
}
if ($bUninstalled === true) {
$aNotInstalled = [];
$hDir = opendir(PHPFOX_DIR_MODULE);
while ($sModule = readdir($hDir)) {
if ($sModule == '.' || $sModule == '..') {
continue;
}
if (!file_exists(PHPFOX_DIR_MODULE . $sModule . PHPFOX_DS . 'install' . PHPFOX_DS . 'phpfox.xml.php')) {
continue;
}
if (isset($aCache[ $sModule ])) {
continue;
}
$aModuleDetails = Phpfox::getLib('xml.parser')->parse(file_get_contents(PHPFOX_DIR_MODULE . $sModule . PHPFOX_DS . 'install' . PHPFOX_DS . 'phpfox.xml.php'));
if (isset($aModuleDetails['data'])) {
$aModuleDetails['data']['is_not_installed'] = true;
$aModuleDetails['data']['product_title'] = (isset($aProductCache[ $aModuleDetails['data']['product_id'] ]) ? $aProductCache[ $aModuleDetails['data']['product_id'] ] : $aModuleDetails['data']['product_id']);
$aNotInstalled[] = $aModuleDetails['data'];
}
}
closedir($hDir);
if (count($aNotInstalled)) {
foreach ($aNotInstalled as $aModule) {
$aModules['3rdparty'][] = $aModule;
}
}
}
return $aModules;
}
/**
* @param array $iId
*
* @return array
*/
public function getForEdit($iId)
{
return $this->database()->select('m.*')
->from($this->_sTable, 'm')
->where("m.module_id = '" . $iId . "'")
->execute('getSlaveRow');
}
/**
* @todo Cache
* Once removed from the ORDER it will still throw a fatal error because of the COUNT requires
* the text to be in the order. Yet another Catch 22 for Microsoft. In any case created a PHP fix for the
* time being, however need to do further testing on MSSQL as there must be a way!
*
* @return array
*/
public function getModulesForSettings()
{
$this->database()->select('COUNT(setting.module_id) AS total_settings, ')->group('m_sub.module_id');
$this->database()->select("m_sub.module_id")
->from($this->_sTable, "m_sub")
->leftJoin(Phpfox::getT('setting'), 'setting', [
'setting.module_id = m_sub.module_id AND setting.is_hidden = 0'
]
)
->where('m_sub.is_active = 1')
->union();
$aRows = $this->database()->select("m_sub.total_settings, m.module_id, language_phrase.text AS info")
->unionFrom('m_sub')
->join($this->_sTable, 'm', 'm.module_id = m_sub.module_id')
->leftJoin(Phpfox::getT('language_phrase'), 'language_phrase', [
"language_phrase.language_id = '" . Phpfox_Locale::instance()->getLangId() . "'",
'AND m.phrase_var_name = language_phrase.var_name'
]
)
->order('m.module_id ASC')
->execute('getSlaveRows');
return $aRows;
}
/**
* @param string $sProductId
* @param bool $bIsCore
*
* @return bool
*/
public function export($sProductId, $bIsCore = false)
{
$aRows = $this->database()->select('m.*, product.title AS product_name')
->from($this->_sTable, 'm')
->leftJoin(Phpfox::getT('product'), 'product', 'product.product_id = m.product_id')
->where("m.product_id = '" . $sProductId . "'" . ($bIsCore ? ' AND m.is_core = 1' : ''))
->execute('getSlaveRows');
if (!isset($aRows[0]['product_name'])) {
return Phpfox_Error::set(_p('product_does_not_have_any_settings'));
}
$oXmlBuilder = Phpfox::getLib('xml.builder');
$oXmlBuilder->addGroup('modules');
foreach ($aRows as $aRow) {
$oXmlBuilder->addTag('module', $aRow['menu'], [
'module_id' => $aRow['module_id'],
'is_core' => $aRow['is_core'],
'is_active' => $aRow['is_active'],
'is_menu' => $aRow['is_menu'],
'phrase_var_name' => $aRow['phrase_var_name']
]
);
}
$oXmlBuilder->closeGroup();
return $oXmlBuilder->output();
}
/**
* @param string $sProductId
* @param bool|true $bCore
* @param null $aModuleCache
* @param array $tempContents
*
* @return bool|array
*/
public function exportForModules($sProductId = 'phpfox', $bCore = true, $aModuleCache = null, $tempContents = [])
{
$includePaths = [];
$oDatabaseSupport = Phpfox::getLib('database.support');
$oXmlBuilder = Phpfox::getLib('xml.builder');
if (!defined('PHPFOX_XML_SKIP_STAMP')) {
define('PHPFOX_XML_SKIP_STAMP', true);
}
$aRows = $this->database()->select('*')
->from($this->_sTable)
->execute('getSlaveRows');
if (!count($aRows)) {
return false;
}
foreach ($aRows as $aRow) {
$sDir = PHPFOX_DIR_MODULE . $aRow['module_id'];
$oXmlBuilder->addGroup('module');
$oXmlBuilder->addGroup('data');
foreach ($aRow as $sKey => $sValue) {
$oXmlBuilder->addTag($sKey, $sValue);
}
if ($sProductId == 'phpfox') {
$aWritableFiles = Phpfox_Module::instance()->init($aRow['module_id'], 'aInstallWritable');
$oXmlBuilder->addTag('writable', ((count($aWritableFiles) && is_array($aWritableFiles)) ? serialize($aWritableFiles) : ''));
}
$oXmlBuilder->closeGroup();
$iCnt = 0;
$aModuleCallback = Phpfox::massCallback('exportModule', $sProductId, $aRow['module_id'], $bCore);
foreach ($aModuleCallback as $sModuleCallback => $mReturn) {
if ($sModuleCallback == 'language')
{
continue;
}
if ($mReturn === true) {
$iCnt++;
}
}
if ($bCore === true && is_dir($sDir)) {
$aTables = Phpfox_Module::instance()->init($aRow['module_id'], 'aTables');
if (count($aTables) > 0) {
$oXmlBuilder->addTag('tables', serialize($oDatabaseSupport->prepareSchema($aTables)));
}
$sInstallFile = $sDir . PHPFOX_DIR_MODULE_XML . PHPFOX_DS . 'version' . PHPFOX_DS . 'install' . PHPFOX_XML_SUFFIX;
if (file_exists($sInstallFile)) {
$aInstallData = Phpfox::getLib('xml.parser')->parse(file_get_contents($sInstallFile));
if (isset($aInstallData['install'])) {
$oXmlBuilder->addTag('install', $aInstallData['install']);
}
}
}
if ($bCore === false && $aModuleCache !== null && is_dir($sDir) && isset($aModuleCache[ $aRow['module_id'] ])) {
if (file_exists($sDir . '/export.json')) {
$json = json_decode(file_get_contents($sDir . '/export.json'), true);
foreach ($json['paths'] as $path) {
$includePaths[] = dirname(PHPFOX_DIR) . '/' . $path;
}
} else {
$includePaths[] = $sDir;
}
}
$oXmlBuilder->closeGroup();
if ($iCnt) {
if ($bCore === true) {
$locale = 'PF.Base' . PHPFOX_DS . 'module' . PHPFOX_DS . $aRow['module_id'] . PHPFOX_DIR_MODULE_XML . PHPFOX_DS . 'phpfox' . PHPFOX_XML_SUFFIX;
$oXmlOuput = $oXmlBuilder->output();
$tempContents[$locale] = $oXmlOuput;
// write out to file
if(!empty($aModuleCache) && !empty($aModuleCache[$aRow['module_id']])) {
$filename = realpath(dirname(PHPFOX_DIR)) . '/' . $locale;
if (!is_writable($filename)) {
exit("can not write to file " . $filename);
}
file_put_contents($filename, $oXmlOuput);
}
} else {
$locale = 'PF.Base'. PHPFOX_DS .'module' . PHPFOX_DS . $aRow['module_id'] . PHPFOX_DS . 'phpfox.xml';
$tempContents[ $locale ] = $oXmlBuilder->output();
}
} else {
$oXmlBuilder->output();
}
}
return [
'paths' => $includePaths,
'contents' => $tempContents,
];
}
/**
* If a call is made to an unknown method attempt to connect
* it to a specific plug-in with the same name thus allowing
* plug-in developers the ability to extend classes.
*
* @param string $sMethod is the name of the method
* @param array $aArguments is the array of arguments of being passed
*
* @return null
*/
public function __call($sMethod, $aArguments)
{
/**
* Check if such a plug-in exists and if it does call it.
*/
if ($sPlugin = Phpfox_Plugin::get('admincp.service_module_module___call')) {
eval($sPlugin);
return null;
}
/**
* No method or plug-in found we must throw a error.
*/
Phpfox_Error::trigger('Call to undefined method ' . __CLASS__ . '::' . $sMethod . '()', E_USER_ERROR);
}
}