CleanCache(); $this->base = alky_get_option('apiaddr'); } /** * Clears the database cache of already fetched webpages * * @param bool $force */ function CleanCache($force = FALSE) { global $wpdb, $cache_settings; if((time() - get_option('alky_cacheage')) >= 1800 || $force) { $wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE 'alkycache_%'"); alky_update_option('cacheage', time()); } } /** * Fetches any location on the web * If $apicall is set to true, the output will be parsed as XML and returned as a formatted array * * @param string $url * @param bool $apicall * @return results */ function &get($url, $apicall = FALSE) { if($apicall) { $this->fetch($this->base . $url); $res = new MiniXMLDoc(); $res->fromString($this->results); return $res; } else { $this->fetch($url); return $this->results; } } /** * Fetches any location on the web, but only if its not cached * * @param string $url * @param bool $apicall * @return results */ function cacheget($url, $apicall = FALSE) { $option = get_option('alkycache_' . md5($url)); if($option !== FALSE) { $this->results = $option; } else { $results = $this->get($url, $apicall); add_option('alkycache_' . md5($url), 'Alchemy Cache Data', 'no'); } } } /** * Various file permissions related functions * */ Class Alky_Perms { function Alky_Perms() { } /** * Returns a requested representation of UNIX permissions * @param mixed The file permissions * @param string The desired representation, defaults to octal * @param string The given representation, defaults to decimal */ function perms_format($in_perms, $out_format = 'octal', $in_format = 'decimal') { $perms = array( 'bit' => array('setuid' => false, 'setguid' => false, 'stickyuser' => false, 'stickygroup' => false, 'stickyworld' => false), 'owner' => array('r' => false, 'w' => false, 'x' => false), 'group' => array('r' => false, 'w' => false, 'x' => false), 'world' => array('r' => false, 'w' => false, 'x' => false), ); switch($in_format) { case 'alky_perms': $perms = $in_perms; break; case 'decimal': $perms = sprintf('%o', $in_perms); break; case 'octal': $in_perms = substr($in_perms, -4); foreach(array('owner' => 1, 'group' => 2, 'world' => 3) as $index => $position) { $number = $in_perms{$position}; if(($number & 4) == 4) { $perms[$index]['r'] = true; } if(($number & 2) == 2) { $perms[$index]['w'] = true; } if(($number & 1) == 1) { $perms[$index]['x'] = true; } } break; } switch($out_format) { case 'alky_perms': $ret = $perms; break; case 'octal': $ret = '0'; foreach(array('owner', 'group', 'world') as $role) { $level = 0; if($perms[$role]['r']) $level = $level + 4; if($perms[$role]['w']) $level = $level + 2; if($perms[$role]['x']) $level = $level + 1; $ret .= $level; } break; } return $ret; } /** * @return bool Whether the wp-content plugins and themes subdirectories are writable by PHP */ function perms_ok() { return count($this->get_unwritable()) == 0; } /** * @return array Paths to files and directories in wp-content/themes and wp-content/plugins that are unwritable */ function get_unwritable() { $unwritable = array(); foreach(array_merge(alky_scandir_deep(ABSPATH . 'wp-content/plugins'), alky_scandir_deep(ABSPATH . 'wp-content/themes')) as $file) { if(!is_writable($file)) { $unwritable[] = $file; } } return $unwritable; } /** * Find the mode required for an user to do an action on a file or directory * @param string Path to file or directory * @param string Action to test for: 'r' (read), 'rw' (read and write) or 'rwx' (read, write and execute) * @param string Name of user, defaults to the server * @param boolean Whether to remove unspecified privileges from the current file mode, eg if 'r' is specified and the current mode is 'rwx', change it to 'r--'. Defaults to keeping unspecified privileges. * @return string file mode */ function get_required_mode($path, $action, $entity = 'alky_the_server', $only_escalate = true) { /* Find the role of the entity in relation to file: owner, member of group, or other */ if($entity == 'alky_the_server') { $entity = alky_array_key('name', posix_getpwuid(posix_getuid())); } $file['owner']['name'] = alky_array_key('name', posix_getpwuid(fileowner($path))); $filegroup = posix_getgrgid(filegroup($path)); $file['group']['name'] = $filegroup['name']; $file['group']['members'] = $filegroup['members']; if($entity == $file['owner']['name']) { $entity_role = 'owner'; } elseif(in_array($entity, $file['group']['members'])) { $entity_role = 'group'; } else { $entity_role = 'world'; } /* Change perms */ $current_perms = Alky_Perms::perms_format(fileperms($path), 'alky_perms'); $role_perms = $current_perms[$entity_role]; for($i = 0; $i < strlen($action); $i++) { $new_privs[] = strtolower($action{$i}); } foreach($role_perms as $priv => $state) { if(in_array($priv, $new_privs)) { $role_perms[$priv] = true; } elseif($only_escalate === false) { $role_perms[$priv] = false; } } $current_perms[$entity_role] = $role_perms; return Alky_Perms::perms_format($current_perms, 'octal', 'alky_perms'); } } /** * Environment Variables and Methods */ Class Alky_Env { function can_use_ssh2() { return function_exists('ssh2_connect'); } function can_use_zip() { return function_exists('zip_open'); } } /** * Mimic WordPress' get_option, but use only one database row for all of Alky * * @param string $option_name * @return option_value */ function alky_get_option($option_name) { $alky_opts = get_option('alchemy'); return $alky_opts[$option_name]; } /** * Mimic WordPress' add_option, but use only one database row for all of Alky * * @param string $option_name * @param mixed $option_value */ function alky_add_option($option_name, $option_value) { $alky_opts = get_option('alchemy'); if(is_null($alky_opts[$option_name])) { $alky_opts[$option_name] = $option_value; } update_option('alchemy', $alky_opts); } /** * Mimic WordPress' update_option, but use only one database row for all of Alky * * @param string $option_name * @param mixed $option_value */ function alky_update_option($option_name, $option_value) { $alky_opts = get_option('alchemy'); $alky_opts[$option_name] = $option_value; update_option('alchemy', $alky_opts); } /** * Mimic WordPress' delete_option, but only use one database row, so delete from the array * * @param string $option_name */ function alky_delete_option($option_name) { $alky_opts = get_option('alchemy'); unset($alky_opts[$option_name]); update_option('alchemy', $alky_opts); } ?>