File typo3-manager.php of Package typo3-manager

#!/usr/bin/php
<?php

error_reporting(E_ALL);

define('PACKAGE_NAME','typo3');
define('DATA_DIR','/usr/share');
define('LOCAL_STATE_DIR','/var/lib');

/**
 * SuSE Typo3 Manager to manage installed Typo3 instances.
 *
 * @author Thomas Worm <thomas.worm@thomas-worm.de>
 */
class Typo3Manager {

  /**
   * Filename to instances database.
   *
   * @var string
   */
  private $_instances_db;

  /**
   * Handle to instances database.
   *
   * @var handle
   */
  private $_instances_db_handle;

  /**
   * Buffer for instances database.
   *
   * @var array
   */
  private $_instances_db_buffer;

  /**
   * Class constructor.
   */
  public function __construct() {
    $this->init();
  }

  /**
   * Inits Typo3 manager.
   *
   * @return void
   */
  private function init() {
    $this->_instances_db = LOCAL_STATE_DIR . '/' . PACKAGE_NAME . '/' . 'instances.phpdat';
  }

  /**
   * Start point of application
   * 
   * @return void
   */
  public function run() {
    $this->printIntro();
    $this->mainMenu();
  }

  /**
   * Reads input from STDIN
   *
   * @return string
   */
  private function getInput($question, $default = '') {
    echo($question . ' [' . $default . ']: ');
    $input = fgets(STDIN);
    $input = trim($input);
    if (empty($input))
      $input = $default;
    return $input;
  }

  /**
   * Checks if user is allowed to read from instances database.
   *
   * @return bool
   */
  private function checkReadAccess() {
    return is_readable($this->_instances_db);
  }

  /**
   * Opens the instances database writeable and reads it to buffer.
   *
   + @return bool
   */
  private function openWriteableAndReadInstancesDatabase() {
    return $this->openAndReadInstancesDatabase(true);
  }

  /**
   * Opens the instances database and reads it to buffer.
   *
   * @param bool $writeable Indicates whether to open file in write mode or not.
   * @return bool
   */
  private function openAndReadInstancesDatabase($writeable = false) {
    if (!$this->openInstancesDatabase($writeable))
      return false;
    return $this->readInstancesDatabaseToBuffer();
  }

  /**
   * Opens the instances database.
   *
   * @param bool $writeable Indicates whether to open file in write mode or not.
   * @return bool
   */
  private function openInstancesDatabase($writeable = false) {
    $mode = $writeable ? 'r+' : 'r';
    $this->_instances_db_handle = fopen($this->_instances_db,$mode);
    return ($this->_instances_db_handle === FALSE) ? false : true;
  }

  /**
   * Reads the instances database to buffer.
   *
   * @return bool
   */
  private function readInstancesDatabaseToBuffer() {
    fseek($this->_instances_db_handle,0,SEEK_SET);
    #$raw = fread($this->_instances_db_handle,filesize($this->_instances_db));
    $raw = '';
    while (!feof($this->_instances_db_handle)) {
      $raw .= fread($this->_instances_db_handle, 4096);
    }
    $this->_instances_db_buffer = unserialize($raw);
    return (is_array($this->_instances_db_buffer) && $this->checkInstancesDatabaseVersion());
  }

  /**
   * Saves and closes the instances database.
   *
   * @return bool
   */
  private function saveAndCloseInstancesDatabase() {
    if (!$this->saveInstancesDatabase())
      return false;
    return $this->closeInstancesDatabase();
  }

  /**
   * Saves the instances database buffer to file.
   *
   * @return bool
   */
  private function saveInstancesDatabase() {
    if (!ftruncate($this->_instances_db_handle,0))
      return false;
    fseek($this->_instances_db_handle,0,SEEK_SET);
    $data = serialize($this->_instances_db_buffer);
    return (fwrite($this->_instances_db_handle,$data) === FALSE) ? false : true;
  }

  /**
   * Checks the version of the instances database.
   *
   * @return bool
   */
  private function checkInstancesDatabaseVersion() {
    $version = $this->_instances_db_buffer['version'];
    return (($version['major'] == 1) &&
            ($version['minor'] == 0) &&
            ($version['update'] == 0));
  }

  /**
   * Closes the instances database
   *
   * @return bool
   */
  private function closeInstancesDatabase() {
    return fclose($this->_instances_db_handle);
  }

  /**
   * Checks if user is allowed to write to instances database.
   *
   * @return bool
   */
  private function checkWriteAccess() {
    return is_writeable($this->_instances_db);
  }

