/** * function for changing owner and group to correct and safe settings. * * we read which user the web server is running under by fetching * the whoami script from the server. the owner will be the user running the * script. Public upload dir /htdocs/files will then be set to 770 with correct * user and group * * @return int value from exec command */ function cos_chmod_files() { $group = conf::getServerUser(); if (!$group) { common::echoMessage('Servername is not set in config.ini', 'r'); common::echoMessage('Set it, and try again', 'y'); return 1; } // Try to get login username // As it is easier for the current user to examine // the files which belongs to the web user if (function_exists('posix_getlogin')) { $owner = posix_getlogin(); } else { $owner = exec('whoami'); } if (!$owner) { $owner = $group; } common::needRoot(); $files_path = conf::pathBase() . '/htdocs/files '; $files_path .= conf::pathBase() . '/logs '; $files_path .= conf::pathBase() . '/private '; $files_path .= conf::pathBase() . '/config/multi'; $command = "chown -R {$owner}:{$group} {$files_path}"; common::execCommand($command); $command = "chmod -R 770 {$files_path}"; common::execCommand($command); }
function cos_upgrade_to($version) { common::echoMessage("Will now pull source, and checkout latest tag", 'y'); $command = "git fetch --tags && git checkout master && git pull && git checkout {$version}"; $ret = common::execCommand($command); if ($ret) { common::abort('Aborting upgrade'); } common::echoMessage("Will upgrade vendor with composer according to version", 'y'); $command = "composer update"; $ret = common::systemCommand($command); if ($ret) { common::abort('Composer update failed.'); } common::echoMessage("Will upgrade all modules and templates the versions in the profile", 'y'); // Upgrade all modules and templates $profile = conf::getModuleIni('system_profile'); if (!$profile) { $profile = 'default'; } upgrade_from_profile(array('clone_only' => 1, 'profile' => $profile)); // reload any changes common::echoMessage("Reloading all configuration files", 'y'); $p = new profile(); $p->reloadProfile($profile); common::echoMessage("Load modules changes into database", 'y'); cos_config_reload(); }
function miau_colors($options) { $ary = miau_get_colors(); foreach ($ary as $color) { common::echoMessage($color); $char = substr($color, 0, 1); echo common::colorOutput(miau_cat(), $char) . PHP_EOL; } }
function cron_install() { $mes = "Add the following line to your crontab"; common::echoMessage($mes); $command = diversen\conf::pathBase() . "/coscli.sh cron --run"; $command = "* * * * * {$command} 1>> /dev/null 2>&1"; common::echoMessage($command); return 0; }
function cron_install() { $mes = "Add the following line to your crontab"; common::echoMessage($mes); $command = conf::pathBase() . "/coscli.sh cron --run"; $log = conf::pathBase() . "/logs/cron.log"; $command = "* * * * * {$command} >> {$log} 2>&1"; common::echoMessage($command); return 0; }
/** * function for purgeing a template * * @param array options */ function purge_template($options) { //uninstall_module($options); if (strlen($options['template']) == 0) { common::echoMessage("No such template: {$options['template']}"); common::abort(); } $template_path = conf::pathBase() . '/htdocs/templates/' . $options['template']; if (!file_exists($template_path)) { common::echoMessage("Template already purged: No such template path: {$template_path}"); common::abort(); } $command = "rm -rf {$template_path}"; common::execCommand($command); }
function multi_shared_exec_command($options = null) { $path = conf::pathBase() . "/config/multi/*"; if (!isset($options['command'])) { common::abort('Specify a command'); return 1; } $command = $options['command']; $dirs = file::getDirsGlob($path, array('basename' => 1)); foreach ($dirs as $domain) { $exec_command = "./coscli.sh --domain={$domain} {$command}"; common::echoMessage("Executing command: {$exec_command}"); passthru($exec_command, $return_var); } }
/** * function for upgrading a module * * @param array options the module to be upgraded */ function cos_menu_uninstall_menu($options) { // check if module exists in modules dir $module_path = conf::pathModules() . '/' . $options['module']; if (!file_exists($module_path)) { common::echoMessage("module {$options['module']} does not exists in modules dir. "); } $menu = new moduleinstaller($options); $res = $menu->deleteMenuItem($options['module']); if ($res) { if (conf::getMainIni('verbose')) { common::echoMessage("Main menu item for '{$options['module']}' deleted"); } } }
/** * wrapper function for creating documention with phpdoc * hi! I'am created with this function :) * * @return int value from cos_system command */ function create_docs() { // check if command exists $command = "whereis phpdoc"; $ret = common::execCommand($command); if ($ret) { common::echoMessage("Could not find command phpdoc on your system"); common::echoMessage("If the command phpdoc is not on your system we will not be able to create documentation."); common::echoMessage("One way to do this is to: pear install PhpDocumentor"); exit(127); } $command = "phpdoc run "; $command .= "-d coslib "; $command .= "--template abstract -t " . conf::pathBase() . "/htdocs/phpdocs "; common::systemCommand($command); }
/** * function for checking if your are denying people * from e.g. admin areas of your module. */ function dev_test_access($options = null) { $files = file::getFileListRecursive(conf::pathModules(), "*module.php"); foreach ($files as $val) { $class_path = "modules" . str_replace(conf::pathModules(), '', $val); $class_path = str_replace('.php', '', $class_path); $class = str_replace('/', "\\", $class_path); $ary = get_class_methods($class); if (!is_array($ary)) { continue; } $call_paths = dev_get_actions($ary, $class_path); foreach ($call_paths as $path) { $url = conf::getSchemeWithServerName() . "{$path}"; $curl = new mycurl($url); $curl->createCurl(); echo $curl->getHttpStatus(); common::echoMessage(" Status code recieved on: {$url}"); } } }
function db_to_sqlite($options = array()) { $check = "which sequel"; if (common::execCommand($check)) { common::echoMessage('You need sequel. Install it like this, e.g.:'); common::echoMessage('sudo aptitude install ruby-sequel libsqlite3-ruby libmysql-ruby'); common::abort(); } else { common::echoStatus('OK', 'g', 'Sequel is installed'); } $ok = false; $info = admin::getDbInfo(); if (!$info) { return db_no_url(); } if ($info['scheme'] == 'mysql') { $ok = true; } if ($info['scheme'] == 'mysqli') { $ok = true; } if (!$ok) { common::echoStatus('ERROR', 'r', 'Driver needs to be mysql or mysqli'); } $fs = new Filesystem(); $fs->remove('sqlite/database.sql'); $username = conf::getMainIni('username'); $password = conf::getMainIni('password'); $command = "sequel "; $command .= "{$info['scheme']}://{$username}:{$password}@{$info['host']}/{$info['dbname']} "; $command .= "-C "; $command .= "sqlite://sqlite/database.sql"; $ret = common::systemCommand($command); $base = conf::pathBase(); if (!$ret) { $fs->chmod('sqlite/database.sql', 0777, 00, true); common::echoMessage('Sqlite database created. Edit config.ini and add:'); common::echoMessage("sqlite:/{$base}/sqlite/database.sql"); } }
/** * reads install info from modules/module_name/install.inc * @param array $options */ public function setInstallInfo($options) { // In profile all templates are also modules if (isset($options['module_name'])) { $template_name = $options['module_name']; } else { $template_name = $options['template']; } // Set dir and ini files $template_dir = conf::pathHtdocs() . "/templates/{$template_name}"; $ini_file = $template_dir . "/{$template_name}.ini"; $ini_file_dist = $template_dir . "/{$template_name}.ini-dist"; // Profile if (isset($options['profile'])) { $ini_file_dist = conf::pathBase() . "/profiles/{$options['profile']}/{$template_name}.ini-dist"; } // Generate ini file $this->generateInifile($ini_file, $ini_file_dist); if (file_exists($template_dir)) { $install_file = "{$template_dir}/install.inc"; if (!file_exists($install_file)) { common::echoMessage("Notice: No install file '{$install_file}' found in: '{$template_dir}'\n"); } $this->installInfo['NAME'] = $template_name; // if no version we check if this is a git repo if (!isset($this->installInfo['VERSION'])) { $this->setInstallInfoFromGit(); } if (file_exists($install_file)) { include $install_file; $this->installInfo = $_INSTALL; $this->installInfo['NAME'] = $template_name; $this->installInfo['RUN_LEVEL'] = 0; } } else { common::echoMessage("Notice: No template dir: {$template_dir}\n"); } }
/** * function for creating a skeleton for a module. We are just * using shell command touch for creating the files. * * @param array e.g: <code>array('module' => 'test')</code> This will create * the following folder /modules/test containing base files * used when writing a module * @return int result from shell operation 0 is success */ function create_module_skeleton($args) { $module_name = $args['module']; $ary = explode('/', $module_name); $module_path = conf::pathModules() . '/' . $module_name; common::execCommand('mkdir ' . $module_path); if (count($ary) == 1) { // create dirs for sql. Only need in a base module $mysql_dir = $module_path . "/mysql"; common::execCommand('mkdir ' . $mysql_dir); $mysql_up = $mysql_dir . "/up"; common::execCommand('mkdir ' . $mysql_up); $mysql_down = $mysql_dir . "/down"; common::execCommand('mkdir ' . $mysql_down); // create dirs for language. Only need in base module $lang_dir = $module_path . "/lang"; common::execCommand('mkdir ' . $lang_dir); $lang_dir_en = $module_path . "/lang/en_GB"; common::execCommand('mkdir ' . $lang_dir_en); $files = $module_path . "/menu.inc "; $files .= $module_path . "/views.php "; $files .= $module_path . "/README.md "; $files .= $module_path . "/install.inc "; $files .= $module_path . "/{$module_name}.ini "; $files .= $module_path . "/{$module_name}.ini-dist "; $files .= $module_path . "/module.php "; $files .= $lang_dir_en . "/system.inc "; $files .= $lang_dir_en . "/language.inc "; } common::echoMessage('Creating files: '); $res = common::execCommand('touch ' . $files); if (!$res) { // add a version $str = "<?php\n\n\$_INSTALL['VERSION'] = 1.71; \n"; $res = file_put_contents($module_path . "/install.inc", $str); $res; } }
/** * Upgrade to a specific version of a module * @param float $specific, e.g. '5.06' * @return boolean $res */ public function upgrade($specific = null) { // Only upgrade if module is installed if (!moduleloader::isInstalledModule($this->installInfo['NAME'])) { common::echoMessage("Notice: Can not upgrade. You will need to install module first"); return; } // Get specific version if (!isset($specific)) { $specific = $this->installInfo['VERSION']; } // Get current module version from registry $row = $this->getModuleDbInfo(); $current_version = $row['module_version']; // Same version. Return if ($current_version == $specific) { $this->confirm = "Module '" . $this->installInfo['NAME'] . "'. Version is '{$specific}'. No upgrade to perform"; return true; } // Get a list of SQL updates to perform $updates = $this->getSqlFileListOrdered($this->installInfo['NAME'], 'up'); // perform sql upgrade if (!empty($updates)) { foreach ($updates as $key => $val) { $possible_versions = ''; $version = substr($val, 0, -4); if ($version == $specific) { $version_exists = true; } else { $possible_versions .= "{$version} "; } } if (!isset($version_exists)) { $this->error = 'Module SQL ' . $this->installInfo['NAME'] . " "; $this->error .= 'does not have such a version. Possible version are: '; $this->error .= $possible_versions; } // perform SQL updates found in .sql files foreach ($updates as $key => $val) { $version = substr($val, 0, -4); if ($current_version < $version) { $this->executeSqlUpgrade($version); } } } // update registry $this->updateRegistry($specific, $row['id']); if ($specific > $current_version) { $this->confirm = "Module '" . $this->installInfo['NAME'] . "'. "; $this->confirm .= "Version '" . $specific . "' installed. "; $this->confirm .= "Upgraded from {$current_version}"; return true; } else { $this->confirm = "Module '" . $this->installInfo['NAME'] . "'. Nothing to upgrade. Module version is still {$current_version}"; return true; } }
/** * function for loading a database file into db specified in config.ini * * @param array options. You can specifiy a file to load in options. * e.g. <code>$options = array('File' => 'backup/sql/latest.sql')</code> * @return int the executed commands shell status 0 on success. */ function load_db_file($options) { if (!isset($options['File'])) { common::echoMessage('You did not specify file to load. We use latest!'); $latest = get_latest_db_dump(); if ($latest == 0) { common::abort('Yet no database dumps'); } $latest = "backup/sql/" . $latest . ".sql"; $file = $latest; } else { $file = $options['File']; if (!file_exists($file)) { common::abort("No such file: {$file}"); } } $db = admin::getDbInfo(conf::getMainIni('url')); if (!$db) { return db_no_url(); } $command = "mysql --default-character-set=utf8 -u" . conf::$vars['coscms_main']['username'] . " -p" . conf::$vars['coscms_main']['password'] . " -h{$db['host']} {$db['dbname']} < {$file}"; return $ret = common::execCommand($command); }
/** * function for updating a modules .ini file with new settings * from updated ini-dist file. * * @param array $options */ function update_ini_file($options) { if (!isset($options['module'])) { echo "Specify module\n"; exit(1); } $ini_file_path = conf::pathModules() . "/{$options['module']}/{$options['module']}.ini"; $ini_dist_path = $ini_file_path . "-dist"; $ini_file = conf::getIniFileArray($ini_file_path); $ini_dist = conf::getIniFileArray($ini_dist_path); $new_settings = array(); foreach ($ini_dist as $key => $val) { if (!isset($ini_file[$key])) { $ini_file[$key] = $val; // used for displaying which settings were updated. $new_settings[$key] = $val; } } // write it to ini file $content = conf::arrayToIniFile($ini_file); file_put_contents($ini_file_path, $content); // install profile. if (!empty($new_settings)) { $new_settings_str = conf::arrayToIniFile($new_settings); common::echoMessage("New ini file written with updated settings: {$ini_file_path}"); common::echoMessage("These are the new ini settings for module {$options['module']}:"); common::echoMessage(trim($new_settings_str)); } }
/** * Checks if any table exist in database * @return boolean */ public static function tablesExists() { $db = new db(); $ret = $db->connect(array('dont_die' => 1)); if ($ret == 'NO_DB_CONN') { return false; } $info = admin::getDbInfo(); if (!$info) { common::echoMessage('No databse url in config.ini'); } if ($info['scheme'] == 'mysql' || $info['scheme'] == 'mysqli') { $rows = $db->selectQuery("SHOW TABLES"); if (empty($rows)) { return false; } return true; } if ($info['scheme'] == 'sqlite') { $sql = "SELECT name FROM sqlite_master WHERE type='table' AND name='modules'"; $rows = $db->selectQuery($sql); if (empty($rows)) { return false; } return true; } }
/** * function for updating a modules .ini file with new settings * from updated ini-dist file. * * @param array $options */ function upgrade_config_ini_file($options) { $ini_file_path = conf::pathBase() . "/config/config.ini"; $ini_dist_path = conf::pathBase() . "/profiles/{$options['profile']}/config.ini-dist"; $ini_file = conf::getIniFileArray($ini_file_path, true); $ini_dist = conf::getIniFileArray($ini_dist_path, true); $ary = array_merge($ini_dist, $ini_file); $ary_diff = array_diff($ary, $ini_file); $content = conf::arrayToIniFile($ary); file_put_contents($ini_file_path, $content); if (empty($ary_diff)) { common::echoMessage("No new ini file settings for config.ini"); } else { $new_settings_str = conf::arrayToIniFile($ary_diff); common::echoMessage("New ini file written to: {$ini_file_path}"); common::echoMessage("These are the new ini settings for config.ini"); common::echoMessage(trim($new_settings_str)); } }
/** * prompt install command */ function heroku_prompt_install() { $res = common::execCommand("which heroku"); if ($res) { die('You wll need the heroku command. Download the heroku toolbelt'); } echo "Enabling addons ... wait\n"; heroku_enable_addons(); common::execCommand("cp misc/htaccess .htaccess"); common::execCommand("mkdir -p files/default"); common::execCommand("chmod -R 777 files"); common::execCommand("touch files/default/dummy.txt"); load_db_default(); common::echoMessage('Installing all modules. This may take a few minutes. Be patient'); install_from_profile(array('profile' => 'default')); useradd_add(); }
/** * function for showing git tags (just for testing) * @param array $options */ function cos_git_echo_remote_tags($options) { if (empty($options['repo'])) { common::abort('You need to specify a repo'); } $tags = git::getTagsRemote($options['repo']); if (empty($tags)) { common::abort('No tags'); } $latest = git::getTagsRemoteLatest($options['repo']); common::echoMessage("Latest is: {$latest}"); }
/** * Execute the parser. * @param array $result * @return int $ret the result of the command execution */ public static function execute($result) { $ret = 0; if (is_object($result) && isset($result->command_name)) { if (isset($result->command->options)) { foreach ($result->command->options as $key => $val) { // command option if set run call back if ($val == 1) { if (function_exists($key)) { $ret = $key($result->command->args); } else { common::abort("No such function {$key}"); } } else { $no_sub = 1; } } return $ret; } else { $no_base = 1; } } if (isset($no_sub)) { common::echoMessage('No sub commands given use -h or --help for help'); } if (isset($no_base)) { common::echoMessage('No base commands given use -h or --help for help'); } }
/** * function for doing a prompt install from shell mode * is a wrapper around other shell functions. */ function prompt_install() { common::echoMessage('Pick a version to install:', 'y'); $tags = git::getTagsInstallLatest() . PHP_EOL; $tags .= "master"; common::echoMessage($tags); $tag = common::readSingleline("Enter tag (version) to use:"); common::execCommand("git checkout {$tag}"); // Which profile to install $profiles = file::getFileList('profiles', array('dir_only' => true)); if (count($profiles) == 1) { $profile = array_pop($profiles); } else { common::echoMessage("List of profiles: "); foreach ($profiles as $val) { common::echoMessage("\t" . $val); } // select profile and load it $profile = common::readSingleline('Enter profile, and hit return: '); } common::echoMessage("Loading the profile '{$profile}'", 'y'); load_profile(array('profile' => $profile, 'config_only' => true)); common::echoMessage("Main configuration (placed in config/config.ini) for '{$profile}' is loaded", 'y'); // Keep base path. Ortherwise we will lose it when loading profile $base_path = conf::pathBase(); // Load the default config.ini settings as a skeleton conf::$vars['coscms_main'] = conf::getIniFileArray($base_path . '/config/config.ini', true); // Reset base path conf::setMainIni('base_path', $base_path); conf::defineCommon(); common::echoMessage("Enter MySQL credentials", 'y'); // Get configuration info $host = common::readSingleline('Enter your MySQL host: '); $database = common::readSingleline('Enter database name: '); $username = common::readSingleline('Enter database user: '******'Enter database users password: '******'Enter server host name: '); common::echoMessage("Writing database connection info to main configuration"); // Assemble configuration info conf::$vars['coscms_main']['url'] = "mysql:dbname={$database};host={$host};charset=utf8"; conf::$vars['coscms_main']['username'] = $username; conf::$vars['coscms_main']['password'] = $password; conf::$vars['coscms_main']['server_name'] = $server_name; // Write it to ini file $content = conf::arrayToIniFile(conf::$vars['coscms_main'], false); $path = conf::pathBase() . "/config/config.ini"; file_put_contents($path, $content); common::echoMessage("Your can also always change the config/config.ini file manually"); $options = array(); $options['profile'] = $profile; if ($tag == 'master') { $options['master'] = true; } common::echoMessage("Will now clone and install all modules", 'y'); cos_install($options); common::echoMessage("Create a super user", 'y'); useradd_add(); $login = "******"; common::echoMessage("If there was no errors you will be able to login at {$login}"); common::echoMessage("Remember to change file permissions. This will require super user"); common::echoMessage("E.g. like this:"); common::echoMessage("sudo ./coscli.sh file --chmod-files"); }