<?php
/**
* SocialEngine
*
* @category Application_Core
* @package Install
* @copyright Copyright 2006-2020 Webligo Developments
* @license http://www.socialengine.com/license/
* @version $Id: ManageController.php 9747 2012-07-26 02:08:08Z john $
* @author John
*/
/**
* @category Application_Core
* @package Install
* @copyright Copyright 2006-2020 Webligo Developments
* @license http://www.socialengine.com/license/
*/
class ManageController extends Zend_Controller_Action
{
/**
* @var Engine_Package_Manager
*/
protected $_packageManager;
/**
* @var Zend_Session_Namespace
*/
protected $_session;
/**
* @var Zend_Cache_Core
*/
protected $_cache;
protected $_settings;
protected $_vfsSettings;
public $contexts = array(
'upload' => array(
'json',
),
'extract' => array(
'json',
),
'select-delete' => array(
'json',
),
);
public function init()
{
// Check if already logged in
if (!Zend_Registry::get('Zend_Auth')->getIdentity()) {
return $this->_helper->redirector->gotoRoute(array(), 'default', true);
}
// Get manager
$this->_packageManager = Zend_Registry::get('Engine_Package_Manager');
// Check if related folders are writeable
$this->_packageManager->checkTemporaryPaths();
if (!is_writeable(APPLICATION_PATH . '/application/packages')) {
throw new Engine_Exception('application/packages folder is not writeable; Please CHMOD this directory to 777 and refresh this page.');
}
// Get cache
$this->_cache = Zend_Registry::get('Cache');
$this->_packageManager->setCache($this->_cache);
// Create session namespace
$this->_session = new Zend_Session_Namespace('InstallManageController');
// Set db and vfs if available
if (Zend_Registry::isRegistered('Zend_Db') && Zend_Registry::get('Zend_Db') instanceof Zend_Db_Adapter_Abstract) {
$this->_packageManager->setDb(Zend_Registry::get('Zend_Db'));
}
if (isset($this->_session->vfsInstance) && $this->_session->vfsInstance instanceof Engine_Vfs_Adapter_Abstract) {
$this->_packageManager->setVfs($this->_session->vfsInstance);
}
// Get settings
$config = array();
$settingsFile = APPLICATION_PATH . '/install/config/general.php';
if (file_exists($settingsFile)) {
$config = include $settingsFile;
}
$this->view->settings = $this->_settings = array_merge(array(
'force' => '0',
'verbose' => '0',
'automated' => '0',
), $config);
// Get vfs config
$vfsConfig = array();
$vfsFile = APPLICATION_PATH . '/install/config/vfs.php';
if (file_exists($vfsFile)) {
$vfsConfig = include $vfsFile;
}
$this->_vfsSettings = $vfsConfig;
// Add manage socialengine title
$this->view->headTitle()->prepend('Manage SocialEngine');
// Set time limit
@set_time_limit(600);
}
public function indexAction()
{
/**
* @var Zend_Db_Adapter_Abstract $db
*/
$db = Zend_Registry::get('Zend_Db');
$generalSiteTitle = $db->select()->from('engine4_core_settings')
->where('name = ? ', 'core.general.site.url');
$generalSiteTitle = $db->fetchRow($generalSiteTitle);
if(!empty($generalSiteTitle['value'])) {
$this->view->siteURL = $generalSiteTitle['value'];
} else {
$this->view->siteURL = _ENGINE_SITE_URL;
}
// Check for updates
try {
$repo = $this->_packageManager->getRepository('socialengine.com');
if ($repo) {
$remoteVersions = $repo->queryList();
}
} catch (Exception $e) {
// Silence
$remoteVersions = array();
}
//$remoteVersions['core-base']['version'] = '4.0.0';
$this->view->remoteVersions = $remoteVersions;
/*
$parts = explode('?', $_SERVER['REQUEST_URI']);
$currentPage = (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://';
$currentPage .= $_SERVER['HTTP_HOST'];
$currentPage .= $parts[0];
$settings = array();
$rows = $db->select()->from('engine4_core_settings')
->where('name = ? ', 'core.client.token')
->orWhere('name = ? ', 'core.client.guid')
->query()->fetchAll();
foreach ($rows as $row) {
$settings[$row['name']] = $row['value'];
}
$warehouse = Engine_Settings::get('warehouse');
$websiteUrl = $warehouse['website_url'];
$websiteUrl .= '/login?return=' . urlencode($currentPage);
if ($this->getParam('product')) {
if (empty($settings['core.client.guid'])) {
exit('<a href="' . $websiteUrl . '">Login</a>');
}
$account = new Engine_Warehouse('/accounts/' . $settings['core.client.guid']);
$account->setToken($settings['core.client.token']);
print_r($account->get(array('include' => 'products'))); exit;
}
if ($this->getParam('token')) {
$api = new Engine_Warehouse('/php-site/auth');
$response = $api->get(array(
'token' => $this->getParam('token')
));
if (empty($response['token'])) {
exit('auth expired');
}
$db->delete('engine4_core_settings', 'name = \'core.client.token\'');
$db->delete('engine4_core_settings', 'name = \'core.client.guid\'');
$db->insert('engine4_core_settings', array(
'name' => 'core.client.token',
'value' => $response['token']
));
$db->insert('engine4_core_settings', array(
'name' => 'core.client.guid',
'value' => $response['guid']
));
header('Location: ' . $currentPage);
exit;
}
$this->view->websiteUrl = $websiteUrl;
$this->view->licenseError = false;
$this->view->licenseKeyUrl = $this->view->htmlLink('/admin/index/license-key/', 'here');
*/
// Try to get a list of installed modules and themes from the database
$dbState = array();
if ($db instanceof Zend_Db_Adapter_Abstract) {
/*
try {
$row = $db->select()->from('engine4_core_settings')
->where('name = ?', 'core.license.key')
->query()->fetch();
if (empty($row['value'])) {
throw new Exception('Missing license key.');
}
$warehouse = new Engine_Warehouse('/php-site/license');
$response = $warehouse->get(array(
'key' => $row['value']
));
if ($response === false) {
throw new \Exception('License key is not valid.');
}
} catch (Exception $e) {
$this->view->licenseError = $e->getMessage();
}
*/
try {
$table = new Zend_Db_Table(array(
'adapter' => $db,
'name' => 'engine4_core_modules',
));
foreach ($table->fetchAll() as $row) {
$dbState['module'][$row->name] = $row->toArray();
}
} catch (Exception $e) {
}
try {
$table = new Zend_Db_Table(array(
'adapter' => $db,
'name' => 'engine4_core_themes',
));
foreach ($table->fetchAll() as $row) {
$dbState['theme'][$row->name] = $row->toArray();
}
} catch (Exception $e) {
}
}
$this->view->dbState = $dbState;
// List installed packages
$upgradeablePackages = array();
$pendingPackages = array();
$installedPackages = array();
foreach ($this->_packageManager->listInstalledPackages(array('caching' => false)) as $installedPackage) {
// Get database state
$databaseInfo = array();
if (isset($dbState[$installedPackage->getType()][$installedPackage->getName()])) {
$databaseInfo = $dbState[$installedPackage->getType()][$installedPackage->getName()];
}
// Get remote version info
$remoteInfo = array();
if (isset($remoteVersions[$installedPackage->getGuid()])) {
$remoteInfo = $remoteVersions[$installedPackage->getGuid()];
}
//
if ($installedPackage->getVersion() == '4.0.0beta3' && !empty($databaseInfo['version']) && $databaseInfo['version'] == '4.0.0') {
$this->_forward('beta-update');
return;
}
// Init
$upgradeable = false;
$pending = false;
$navigation = array();
// Navigation
// Disable
if (isset($databaseInfo['enabled']) && $databaseInfo['enabled'] && $installedPackage->hasAction('disable')) {
$navigation[] = array(
'label' => 'disable',
'href' => $this->view->url(array('action' => 'disable')) . '?package=' . $installedPackage->getKey(),
'class' => "package_disable",
);
}
// Enable
if (isset($databaseInfo['enabled']) && !$databaseInfo['enabled'] && $installedPackage->hasAction('enable')) {
$navigation[] = array(
'label' => 'enable',
'href' => $this->view->url(array('action' => 'enable')) . '?package=' . $installedPackage->getKey(),
'class' => "package_enable",
);
}
// Install
if ($installedPackage->getType() == 'module' && empty($databaseInfo['version'])) {
$pending = true;
$navigation[] = array(
'label' => 'install',
'href' => $this->view->url(array('action' => 'install')) . '?package=' . $installedPackage->getKey(),
'class' => "package_install",
);
}
// Update/downgrade/refresh
if ($installedPackage->getType() == 'module' && !empty($databaseInfo['version'])) {
switch (version_compare($databaseInfo['version'], $installedPackage->getVersion())) {
case 1:
break;
case 0:
break;
case -1:
$pending = true;
$navigation[] = array(
'label' => 'upgrade',
//'href' => $this->view->url(array('action' => 'prepare')) . '?packages[]=' . $installedPackage->getKey(),
'href' => $this->view->url(array('action' => 'install')) . '?package=' . $installedPackage->getKey(),
'class' => "package_upgrade",
);
break;
}
}
// Remove
if ($installedPackage->hasAction('remove')) {
$navigation[] = array(
'label' => 'delete',
'href' => $this->view->url(array('action' => 'prepare')) . '?packages[]=' . $installedPackage->getKey() . '&actions[]=remove',
'class' => "package_delete",
);
}
// Add get upgrade
if (!empty($remoteInfo) && version_compare($remoteInfo['version'], $installedPackage->getVersion(), '>')) {
$upgradeable = true;
$navigation[] = array(
'label' => 'get update (' . $remoteInfo['version'] . ')',
'href' => 'http://www.socialengine.com/client',
);
}
$installedPackageInfo = array(
'package' => $installedPackage,
'database' => $databaseInfo,
'remote' => $remoteInfo,
'navigation' => $navigation,
'upgradeable' => $upgradeable,
'pending' => $pending,
);
if ($upgradeable) {
$upgradeablePackages[$installedPackage->getMeta()->getTitle()] = $installedPackageInfo;
} elseif ($pending) {
$pendingPackages[] = $installedPackageInfo;
} else {
$installedPackages[$installedPackage->getMeta()->getTitle()] = $installedPackageInfo;
}
}
$this->view->installedPackages = (array_merge($upgradeablePackages, $pendingPackages, $installedPackages));
ksort($this->view->installedPackages);
}
public function selectAction()
{
$this->view->installNavigation = $this->getInstallNavigation('select');
// Get extracted packages
$this->view->extractedPackages = $extractedPackages = $this->_packageManager->listExtractedPackages();
// Get available packages
$toExtractPackages = array();
$archiveDir = $this->_packageManager->getTemporaryPath(Engine_Package_Manager::PATH_ARCHIVES);
$extractDir = $this->_packageManager->getTemporaryPath(Engine_Package_Manager::PATH_PACKAGES);
foreach (scandir($archiveDir) as $file) {
if (strtolower(substr($file, -4, 4)) != '.tar') {
continue;
}
$partFile = substr($file, 0, -4);
if (!is_dir($extractDir . DIRECTORY_SEPARATOR . $partFile)) {
$toExtractPackages[] = $file;
}
}
$this->view->toExtractPackages = $toExtractPackages;
}
public function selectDeleteAction()
{
$this->_helper->contextSwitch->initContext();
$package = $this->_getParam('package');
// Setup
$archiveDir = $this->_packageManager->getTemporaryPath(Engine_Package_Manager::PATH_ARCHIVES);
$extractDir = $this->_packageManager->getTemporaryPath(Engine_Package_Manager::PATH_PACKAGES);
if (!is_string($package)) {
$this->view->error = 'Not a string';
return;
}
if (strpos($package, '/') !== false || strpos($package, '\\') !== false) {
$this->view->error = 'No directory traversal!';
return;
}
$packageArchive = $archiveDir . DIRECTORY_SEPARATOR . $package . '.tar';
$packageDirectory = $extractDir . DIRECTORY_SEPARATOR . $package;
if (file_exists($packageArchive) && is_file($packageArchive)) {
if (!@unlink($packageArchive)) {
$this->view->error = 'Could not remove archive file';
return;
}
}
if (file_exists($packageDirectory) && is_dir($packageDirectory)) {
try {
Engine_Package_Utilities::fsRmdirRecursive($packageDirectory, true);
} catch (Exception $e) {
$this->view->error = 'Could not remove extracted archive directory';
return;
}
}
$this->view->status = true;
}
public function extractAction()
{
$this->_helper->contextSwitch->initContext();
$package = $this->_getParam('package');
// Setup
try {
$archiveDir = $this->_packageManager->getTemporaryPath(Engine_Package_Manager::PATH_ARCHIVES);
$extractDir = $this->_packageManager->getTemporaryPath(Engine_Package_Manager::PATH_PACKAGES);
} catch (Exception $e) {
$this->view->error = $e->getMessage();
return;
}
// Check if archive is a tar file
$targetFile = $archiveDir . DIRECTORY_SEPARATOR . $package;
if (strtolower(substr($targetFile, -4, 4)) != '.tar') {
$this->view->error = 'Package is not a TAR archive.';
return;
}
// Check if archive exists
if (!file_exists($targetFile)) {
$this->view->error = 'Package does not exist.';
return;
}
// Try to deflate archive?
$extractFiles = array($targetFile);
$packagesInfo = array();
@set_time_limit(300);
$toRemove = array();
try {
while (count($extractFiles) > 0) {
$current = array_shift($extractFiles);
$hadPackage = false;
$hadArchive = false;
// Try to extract
$outputPath = Engine_Package_Archive::inflate($current, $extractDir);
// Check for tar files or package files
foreach (scandir($outputPath) as $child) {
// Package file
if (strtolower($child) == 'package.json') {
$packageFile = new Engine_Package_Manifest($outputPath . DIRECTORY_SEPARATOR . $child);
$packagesInfo[] = array(
'key' => $packageFile->getKey(),
'data' => $packageFile->toArray(),
'html' => $this->view->packageSelect($packageFile),
);
$hadPackage = true;
} elseif (strtolower(substr($child, -4)) === '.tar') {
$extractFiles[] = $outputPath . DIRECTORY_SEPARATOR . $child;
$hadArchive = true;
}
}
// Add to remove after extraction
$toRemove[] = $current;
if (!$hadPackage) {
$toRemove[] = $outputPath;
}
}
} catch (Exception $e) {
$this->view->error = $e->getMessage();
return;
}
if (empty($packagesInfo)) {
$this->view->error = 'No packages found in archive';
return;
}
// Remove to remove
foreach ($toRemove as $removeFile) {
if (is_dir($removeFile)) {
try {
Engine_Package_Utilities::fsRmdirRecursive($removeFile, true);
} catch (Exception $e) {
}
} elseif (is_file($removeFile)) {
@unlink($removeFile);
}
}
$this->view->status = 1;
$this->view->packagesInfo = $packagesInfo;
}
public function uploadAction()
{
$this->view->installNavigation = $this->getInstallNavigation('select');
$this->_helper->contextSwitch->initContext();
// Check method
if (!$this->getRequest()->isPost()) {
return;
}
// Prepare
$info = $_FILES['Filedata'];
try {
$archiveDir = $this->_packageManager->getTemporaryPath(Engine_Package_Manager::PATH_ARCHIVES);
$extractDir = $this->_packageManager->getTemporaryPath(Engine_Package_Manager::PATH_PACKAGES);
} catch (Exception $e) {
$this->view->error = $e->getMessage();
return;
}
$targetFile = $archiveDir . '/' . $info['name'];
// Check extension
if (strtolower(substr($info['name'], -4, 4)) != '.tar') {
$this->view->error = 'The file uploaded was not a TAR archive.';
return;
}
// Check if already exists
if (file_exists($targetFile) && !@unlink($targetFile)) {
$this->view->error = 'This file has already been uploaded, and the previous file could not be removed. Please try removing it manually in temporary/package/archives';
return;
}
// Check if already extracted
$outputPath = $extractDir . DIRECTORY_SEPARATOR . substr($info['name'], 0, -4);
if (file_exists($outputPath) && is_dir($outputPath)) {
try {
Engine_Package_Utilities::fsRmdirRecursive($outputPath, true);
} catch (Exception $e) {
$this->view->error = 'Extract path already exists and could not be removed. Please try removing it manually in temporary/package/packages';
return;
}
}
// Try to move uploaded file
if (!move_uploaded_file($info['tmp_name'], $targetFile)) {
$this->view->error = 'Unable to move file to packages directory. Please set chmod 0777 on the temporary/package/archives directory.';
return;
}
$this->view->status = 1;
$this->view->file = $info['name'];
}
/* INSTALL PROCESS -------------------------------------------------------- */
public function prepareAction()
{
// Skip
$skip = $this->_getParam('skip');
if (null !== $skip) {
$this->_session->skipDiffErrorFiles = (bool) $skip;
return $this->_helper->redirector->gotoRoute(array('action' => 'vfs'));
}
// Get navigation
$this->view->installNavigation = $this->getInstallNavigation('prepare');
// Clean cache
$this->_packageManager->getCache()->clean();
$this->view->warehouseErrors = array();
$packages = $this->_packageManager->listExtractedPackages();
$httpHost = $_SERVER['HTTP_HOST'];
if (preg_match('/^(.*?)\:([0-9]+)$/i', $httpHost, $matches)) {
$httpHost = $matches[1];
}
// if ($packages && !preg_match('/^([a-z]+)\.socialenginedev\.com$/i', $httpHost)) {
// foreach ($packages as $package) {
// if (!method_exists($package, 'getSku')) {
// continue;
// }
// $sku = $package->getSku();
//
// if (!$sku) {
// $manifestFile = $package->getBasePath() . '/' . $package->getPath() . '/settings/manifest.php';
// if (file_exists($manifestFile)) {
// $manifest = require($manifestFile);
// if (isset($manifest['package']) && isset($manifest['package']['sku'])) {
// $sku = $manifest['package']['sku'];
// }
// }
// }
// }
// }
// Check for modifications to installer (to prevent problems)
$this->_checkForModifications(true);
// Get db
if (Zend_Registry::isRegistered('Zend_Db')
&& ($db = Zend_Registry::get('Zend_Db')) instanceof Zend_Db_Adapter_Abstract) {
Engine_Sanity::setDefaultDbAdapter($db);
}
// Get packages
$this->view->transaction = $transaction =
$this->_packageManager->decide((array) $this->_getParam('packages'), $this->_getParam('actions'));
// Whoops, didn't select anything?
if (!$transaction) {
$this->view->selectError = true;
return;
}
// Get dependencies
$this->view->dependencies = $dependencies =
$transaction->getDependencies();
$dependencyError = false;
foreach ($dependencies as $dependency) {
$dependencyError |= $dependency->hasErrors();
}
$this->view->dependencyError = $dependencyError;
// Get sanity
$this->view->tests = $tests = $transaction->getTests();
$this->view->testsMaxErrorLevel = $testsMaxErrorLevel = $tests->getMaxErrorLevel();
$this->view->testsError = $testsError = ($testsMaxErrorLevel >= 4);
// Get file operations
$this->view->fileOperations = $fileOperations = $transaction->getFileOperations();
$diffError = false;
foreach ($fileOperations as $fileOperation) {
$diffError |= $fileOperation['error'];
}
$this->view->diffError = $diffError;
// Check if we can install
$this->view->prepareError = $prepareError = ($dependencyError || $testsError || $diffError);
$this->view->diffErrorOnly = $diffErrorOnly = (!$dependencyError && !$testsError && $diffError);
// Store the transaction in the cache
$this->_saveTransaction($transaction);
}
public function vfsAction()
{
// Check for modifications to installer (to prevent problems)
if (!$this->_checkForModifications()) {
return;
}
// Load the transaction from the cache
$transaction = $this->_loadTransaction();
// Get navigation
$this->view->installNavigation = $this->getInstallNavigation('vfs');
$adapterType = $this->_getParam('adapter');
if (null === $adapterType) {
$adapterType = $this->_session->vfsAdapter;
if (null === $adapterType) {
$adapterType = @$this->_vfsSettings['adapter'];
}
}
$previousAdapterType = $this->_getParam('previousAdapter');
$this->view->form = $form = new Install_Form_VfsInfo(array(
'adapterType' => $adapterType,
));
if (!$this->getRequest()->isPost() || $adapterType != $previousAdapterType) {
if (!$adapterType) {
// Ignore
} elseif ($adapterType == @$this->_session->vfsAdapter) {
// Load from session
$form->populate(array(
'adapter' => $adapterType,
'config' => $this->_session->vfsConfig
));
} elseif ($adapterType == @$this->_vfsSettings['adapter']) {
// Load from settings file
$form->populate($this->_vfsSettings);
} else {
$form->populate(array(
'adapter' => $adapterType,
));
}
return;
}
if (!$form->isValid($this->getRequest()->getPost())) {
return;
}
// Process
$values = $form->getValues();
$vfsAdapter = $values['adapter'];
$vfsConfig = $values['config'];
// Try to load adapter
try {
$vfs = Engine_Vfs::factory($vfsAdapter, $vfsConfig);
} catch (Exception $e) {
$form->addError('Connection error: ' . $e->getMessage());
return;
}
// Try to connect (getResource will force connect)
try {
$vfs->getResource();
} catch (Exception $e) {
$form->addError('Connection error: ' . $e->getMessage());
return;
}
// Search for target
$path = null;
if (!empty($vfsConfig['search']) && $vfsConfig['search'] !== '0') {
$path = $vfs->findJailedPath($vfsConfig['path'], APPLICATION_PATH . '/install/ftp_search_will_look_for_this_file');
if (!$path) {
$form->addError('Your installation could not be found. Please double check your connection info and starting path. Your starting path needs to be your SocialEngine path, or a parent directory of it.');
return;
}
$path = dirname(dirname($path));
} else {
$path = $vfsConfig['path'];
}
// Verify path
if (!$vfs->exists($path . '/install/ftp_search_will_look_for_this_file')) {
$form->addError('Specified path is not a SocialEngine install directory.');
return;
}
// Save config
$vfsConfig['path'] = $values['config']['path'] = $path;
$vfs->changeDirectory($path);
$this->_session->vfsInstance = $vfs;
$this->_session->vfsAdapter = $vfsAdapter;
$this->_session->vfsConfig = $vfsConfig;
$this->_vfsSettings = $values;
// Save for later
$vfsSettingsData = array(
'adapter' => $vfsAdapter,
'config' => array_diff_key($vfsConfig, array(
'password' => null,
'location' => null,
'search' => null,
)),
);
@file_put_contents(APPLICATION_PATH . '/install/config/vfs.php', '<?php return ' . var_export($vfsSettingsData, true) . '?>');
// Redirect to next step
return $this->_helper->redirector->gotoRoute(array('action' => 'perms'));
}
public function permsAction()
{
// Check for modifications to installer (to prevent problems)
if (!$this->_checkForModifications()) {
return;
}
// Load the transaction from the cache
$transaction = $this->_loadTransaction();
// Get navigation
$this->view->installNavigation = $this->getInstallNavigation('perms');
// Build file todo-list
$files = $transaction->getFileOperations($this->_session->skipDiffErrorFiles);
// Get the operation count
$operationCount = 0;
foreach ($files as $packageKey => $packageSummary) {
$operationCount += count($packageSummary['operations']);
}
$this->view->files = $files;
$this->view->operationCount = $operationCount;
// Get vfs object
//$this->view->vfsPath = $this->_session->vfsConfig['path'];
$vfs = $this->_session->vfsInstance;
// Check permissions
$statCache = array();
$permResults = array();
foreach ((array) $files as $packageKey => $packageSummary) {
$packageFiles = $packageSummary['operations'];
foreach ((array) $packageFiles as $packageFile => $code) {
// Check stat cache
$tmpParts = explode('/', $packageFile);
array_pop($tmpParts);
do {
$tmpPath = join('/', $tmpParts);
if (isset($statCache[$tmpPath])) {
//var_dump(sprintf('Found %d in cache for %s', $statCache[$tmpPath], $tmpPath));
$permResults[$packageKey][$tmpPath] = $statCache[$tmpPath];
continue 2;
}
//var_dump(sprintf('Nothing Found in cache for %s', $tmpPath));
array_pop($tmpParts);
} while (count($tmpParts) > 0);
// Actually check now
$tmpParts = explode('/', $packageFile);
$tmpCache = null;
$first = true;
do {
$tmpPath = join('/', $tmpParts);
try {
$tmpInfo = $vfs->info($tmpPath);
if (!$tmpInfo->exists()) {
if ($first) {
$first = false;
} else {
$tmpCache = $tmpPath;
}
//var_dump(sprintf('Nothing Found on fs for %s', $tmpPath));
} else {
$isWritable = $tmpInfo->isWritable();
$permResults[$packageKey][$tmpPath] = $isWritable;
//var_dump(sprintf('Found %d for %s', $isWritable, $tmpPath));
if ($tmpCache) {
$statCache[$tmpCache] = $isWritable;
}
continue 2;
}
} catch (Exception $e) {
// Silence
}
array_pop($tmpParts);
} while (count($tmpParts) > 0);
// Check the root path
$rootPath = $vfs->path();
if (isset($tmpCache[$rootPath])) {
$permResults[$packageKey][$tmpPath] = $tmpCache[$rootPath];
} else {
$tmpInfo = $vfs->info($rootPath);
$isWritable = $tmpInfo->isWritable();
$tmpCache[$rootPath] = $isWritable;
$permResults[$packageKey][$tmpPath] = $isWritable;
}
// Couldn't find anything?
//throw new Engine_Exception('could not find parent path');
}
}
$this->view->permResults = $permResults;
// Build summary
$notWritableCount = 0;
$permSummary = array();
foreach ((array) $permResults as $packageKey => $packageFiles) {
$permSummary[$packageKey]['writable'] = 0;
$permSummary[$packageKey]['not-writable'] = 0;
foreach ($packageFiles as $packageFile => $isWritable) {
$permSummary[$packageKey][$isWritable ? 'writable' : 'not-writable']++;
if (!$isWritable) {
$notWritableCount++;
}
}
}
$this->view->permSummary = $permSummary;
$this->view->notWritableCount = $notWritableCount;
}
public function placeAction()
{
// Check for modifications to installer (to prevent problems)
if (!$this->_checkForModifications()) {
return;
}
// Load the transaction from the cache
$transaction = $this->_loadTransaction();
// Get navigation
$this->view->installNavigation = $this->getInstallNavigation('place');
// Get vfs object
$vfs = $this->_session->vfsInstance;
$this->view->placeError = false;
// Place files
$actionSummary = array();
foreach ($transaction as $operation) {
$packageKey = $operation->getKey();
$batchSummary = $operation->getFileOperations($this->_session->skipDiffErrorFiles);
foreach ($batchSummary['operations'] as $diffSummary) {
// Copy files
$source = $diffSummary['rightPath'];
$dest = $diffSummary['relPath']; // $diffSummary['leftPath'];
//$dest = ltrim(str_replace(APPLICATION_PATH, '', $dest), '/\\');
// What to do, what to do
$code = $diffSummary['key'];
try {
switch ($code) {
// Ignore
case 'identical':
case 'ignore':
break;
case 'add':
case 'added':
$vfs->makeDirectory(dirname($dest), true);
$vfs->put($dest, $source);
$actionSummary[$packageKey][$dest] = 'added';
break;
case 'different':
case 'different_different':
if($this->_session->skipDiffErrorFiles > 0)
break;
case 'added_added':
case 'replace':
$vfs->put($dest, $source);
$actionSummary[$packageKey][$dest] = 'replaced';
break;
case 'different_removed':
case 'remove':
case 'removed':
$vfs->unlink($dest);
$actionSummary[$packageKey][$dest] = 'removed';
break;
default:
throw new Exception($code);
break;
}
} catch (Exception $e) {
// something bad happened -_-
$this->view->placeError = true;
$actionSummary[$packageKey][$dest] = 'failed (' . $e->getMessage() . ')';
}
}
}
$this->view->actionSummary = $actionSummary;
// Also apply permissions
$permSummary = array();
foreach ($transaction as $operation) {
$package = $operation->getTargetPackage();
if (!method_exists($package, 'getPermissions')) {
continue;
}
$permissions = $package->getPermissions();
if (!is_array($permissions) || empty($permissions)) {
continue;
}
foreach ($permissions as $permission) {
try {
$info = $vfs->info($permission->getPath());
if (!$info->exists()) {
$permSummary[] = $permission->getPath() . ' - Does not exist';
} elseif ($info->isFile()) {
$vfs->mode($permission->getPath(), $permission->getMode());
} elseif ($info->isDirectory()) {
if ($permission->getInclusive()) {
$vfs->mode($permission->getPath(), $permission->getMode(), $permission->getRecursive());
} else {
foreach ($info->getChildren() as $child) {
$vfs->mode($child->getPath(), $permission->getMode(), $permission->getRecursive());
}
}
} else {
$permSummary[] = $permission->getPath() . ' - Unknown file type or missing';
}
} catch (Exception $e) {
$permSummary[] = $permission->getPath() . ' - Error - ' . $e->getMessage();
}
}
}
$this->view->permSummary = $permSummary;
}
public function queryAction()
{
// Check for modifications to installer (to prevent problems)
if (!$this->_checkForModifications()) {
return;
}
// Load the transaction from the cache
$transaction = $this->_loadTransaction();
// Get navigation
$this->view->installNavigation = $this->getInstallNavigation('query');
$db = Zend_Registry::get('Zend_Db');
$vfs = $this->_session->vfsInstance;
$queryError = false;
$results = array();
// Run all them delicious database queries
// Run pre install
$packageTitles = array();
foreach ($this->_packageManager->callback($transaction, 'preinstall') as $result) {
if (!empty($result['errors'])) {
$queryError = true;
}
// Add to results
$key = $result['key'];
$packageTitles[$key] = $result['title'] . ' (' . $result['version'] . ')';
$results[$key][] = $result;
}
if ($queryError) {
$this->view->queryError = true;
$this->view->results = $results;
$this->view->packageTitles = $packageTitles;
return;
}
// Run install
foreach ($this->_packageManager->callback($transaction, 'install') as $result) {
if (!empty($result['errors'])) {
$queryError = true;
}
// Add to results
$key = $result['key'];
$packageTitles[$key] = $result['title'] . ' (' . $result['version'] . ')';
$results[$key][] = $result;
}
if ($queryError) {
$this->view->queryError = true;
$this->view->results = $results;
$this->view->packageTitles = $packageTitles;
return;
}
// Run post install
foreach ($this->_packageManager->callback($transaction, 'postinstall') as $result) {
if (!empty($result['errors'])) {
$queryError = true;
}
// Add to results
$key = $result['key'];
$packageTitles[$key] = $result['title'] . ' (' . $result['version'] . ')';
$results[$key][] = $result;
}
if ($queryError) {
$this->view->queryError = true;
$this->view->results = $results;
$this->view->packageTitles = $packageTitles;
return;
}
$this->view->results = $results;
$this->view->packageTitles = $packageTitles;
}
public function completeAction()
{
// Check for modifications to installer (to prevent problems)
if (!$this->_checkForModifications()) {
return;
}
// Load the transaction from the cache
$transaction = $this->_loadTransaction();
$this->view->installNavigation = $this->getInstallNavigation('complete');
$vfs = $this->_session->vfsInstance;
// Let's do some clean-up
try {
$this->_packageManager->cleanup($transaction);
} catch (Exception $e) {
$path = APPLICATION_PATH . '/temporary/package/packages';
if (is_dir($path)) {
rename($path, $path . '-remove-' . time());
}
mkdir($path, 0777);
}
// Try to flush the scaffold cache
try {
Engine_Package_Utilities::fsRmdirRecursive(APPLICATION_PATH . '/temporary/scaffold', false, array('index.html'));
} catch (Exception $e) {
}
// Try to increment the site counter
// try {
// $db->update('engine4_core_settings', array(
// 'value' => new Zend_Db_Expr('value + 1'),
// ), array(
// 'name = ?' => 'core.site.counter',
// ));
// } catch (Exception $e) {
// Silence
// }
$this->_session->unsetAll();
}
public function enableAction()
{
$this->view->form = $form = new Install_Form_Confirm(array(
'title' => 'Enable Package?',
'description' => 'Are you sure you want to enable this package?',
'submitLabel' => 'Enable Package',
'cancelHref' => $this->view->url(array('action' => 'index')),
'useToken' => true,
));
if (!$this->getRequest()->isPost()) {
return;
}
if (!$form->isValid($this->getRequest()->getPost())) {
return;
}
// Do the enable
$packageName = $this->_getParam('package');
$package = null;
foreach ($this->_packageManager->listInstalledPackages() as $installedPackage) {
if ($installedPackage->getKey() == $packageName) {
$package = $installedPackage;
}
}
// Enable/disable
if ($package->hasAction('enable')) {
$operation = new Engine_Package_Manager_Operation_Enable($this->_packageManager, $package);
$ret = $this->_packageManager->execute($operation, 'enable');
// Try to flush the scaffold cache
try {
Engine_Package_Utilities::fsRmdirRecursive(APPLICATION_PATH . '/temporary/scaffold', false, array('index.html'));
} catch (Exception $e) {
}
// Try to increment the site counter
try {
$db = Zend_Registry::get('Zend_Db');
$db->update('engine4_core_settings', array(
'value' => new Zend_Db_Expr('value + 1'),
), array(
'name = ?' => 'core.site.counter',
));
} catch (Exception $e) {
// Silence
}
}
return $this->_helper->redirector->gotoRoute(array('action' => 'index'));
}
public function disableAction()
{
$this->view->form = $form = new Install_Form_Confirm(array(
'title' => 'Disable Package?',
'description' => 'Are you sure you want to disable this package?',
'submitLabel' => 'Disable Package',
'cancelHref' => $this->view->url(array('action' => 'index')),
'useToken' => true,
));
if (!$this->getRequest()->isPost()) {
return;
}
if (!$form->isValid($this->getRequest()->getPost())) {
return;
}
// Do the disable
$packageName = $this->_getParam('package');
$package = null;
foreach ($this->_packageManager->listInstalledPackages() as $installedPackage) {
if ($installedPackage->getKey() == $packageName) {
$package = $installedPackage;
}
}
// Enable/disable
if ($package->hasAction('disable')) {
$operation = new Engine_Package_Manager_Operation_Disable($this->_packageManager, $package);
$ret = $this->_packageManager->execute($operation, 'disable');
}
return $this->_helper->redirector->gotoRoute(array('action' => 'index'));
}
public function installAction()
{
$this->view->form = $form = new Install_Form_Confirm(array(
'title' => 'Install Package?',
'description' => 'Are you sure you want to install this package?',
'submitLabel' => 'Install Package',
'cancelHref' => $this->view->url(array('action' => 'index')),
'useToken' => true,
));
if (!$this->getRequest()->isPost()) {
return;
}
if (!$form->isValid($this->getRequest()->getPost())) {
return;
}
// Do the disable
$packageName = $this->_getParam('package');
$package = null;
foreach ($this->_packageManager->listInstalledPackages() as $installedPackage) {
if ($installedPackage->getKey() == $packageName) {
$package = $installedPackage;
}
}
// Enable/disable
$operation = new Engine_Package_Manager_Operation_Install($this->_packageManager, $package);
$errors = array();
$queryError = false;
// Run preinstall
$result = $this->_packageManager->execute($operation, 'preinstall');
if (!empty($result['errors'])) {
$queryError = true;
$errors = array_merge($errors, $result['errors']);
}
if (isset($queryError) && $queryError) {
$this->view->queryError = true;
$this->view->errors = $errors;
return;
}
// Run install
$result = $this->_packageManager->execute($operation, 'install');
if (!empty($result['errors'])) {
$queryError = true;
$errors = array_merge($errors, $result['errors']);
}
if (isset($queryError) && $queryError) {
$this->view->queryError = true;
$this->view->errors = $errors;
return;
}
// Run postinstall
$result = $this->_packageManager->execute($operation, 'postinstall');
if (!empty($result['errors'])) {
$queryError = true;
$errors = array_merge($errors, $result['errors']);
}
if (isset($queryError) && $queryError) {
$this->view->queryError = true;
$this->view->errors = $errors;
return;
}
// Redirect if no error
if (!isset($queryError) || !$queryError) {
return $this->_helper->redirector->gotoRoute(array('action' => 'index'));
}
}
// This is used to make the beta3 appear correctly
public function betaUpdateAction()
{
if (!$this->getRequest()->isPost()) {
return;
}
$db = Zend_Registry::get('Zend_Db');
//$db = new Zend_Db_Adapter_Abstract();
// Get all module info
$select = new Zend_Db_Select($db);
$select
->from('engine4_core_modules')
;
$modules = array();
foreach ($select->query()->fetchAll() as $row) {
$modules[$row['name']] = $row;
}
$errors = array();
$installedPackages = $this->_packageManager->listInstalledPackages();
foreach ($installedPackages as $installedPackage) {
if ($installedPackage->getType() !== 'module') {
continue;
}
// Remove modules that have not been installed
if (!isset($modules[$installedPackage->getName()])) {
$packageFile = $installedPackage->getSourcePath();
if (!@unlink($packageFile)) {
$errors[] = sprintf('Unable to remove package file "%s" for not installed module "%s"', $packageFile, $modules[$installedPackage->getName()]['title']);
}
}
// Remove modules from content system that have not been installed
if (!isset($modules[$installedPackage->getName()])) {
$db->delete('engine4_core_content', array(
'name LIKE ?' => $installedPackage->getName().'.%',
));
}
}
$this->view->errors = $errors;
// Update database
try {
$db->query('ALTER TABLE `engine4_core_modules` CHANGE `version` `version` varchar(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL');
} catch (Exception $e) {
}
$db->update('engine4_core_modules', array(
'version' => '4.0.0beta3',
), array(
'version = ?' => '4.0.0',
));
// Delete pages for Groups and Events if not installed
if (!array_key_exists('group', $modules)) {
$page = new Zend_Db_Select($db);
$page->from('engine4_core_pages')
->where('name = ?', 'group_profile_index');
$page = $db->fetchRow($page);
if ($page) {
$page_id = $page['page_id'];
$db->delete('engine4_core_pages', array(
'page_id = ?' => $page_id
));
$db->delete('engine4_core_content', array(
'page_id = ?' => $page_id,
));
}
}
if (!array_key_exists('event', $modules)) {
$page = new Zend_Db_Select($db);
$page->from('engine4_core_pages')
->where('name = ?', 'event_profile_index');
$page = $db->fetchRow($page);
if ($page) {
$page_id = $page['page_id'];
$db->delete('engine4_core_pages', array(
'page_id = ?' => $page_id
));
$db->delete('engine4_core_content', array(
'page_id = ?' => $page_id
));
}
}
$this->view->status = true;
$this->view->modules = $modules;
}
// Utility
public function getInstallNavigation($active = 0)
{
return new Zend_Navigation(array(
array(
'label' => 'Choose Packages',
'uri' => 'javascript:void(0);',
'active' => ($active == 'select'),
),
array(
'label' => 'Run Pre-install Check',
'uri' => 'javascript:void(0);',
'active' => ($active == 'prepare'),
),
array(
'label' => 'Enter FTP Info',
'uri' => 'javascript:void(0);',
'active' => ($active == 'vfs'),
),
array(
'label' => 'Run Permissions Check',
'uri' => 'javascript:void(0);',
'active' => ($active == 'perms'),
),
array(
'label' => 'Copy Files',
'uri' => 'javascript:void(0);',
'active' => ($active == 'place'),
),
array(
'label' => 'Update Database',
'uri' => 'javascript:void(0);',
'active' => ($active == 'query'),
),
array(
'label' => 'Complete!',
'uri' => 'javascript:void(0);',
'active' => ($active == 'complete'),
),
));
}
/**
* @param Engine_Package_Manager_Transaction $transaction
* @return void
*/
protected function _saveTransaction(Engine_Package_Manager_Transaction $transaction)
{
$id = $transaction->getId();
$this->_session->transactionIdentity = $id;
$this->_cache->save($transaction, 'transaction' . $id);
}
/**
* @return Engine_Package_Manager_Transaction
*/
protected function _loadTransaction()
{
$id = $this->_session->transactionIdentity;
if (!$id) {
throw new Engine_Exception('No transaction id is stored in the session.');
}
$transaction = $this->_cache->load('transaction' . $id);
if (!$transaction || !($transaction instanceof Engine_Package_Manager_Transaction)) {
throw new Engine_Exception('No transaction was found in the cache.');
}
$transaction->setManager($this->_packageManager);
return $transaction;
}
protected function _checkForModifications($initialize = false)
{
return true; // Just disable it for now
$currentSignature = $this->_session->currentInstallerSignature;
$installedPackages = $this->_packageManager->listInstalledPackages();
$currentInstallerPackage = $installedPackages->offsetGet('core-install');
if (!$currentInstallerPackage || strlen($currentSignature) == 40) {
$signature = sha1(file_get_contents(__FILE__));
} else {
$signature = $currentInstallerPackage->getVersion();
}
// Initialize
if (true === $initialize) {
$this->_session->currentInstallerSignature = $signature;
return true;
}
// Was updated
elseif ($signature != $this->_session->currentInstallerSignature) {
$extractedPackages = $this->_packageManager->listExtractedPackages();
$this->view->extractedPackageKeys = $extractedPackages->getArrayKeys();
$this->view->extractedPackageKeys = array_diff($this->view->extractedPackageKeys, array(
$extractedPackages->getKeyByGuid('core-install'),
$extractedPackages->getKeyByGuid('library-engine'),
));
$this->_session->unsetAll();
$this->_helper->viewRenderer->renderScript('_installerUpdated.tpl');
return false;
}
// Was not updated
return true;
}
}