  /**
   * Prints intro message.
   *
   * @return void
   */
  private function printIntro() {
    echo ("
SuSE Typo3 Manager
==================
");
  }

  /**
   * Main menu.
   *
   * @return void
   */
  private function mainMenu() {
    $choice = '';
    while ($choice != 'q') {
      $this->printMainMenu();
      $choice = $this->getInput('Your choice');
      switch($choice) {
        case 'i':
          $this->installInstance();
          break;
        case 'l':
          $this->listInstances();
          break;
        case 'q':
          break;
        default:
          echo("\nUnknown action!\n");
      }
    }
  }

  /**
   * Prints main menu on screen.
   *
   * @return void
   */
  private function printMainMenu() {
    echo ("
What do you want to do next?

i: Install a typo3 instance.
l: List installed typo3 instances.
q: Quit.

");
  }

  /**
   * Installs a typo3 instance.
   *
   * @return void
   */
  private function installInstance() {
    if ((!$this->checkReadAccess()) && (!$this->checkWriteAccess())) {
      echo("\nERROR: You're not permitted to install a Typo3 instance.\n");
      return;
    }

    if (!$this->openWriteableAndReadInstancesDatabase()) {
      die ("\nCRITICAL ERROR: Unable to open and read instances database.\n");
    }

    echo ("\nAvailable typo3 versions:\n");
    $versions = $this->getInstalledTypo3Versions();
    if (count($versions) < 1) {
      echo("\nERROR: No typo3 version is installed.\n");
      return;
    }
    sort($versions);
    foreach ($versions as $version) {
      echo ("- $version\n");
    }
    $version = $this->getInput("\nFor which version do you like to install a typo3 instance?",end($versions));
    if (!in_array($version, $versions)) {
      echo ("\nERROR: Typo3 version not found!\n");
      return;
    }

    $sitename = $this->getInput("Typo3 site name",'New TYPO3 site');
    $directory = $this->getInput('Instance directory','');
    $dbhost = $this->getInput('Database host','localhost');
    $dbuser = $this->getInput('Database username','');
    $dbpass = $this->getInput('Database password','');
    $dbname = $this->getInput('Database name','typo3');

    if (!$this->createDirectoryWithParents($directory)) {
      echo("\nERROR: Cannot create directory!\n");
      return;
    }

    if (!$this->createDirectoryStructure($directory)) {
      echo("\nERROR: Cannot create directory structure!\n");
      return;
    }

    if (!$this->createSymlinkStructure($directory, $version)) {
      echo("\nERROR: Cannot create symlink structure!\n");
      return;
    }

    if (!$this->createLocalconfFile($directory . '/typo3conf/localconf.php', $sitename, $dbhost, $dbuser, $dbpass, $dbname)) {
      echo("\nERROR: Cannot create local configuration file!\n");
      return;
    }

    $version_matches = array();
    preg_match('/^([0-9]).([0-9])$/',$version,$version_matches);

    $this->addInstanceToDatabase($sitename, $directory, $dbhost, $dbuser, $dbpass, $dbname, $version_matches[1], $version_matches[2]);

    $this->saveAndCloseInstancesDatabase();

    echo("\nTypo3 instance installed.\n");
  }

  /**
   * Add instance entry to instances database.
   *
   * @param string $sitename Typo3 site name.
   * @param string $directory Directory in which instance resists.
   * @param string $dbhost Hostname of database server.
   * @param string $dbuser Username for accessing database.
   * @param string $dbpass Password for accessing database.
   * @param string $dbname Name of database.
   * @return void
   */
  private function addInstanceToDatabase($sitename, $directory, $dbhost, $dbuser, $dbpass, $dbname, $version_major, $version_minor) {
    $this->_instances_db_buffer['instances'][] = array(
      'sitename' => $sitename,
      'directory' => $directory,
      'database' => array(
        'hostname' => $dbhost,
        'username' => $dbuser,
        'password' => $dbpass,
        'database' => $dbname
      ),
      'version' => array(
        'major' => $version_major,
        'minor' => $version_minor
      )
    );
  }

  /**
   * Creates directory with parents.
   *
   * @param string $path Directory path
   * @param integer $mode Directory mode.
   * @return bool
   */
  private function createDirectoryWithParents($path, $mode = 0755) {
    if (is_dir($path))
      return true;
    return mkdir($path, $mode, true);
  }

  /**
   * Creates localconf.php file.
   *
   * @param string $path Path name to localconf.php.
   * @param string $sitename Typo3 site name.
   * @param string $dbhost Database hostname.
   * @param string $dbuser Database username.
   * @param string $dbpass Database password.
   * @param string $dbname Database name.
   * @return bool
   */
  private function createLocalconfFile($path, $sitename, $dbhost, $dbuser, $dbpass, $dbname) {
    $fh = fopen($path, 'w');

    if ($fh === FALSE)
      return false;

    if (fwrite($fh,'
<?php
if (!defined (\'TYPO3_MODE\')) {
        die (\'Access denied.\');
}

$TYPO3_CONF_VARS[\'SYS\'][\'sitename\'] = \''.addslashes($sitename).'\';

        // Default password is "joh316" :
$TYPO3_CONF_VARS[\'BE\'][\'installToolPassword\'] = \'bacb98acf97e0b6112b1d1b650b84971\';

$TYPO3_CONF_VARS[\'EXT\'][\'extList\'] = \'info,perm,func,filelist,about,version,tsconfig_help,context_help,extra_page_cm_options,impexp,sys_note,tstemplate,tstemplate_ceditor,tstemplate_info,tstemplate_objbrowser,tstemplate_analyzer,func_wizards,wizard_crpages,wizard_sortpages,lowlevel,install,belog,beuser,aboutmodules,setup,taskcenter,info_pagetsconfig,viewpage,rtehtmlarea,css_styled_content,t3skin,t3editor,reports,felogin\';

$typo_db_extTableDef_script = \'extTables.php\';

// For backend charset
$TYPO3_CONF_VARS[\'BE\'][\'forceCharset\'] = \'utf-8\';
$TYPO3_CONF_VARS[\'SYS\'][\'setDBinit\'] = \'SET NAMES utf8;\'; 
 
// For GIFBUILDER support
// Set it to \'iconv\' or \'mbstring\'
$TYPO3_CONF_VARS[\'SYS\'][\'t3lib_cs_convMethod\'] = \'mbstring\';
// For \'iconv\' support you need at least PHP 5.
$TYPO3_CONF_VARS[\'SYS\'][\'t3lib_cs_utils\'] = \'mbstring\';

$typo_db_username = \''.addslashes($dbuser).'\';
$typo_db_password = \''.addslashes($dbpass).'\';
$typo_db_host = \''.addslashes($dbhost).'\';
$typo_db = \''.addslashes($dbname).'\';

## INSTALL SCRIPT EDIT POINT TOKEN - all lines after this points may be changed by the install script!

?>') === FALSE)
      return false;;

    return fclose($fh);
  }

  /**
   * Creates the typo3 directory structure in given folder.
   *
   * @param string $path Instance directory.
   * @return bool
   */
  private function createDirectoryStructure($path) {
    if (!$this->createDirectoryWithParents($path))
      return false;

    if (!$this->createDirectoryWithParents($path . '/fileadmin', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/fileadmin/_temp_', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/fileadmin/user_upload', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/typo3conf'))
      return false;

    if (!$this->createDirectoryWithParents($path . '/typo3conf/ext', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/typo3conf/l10n', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/uploads', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/uploads/media', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/uploads/pics', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/uploads/tf', 0777))
      return false;

    if (!$this->createDirectoryWithParents($path . '/typo3temp', 0777))
      return false;

    return true;
  }
  
  /**
   * Creates symlink structure for Typo3
   *
   * @param string $path Typo3 instance directory.
   * @param string $version Version to symlink to.
   * @return bool
   */
  private function createSymlinkStructure($path, $version) {
    if (!symlink(DATA_DIR . '/typo3-cms-' . preg_replace('/\./','_',$version), $path . '/typo3_src'))
      return false;

    if (!symlink('typo3_src/typo3', $path . '/typo3'))
      return false;

    if (!symlink('typo3_src/t3lib', $path . '/t3lib'))
      return false;

    if (!symlink('typo3_src/index.php', $path . '/index.php'))
      return false;

    return true;
  }

  /**
   * Gets the installed typo3 versions
   *
   * @return array
   */
  private function getInstalledTypo3Versions() {
    $datadir = scandir(DATA_DIR);
    return preg_filter('/^typo3-cms-([0-9])_([0-9])$/', '$1.$2', $datadir);
  }

  /**
   * Gets the instances from instances database buffer.
   *
   * @return array
   */
  private function getInstancesFromDatabase() {
    return $this->_instances_db_buffer['instances'];
  }

  /**
   * List installed typo3 instances.
   *
   * @return void
   */
  private function listInstances() {
    if (!$this->checkReadAccess()) {
      echo ("\nERROR: You're not permitted to list installed typo3 instances!\n");
      return;
    }

    if (!$this->openAndReadInstancesDatabase()) {
      die ("\nCRITICAL ERROR: Unable to open and read instances database!\n");
    }

    echo ("
Installed typo3 instances:
==========================
");

    foreach ($this->getInstancesFromDatabase() as $instance) {
      $this->printInstance($instance);
    }

    $this->closeInstancesDatabase();
  }

  /**
   * Prints an instance entry on screen.
   *
   * @param array $instance Instances entry from instances database.
   * @return void
   */
  private function printInstance($instance) {
    echo ("\nSitename:  " . $instance['sitename']);
    echo ("\nVersion:   " . $instance['version']['major'] . '.' . $instance['version']['minor']);
    echo ("\nDirectory: " . $instance['directory']);
    echo ("\nDatabase:  (Hostname: " . $instance['database']['hostname'] . ', Username: ' . $instance['database']['username'] . ', Password: ' . $instance['database']['password'] . ', Database: ' . $instance['database']['database'] . ')');
    echo ("\n");
  }

}

$app = new Typo3Manager();
$app->run();

?>
openSUSE Build Service is sponsored by