sm = new \Zotlabs\Web\SubModule(); } function post(){ logger('admin_post', LOGGER_DEBUG); if(! is_site_admin()) { return; } // urls if (argc() > 1) { switch (argv(1)) { case 'site': $this->admin_page_site_post($a); break; case 'accounts': $this->admin_page_accounts_post($a); break; case 'channels': $this->admin_page_channels_post($a); break; case 'plugins': if (argc() > 2 && argv(2) === 'addrepo') { $this->admin_page_plugins_post('addrepo'); break; } if (argc() > 2 && argv(2) === 'installrepo') { $this->admin_page_plugins_post('installrepo'); break; } if (argc() > 2 && argv(2) === 'removerepo') { $this->admin_page_plugins_post('removerepo'); break; } if (argc() > 2 && argv(2) === 'updaterepo') { $this->admin_page_plugins_post('updaterepo'); break; } if (argc() > 2 && is_file("addon/" . argv(2) . "/" . argv(2) . ".php")){ @include_once("addon/" . argv(2) . "/" . argv(2) . ".php"); if(function_exists(argv(2).'_plugin_admin_post')) { $func = argv(2) . '_plugin_admin_post'; $func($a); } } goaway(z_root() . '/admin/plugins/' . argv(2) ); break; case 'themes': $theme = argv(2); if (is_file("view/theme/$theme/php/config.php")){ require_once("view/theme/$theme/php/config.php"); // fixme add parent theme if derived if (function_exists("theme_admin_post")){ theme_admin_post($a); } } info(t('Theme settings updated.')); if(is_ajax()) return; goaway(z_root() . '/admin/themes/' . $theme ); break; case 'logs': $this->admin_page_logs_post($a); break; case 'features': $this->admin_page_features_post($a); break; case 'dbsync': $this->admin_page_dbsync_post($a); break; case 'profs': $this->admin_page_profs_post($a); break; default: $this->sm->call('post'); break; } } goaway(z_root() . '/admin' ); } /** * @param App &$a * @return string */ function get() { logger('admin_content', LOGGER_DEBUG); if(! is_site_admin()) { return login(false); } /* * Page content */ $o = ''; // urls if (argc() > 1){ switch (argv(1)) { case 'site': $o = $this->admin_page_site($a); break; case 'accounts': $o = $this->admin_page_accounts($a); break; case 'channels': $o = $this->admin_page_channels($a); break; case 'themes': $o = $this->admin_page_themes($a); break; case 'features': $o = $this->admin_page_features($a); break; case 'logs': $o = $this->admin_page_logs($a); break; case 'dbsync': $o = $this->admin_page_dbsync($a); break; case 'profs': $o = $this->admin_page_profs($a); break; case 'queue': $o = $this->admin_page_queue($a); break; default: $o = $this->sm->call('get'); if($o === false) { notice( t('Item not found.') ); } break; } } else { $o = $this->admin_page_summary($a); } if(is_ajax()) { echo $o; killme(); return ''; } else { return $o; } } /** * @brief Returns content for Admin Summary Page. * * @param App &$a * @return string HTML from parsed admin_summary.tpl */ function admin_page_summary(&$a) { // list total user accounts, expirations etc. $accounts = array(); $r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN account_expires > %s THEN 1 ELSE NULL END) AS expiring, COUNT(CASE WHEN account_expires < %s AND account_expires != '%s' THEN 1 ELSE NULL END) AS expired, COUNT(CASE WHEN (account_flags & %d)>0 THEN 1 ELSE NULL END) AS blocked FROM account", db_utcnow(), db_utcnow(), dbesc(NULL_DATE), intval(ACCOUNT_BLOCKED) ); if ($r) { $accounts['total'] = array('label' => t('# Accounts'), 'val' => $r[0]['total']); $accounts['blocked'] = array('label' => t('# blocked accounts'), 'val' => $r[0]['blocked']); $accounts['expired'] = array('label' => t('# expired accounts'), 'val' => $r[0]['expired']); $accounts['expiring'] = array('label' => t('# expiring accounts'), 'val' => $r[0]['expiring']); } // pending registrations $r = q("SELECT COUNT(id) AS `count` FROM `register` WHERE `uid` != '0'"); $pending = $r[0]['count']; // available channels, primary and clones $channels = array(); $r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN channel_primary = 1 THEN 1 ELSE NULL END) AS main, COUNT(CASE WHEN channel_primary = 0 THEN 1 ELSE NULL END) AS clones FROM channel WHERE channel_removed = 0"); if ($r) { $channels['total'] = array('label' => t('# Channels'), 'val' => $r[0]['total']); $channels['main'] = array('label' => t('# primary'), 'val' => $r[0]['main']); $channels['clones'] = array('label' => t('# clones'), 'val' => $r[0]['clones']); } // We can do better, but this is a quick queue status $r = q("SELECT COUNT(outq_delivered) AS total FROM outq WHERE outq_delivered = 0"); $queue = (($r) ? $r[0]['total'] : 0); $queues = array( 'label' => t('Message queues'), 'queue' => $queue ); // If no plugins active return 0, otherwise list of plugin names $plugins = (count(\App::$plugins) == 0) ? count(\App::$plugins) : \App::$plugins; // Could be extended to provide also other alerts to the admin $alertmsg = ''; // annoy admin about upcoming unsupported PHP version if (version_compare(PHP_VERSION, '5.4', '<')) { $alertmsg = 'Your PHP version ' . PHP_VERSION . ' will not be supported with the next major release of $Projectname. You are strongly urged to upgrade to a current version.' . '
PHP 5.3 has reached its End of Life (EOL) in August 2014.' . ' A list about current PHP versions can be found here.'; } $vmaster = get_repository_version('master'); $vdev = get_repository_version('dev'); $upgrade = ((version_compare(STD_VERSION,$vmaster) < 0) ? t('Your software should be updated') : ''); $t = get_markup_template('admin_summary.tpl'); return replace_macros($t, array( '$title' => t('Administration'), '$page' => t('Summary'), '$adminalertmsg' => $alertmsg, '$queues' => $queues, '$accounts' => array( t('Registered accounts'), $accounts), '$pending' => array( t('Pending registrations'), $pending), '$channels' => array( t('Registered channels'), $channels), '$plugins' => array( t('Active plugins'), $plugins ), '$version' => array( t('Version'), STD_VERSION), '$vmaster' => array( t('Repository version (master)'), $vmaster), '$vdev' => array( t('Repository version (dev)'), $vdev), '$upgrade' => $upgrade, '$build' => get_config('system', 'db_version') )); } /** * @brief POST handler for Admin Site Page. * * @param App &$a */ function admin_page_site_post(&$a){ if (!x($_POST, 'page_site')){ return; } check_form_security_token_redirectOnErr('/admin/site', 'admin_site'); $sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : ''); $server_role = ((x($_POST,'server_role')) ? notags(trim($_POST['server_role'])) : 'standard'); $banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false); $admininfo = ((x($_POST,'admininfo')) ? trim($_POST['admininfo']) : false); $language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : ''); $theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : ''); $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : ''); // $site_channel = ((x($_POST,'site_channel')) ? notags(trim($_POST['site_channel'])) : ''); $maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0); $register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0); $access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0); $invite_only = ((x($_POST,'invite_only')) ? True : False); $abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0); $register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : ''); $frontpage = ((x($_POST,'frontpage')) ? notags(trim($_POST['frontpage'])) : ''); $mirror_frontpage = ((x($_POST,'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0); $directory_server = ((x($_POST,'directory_server')) ? trim($_POST['directory_server']) : ''); $allowed_sites = ((x($_POST,'allowed_sites')) ? notags(trim($_POST['allowed_sites'])) : ''); $force_publish = ((x($_POST,'publish_all')) ? True : False); $disable_discover_tab = ((x($_POST,'disable_discover_tab')) ? False : True); $login_on_homepage = ((x($_POST,'login_on_homepage')) ? True : False); $enable_context_help = ((x($_POST,'enable_context_help')) ? True : False); $global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : ''); $no_community_page = !((x($_POST,'no_community_page')) ? True : False); $default_expire_days = ((array_key_exists('default_expire_days',$_POST)) ? intval($_POST['default_expire_days']) : 0); $verifyssl = ((x($_POST,'verifyssl')) ? True : False); $proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : ''); $proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : ''); $timeout = ((x($_POST,'timeout')) ? intval(trim($_POST['timeout'])) : 60); $delivery_interval = ((x($_POST,'delivery_interval'))? intval(trim($_POST['delivery_interval'])) : 0); $delivery_batch_count = ((x($_POST,'delivery_batch_count') && $_POST['delivery_batch_count'] > 0)? intval(trim($_POST['delivery_batch_count'])) : 1); $poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0); $maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50); $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0); $verify_email = ((x($_POST,'verify_email')) ? 1 : 0); set_config('system', 'server_role', $server_role); set_config('system', 'feed_contacts', $feed_contacts); set_config('system', 'delivery_interval', $delivery_interval); set_config('system', 'delivery_batch_count', $delivery_batch_count); set_config('system', 'poll_interval', $poll_interval); set_config('system', 'maxloadavg', $maxloadavg); set_config('system', 'frontpage', $frontpage); set_config('system', 'mirror_frontpage', $mirror_frontpage); set_config('system', 'sitename', $sitename); set_config('system', 'login_on_homepage', $login_on_homepage); set_config('system', 'enable_context_help', $enable_context_help); set_config('system', 'verify_email', $verify_email); set_config('system', 'default_expire_days', $default_expire_days); if($directory_server) set_config('system','directory_server',$directory_server); if ($banner == '') { del_config('system', 'banner'); } else { set_config('system', 'banner', $banner); } if ($admininfo == ''){ del_config('system', 'admininfo'); } else { require_once('include/text.php'); linkify_tags($a, $admininfo, local_channel()); set_config('system', 'admininfo', $admininfo); } set_config('system', 'language', $language); set_config('system', 'theme', $theme); if ( $theme_mobile === '---' ) { del_config('system', 'mobile_theme'); } else { set_config('system', 'mobile_theme', $theme_mobile); } // set_config('system','site_channel', $site_channel); set_config('system','maximagesize', $maximagesize); set_config('system','register_policy', $register_policy); set_config('system','invitation_only', $invite_only); set_config('system','access_policy', $access_policy); set_config('system','account_abandon_days', $abandon_days); set_config('system','register_text', $register_text); set_config('system','allowed_sites', $allowed_sites); set_config('system','publish_all', $force_publish); set_config('system','disable_discover_tab', $disable_discover_tab); if ($global_directory == '') { del_config('system', 'directory_submit_url'); } else { set_config('system', 'directory_submit_url', $global_directory); } set_config('system','no_community_page', $no_community_page); set_config('system','no_utf', $no_utf); set_config('system','verifyssl', $verifyssl); set_config('system','proxyuser', $proxyuser); set_config('system','proxy', $proxy); set_config('system','curl_timeout', $timeout); info( t('Site settings updated.') . EOL); goaway(z_root() . '/admin/site' ); } /** * @brief Admin page site. * * @param App $a * @return string */ function admin_page_site(&$a) { /* Installed langs */ $lang_choices = array(); $langs = glob('view/*/hstrings.php'); if(is_array($langs) && count($langs)) { if(! in_array('view/en/hstrings.php',$langs)) $langs[] = 'view/en/'; asort($langs); foreach($langs as $l) { $t = explode("/",$l); $lang_choices[$t[1]] = $t[1]; } } /* Installed themes */ $theme_choices_mobile["---"] = t("Default"); $theme_choices = array(); $files = glob('view/theme/*'); if($files) { foreach($files as $file) { $vars = ''; $f = basename($file); if (file_exists($file . '/library')) continue; if (file_exists($file . '/mobile')) $vars = t('mobile'); if (file_exists($file . '/experimental')) $vars .= t('experimental'); if (file_exists($file . '/unsupported')) $vars .= t('unsupported'); if ($vars) { $theme_choices[$f] = $f . ' (' . $vars . ')'; $theme_choices_mobile[$f] = $f . ' (' . $vars . ')'; } else { $theme_choices[$f] = $f; $theme_choices_mobile[$f] = $f; } } } $dir_choices = null; $dirmode = get_config('system','directory_mode'); $realm = get_directory_realm(); // directory server should not be set or settable unless we are a directory client if($dirmode == DIRECTORY_MODE_NORMAL) { $x = q("select site_url from site where site_flags in (%d,%d) and site_realm = '%s'", intval(DIRECTORY_MODE_SECONDARY), intval(DIRECTORY_MODE_PRIMARY), dbesc($realm) ); if($x) { $dir_choices = array(); foreach($x as $xx) { $dir_choices[$xx['site_url']] = $xx['site_url']; } } } /* Banner */ $banner = get_config('system', 'banner'); if($banner === false) $banner = get_config('system','sitename'); $banner = htmlspecialchars($banner); /* Admin Info */ $admininfo = get_config('system', 'admininfo'); /* Register policy */ $register_choices = Array( REGISTER_CLOSED => t("No"), REGISTER_APPROVE => t("Yes - with approval"), REGISTER_OPEN => t("Yes") ); /* Acess policy */ $access_choices = Array( ACCESS_PRIVATE => t("My site is not a public server"), ACCESS_PAID => t("My site has paid access only"), ACCESS_FREE => t("My site has free access only"), ACCESS_TIERED => t("My site offers free accounts with optional paid upgrades") ); // $ssl_choices = array( // SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"), // SSL_POLICY_FULL => t("Force all links to use SSL") // ); $discover_tab = get_config('system','disable_discover_tab'); // $disable public streams by default if($discover_tab === false) $discover_tab = 1; // now invert the logic for the setting. $discover_tab = (1 - $discover_tab); $server_roles = [ 'basic' => t('Basic/Minimal Social Networking'), 'standard' => t('Standard Configuration (default)'), 'pro' => t('Professional') ]; $homelogin = get_config('system','login_on_homepage'); $enable_context_help = get_config('system','enable_context_help'); $t = get_markup_template("admin_site.tpl"); return replace_macros($t, array( '$title' => t('Administration'), '$page' => t('Site'), '$submit' => t('Submit'), '$registration' => t('Registration'), '$upload' => t('File upload'), '$corporate' => t('Policies'), '$advanced' => t('Advanced'), '$baseurl' => z_root(), // name, label, value, help string, extra data... '$sitename' => array('sitename', t("Site name"), htmlspecialchars(get_config('system','sitename'), ENT_QUOTES, 'UTF-8'),''), '$server_role' => array('server_role', t("Server Configuration/Role"), get_config('system','server_role'),'',$server_roles), '$banner' => array('banner', t("Banner/Logo"), $banner, ""), '$admininfo' => array('admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode can be used here")), '$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices), '$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - change theme settings"), $theme_choices), '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile_theme'), t("Theme for mobile devices"), $theme_choices_mobile), // '$site_channel' => array('site_channel', t("Channel to use for this website's static pages"), get_config('system','site_channel'), t("Site Channel")), '$feed_contacts' => array('feed_contacts', t('Allow Feeds as Connections'),get_config('system','feed_contacts'),t('(Heavy system resource usage)')), '$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")), '$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices), '$invite_only' => array('invite_only', t("Invitation only"), get_config('system','invitation_only'), t("Only allow new member registrations with an invitation code. Above register policy must be set to Yes.")), '$access_policy' => array('access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system','access_policy'), "This is displayed on the public server site list.", $access_choices), '$register_text' => array('register_text', t("Register text"), htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")), '$frontpage' => array('frontpage', t("Site homepage to show visitors (default: login box)"), get_config('system','frontpage'), t("example: 'public' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file.")), '$mirror_frontpage' => array('mirror_frontpage', t("Preserve site homepage URL"), get_config('system','mirror_frontpage'), t('Present the site homepage in a frame at the original location instead of redirecting')), '$abandon_days' => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')), '$allowed_sites' => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")), '$verify_email' => array('verify_email', t("Verify Email Addresses"), get_config('system','verify_email'), t("Check to verify email addresses used in account registration (recommended).")), '$force_publish' => array('publish_all', t("Force publish"), get_config('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")), '$disable_discover_tab' => array('disable_discover_tab', t('Import Public Streams'), $discover_tab, t('Import and allow access to public content pulled from other sites. Warning: this content is unmoderated.')), '$login_on_homepage' => array('login_on_homepage', t("Login on Homepage"),((intval($homelogin) || $homelogin === false) ? 1 : '') , t("Present a login box to visitors on the home page if no other content has been configured.")), '$enable_context_help' => array('enable_context_help', t("Enable context help"),((intval($enable_context_help) === 1 || $enable_context_help === false) ? 1 : 0) , t("Display contextual help for the current page when the help button is pressed.")), '$directory_server' => (($dir_choices) ? array('directory_server', t("Directory Server URL"), get_config('system','directory_server'), t("Default directory server"), $dir_choices) : null), '$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""), '$proxy' => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""), '$timeout' => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")), '$delivery_interval' => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")), '$delivery_batch_count' => array('delivery_batch_count', t('Deliveries per process'),(x(get_config('system','delivery_batch_count'))?get_config('system','delivery_batch_count'):1), t("Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5.")), '$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")), '$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")), '$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')), '$form_security_token' => get_form_security_token("admin_site"), )); } function admin_page_features_post(&$a) { check_form_security_token_redirectOnErr('/admin/features', 'admin_manage_features'); logger('postvars: ' . print_r($_POST,true)); $arr = array(); $features = get_features(false); foreach($features as $fname => $fdata) { foreach(array_slice($fdata,1) as $f) { $feature = $f[0]; if(array_key_exists('feature_' . $feature,$_POST)) $val = intval($_POST['feature_' . $feature]); else $val = 0; set_config('feature',$feature,$val); if(array_key_exists('featurelock_' . $feature,$_POST)) set_config('feature_lock',$feature,$val); else del_config('feature_lock',$feature); } } goaway(z_root() . '/admin/features' ); } function admin_page_features(&$a) { if((argc() > 1) && (argv(1) === 'features')) { $arr = array(); $features = get_features(false); foreach($features as $fname => $fdata) { $arr[$fname] = array(); $arr[$fname][0] = $fdata[0]; foreach(array_slice($fdata,1) as $f) { $set = get_config('feature',$f[0]); if($set === false) $set = $f[3]; $arr[$fname][1][] = array( array('feature_' .$f[0],$f[1],$set,$f[2],array(t('Off'),t('On'))), array('featurelock_' .$f[0],sprintf( t('Lock feature %s'),$f[1]),(($f[4] !== false) ? 1 : 0),'',array(t('Off'),t('On'))) ); } } $tpl = get_markup_template("admin_settings_features.tpl"); $o .= replace_macros($tpl, array( '$form_security_token' => get_form_security_token("admin_manage_features"), '$title' => t('Manage Additional Features'), '$features' => $arr, '$submit' => t('Submit'), )); return $o; } } function admin_page_dbsync(&$a) { $o = ''; if(argc() > 3 && intval(argv(3)) && argv(2) === 'mark') { set_config('database', 'update_r' . intval(argv(3)), 'success'); if(intval(get_config('system','db_version')) <= intval(argv(3))) set_config('system','db_version',intval(argv(3)) + 1); info( t('Update has been marked successful') . EOL); goaway(z_root() . '/admin/dbsync'); } if(argc() > 2 && intval(argv(2))) { require_once('install/update.php'); $func = 'update_r' . intval(argv(2)); if(function_exists($func)) { $retval = $func(); if($retval === UPDATE_FAILED) { $o .= sprintf( t('Executing %s failed. Check system logs.'), $func); } elseif($retval === UPDATE_SUCCESS) { $o .= sprintf( t('Update %s was successfully applied.'), $func); set_config('database',$func, 'success'); } else $o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $func); } else $o .= sprintf( t('Update function %s could not be found.'), $func); return $o; } $failed = array(); $r = q("select * from config where `cat` = 'database' "); if(count($r)) { foreach($r as $rr) { $upd = intval(substr($rr['k'],8)); if($rr['v'] === 'success') continue; $failed[] = $upd; } } if(! count($failed)) return '

' . t('No failed updates.') . '

'; $o = replace_macros(get_markup_template('failed_updates.tpl'),array( '$base' => z_root(), '$banner' => t('Failed Updates'), '$desc' => '', '$mark' => t('Mark success (if update was manually applied)'), '$apply' => t('Attempt to execute this update step automatically'), '$failed' => $failed )); return $o; } function admin_page_queue($a) { $o = ''; $expert = ((array_key_exists('expert',$_REQUEST)) ? intval($_REQUEST['expert']) : 0); if($_REQUEST['drophub']) { require_once('hubloc.php'); hubloc_mark_as_down($_REQUEST['drophub']); remove_queue_by_posturl($_REQUEST['drophub']); } if($_REQUEST['emptyhub']) { remove_queue_by_posturl($_REQUEST['emptyhub']); } $r = q("select count(outq_posturl) as total, max(outq_priority) as priority, outq_posturl from outq where outq_delivered = 0 group by outq_posturl order by total desc"); for($x = 0; $x < count($r); $x ++) { $r[$x]['eurl'] = urlencode($r[$x]['outq_posturl']); $r[$x]['connected'] = datetime_convert('UTC',date_default_timezone_get(),$r[$x]['connected'],'Y-m-d'); } $o = replace_macros(get_markup_template('admin_queue.tpl'), array( '$banner' => t('Queue Statistics'), '$numentries' => t('Total Entries'), '$priority' => t('Priority'), '$desturl' => t('Destination URL'), '$nukehub' => t('Mark hub permanently offline'), '$empty' => t('Empty queue for this hub'), '$lastconn' => t('Last known contact'), '$hasentries' => ((count($r)) ? true : false), '$entries' => $r, '$expert' => $expert )); return $o; } /** * @brief Handle POST actions on accounts admin page. * * This function is called when on the admin user/account page the form was * submitted to handle multiple operations at once. If one of the icons next * to an entry are pressed the function admin_page_accounts() will handle this. * * @param App $a */ function admin_page_accounts_post($a) { $pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() ); $users = ( x($_POST, 'user') ? $_POST['user'] : array() ); $blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() ); check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts'); // change to switch structure? // account block/unblock button was submitted if (x($_POST, 'page_users_block')) { for ($i = 0; $i < count($users); $i++) { // if account is blocked remove blocked bit-flag, otherwise add blocked bit-flag $op = ($blocked[$i]) ? '& ~' : '| '; q("UPDATE account SET account_flags = (account_flags $op%d) WHERE account_id = %d", intval(ACCOUNT_BLOCKED), intval($users[$i]) ); } notice( sprintf( tt("%s account blocked/unblocked", "%s account blocked/unblocked", count($users)), count($users)) ); } // account delete button was submitted if (x($_POST, 'page_accounts_delete')) { foreach ($users as $uid){ account_remove($uid, true, false); } notice( sprintf( tt("%s account deleted", "%s accounts deleted", count($users)), count($users)) ); } // registration approved button was submitted if (x($_POST, 'page_users_approve')) { foreach ($pending as $hash) { account_allow($hash); } } // registration deny button was submitted if (x($_POST, 'page_users_deny')) { foreach ($pending as $hash) { account_deny($hash); } } goaway(z_root() . '/admin/accounts' ); } /** * @brief Generate accounts admin page and handle single item operations. * * This function generates the accounts/account admin page and handles the actions * if an icon next to an entry was clicked. If several items were selected and * the form was submitted it is handled by the function admin_page_accounts_post(). * * @param App &$a * @return string */ function admin_page_accounts(&$a){ if (argc() > 2) { $uid = argv(3); $account = q("SELECT * FROM account WHERE account_id = %d", intval($uid) ); if (! $account) { notice( t('Account not found') . EOL); goaway(z_root() . '/admin/accounts' ); } check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't'); switch (argv(2)){ case 'delete': // delete user account_remove($uid,true,false); notice( sprintf(t("Account '%s' deleted"), $account[0]['account_email']) . EOL); break; case 'block': q("UPDATE account SET account_flags = ( account_flags | %d ) WHERE account_id = %d", intval(ACCOUNT_BLOCKED), intval($uid) ); notice( sprintf( t("Account '%s' blocked") , $account[0]['account_email']) . EOL); break; case 'unblock': q("UPDATE account SET account_flags = ( account_flags & ~%d ) WHERE account_id = %d", intval(ACCOUNT_BLOCKED), intval($uid) ); notice( sprintf( t("Account '%s' unblocked"), $account[0]['account_email']) . EOL); break; } goaway(z_root() . '/admin/accounts' ); } /* get pending */ $pending = q("SELECT account.*, register.hash from account left join register on account_id = register.uid where (account_flags & %d )>0 ", intval(ACCOUNT_PENDING) ); /* get accounts */ $total = q("SELECT count(*) as total FROM account"); if (count($total)) { \App::set_pager_total($total[0]['total']); \App::set_pager_itemspage(100); } $serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : ''); $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id'); $dir = 'asc'; if(array_key_exists('dir',$_REQUEST)) $dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc'); $base = z_root() . '/admin/accounts?f='; $odir = (($dir === 'asc') ? '0' : '1'); $users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . "`account_service_class`, ( account_flags & %d ) > 0 as `blocked`, " . "(SELECT %s FROM channel as ch " . "WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as `channels` " . "FROM account as ac where true $serviceclass order by $key $dir limit %d offset %d ", intval(ACCOUNT_BLOCKED), db_concat('ch.channel_address', ' '), intval(\App::$pager['itemspage']), intval(\App::$pager['start']) ); // function _setup_users($e){ // $accounts = Array( // t('Normal Account'), // t('Soapbox Account'), // t('Community/Celebrity Account'), // t('Automatic Friend Account') // ); // $e['page_flags'] = $accounts[$e['page-flags']]; // $e['register_date'] = relative_date($e['register_date']); // $e['login_date'] = relative_date($e['login_date']); // $e['lastitem_date'] = relative_date($e['lastitem_date']); // return $e; // } // $users = array_map("_setup_users", $users); $t = get_markup_template('admin_accounts.tpl'); $o = replace_macros($t, array( // strings // '$title' => t('Administration'), '$page' => t('Accounts'), '$submit' => t('Submit'), '$select_all' => t('select all'), '$h_pending' => t('Registrations waiting for confirm'), '$th_pending' => array( t('Request date'), t('Email') ), '$no_pending' => t('No registrations.'), '$approve' => t('Approve'), '$deny' => t('Deny'), '$delete' => t('Delete'), '$block' => t('Block'), '$unblock' => t('Unblock'), '$odir' => $odir, '$base' => $base, '$h_users' => t('Accounts'), '$th_users' => array( [ t('ID'), 'account_id' ], [ t('Email'), 'account_email' ], [ t('All Channels'), 'channels' ], [ t('Register date'), 'account_created' ], [ t('Last login'), 'account_lastlog' ], [ t('Expires'), 'account_expires' ], [ t('Service Class'), 'account_service_class'] ), '$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'), '$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'), '$form_security_token' => get_form_security_token("admin_accounts"), // values // '$baseurl' => z_root(), '$pending' => $pending, '$users' => $users, )); $o .= paginate($a); return $o; } /** * @brief Channels admin page. * * @param App &$a */ function admin_page_channels_post(&$a) { $channels = ( x($_POST, 'channel') ? $_POST['channel'] : Array() ); check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels'); $xor = db_getfunc('^'); if (x($_POST,'page_channels_block')){ foreach($channels as $uid){ q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d", intval(PAGE_CENSORED), intval( $uid ) ); \Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush')); } notice( sprintf( tt("%s channel censored/uncensored", "%s channels censored/uncensored", count($channels)), count($channels)) ); } if (x($_POST,'page_channels_code')){ foreach($channels as $uid){ q("UPDATE channel SET channel_pageflags = ( channel_pageflags $xor %d ) where channel_id = %d", intval(PAGE_ALLOWCODE), intval( $uid ) ); } notice( sprintf( tt("%s channel code allowed/disallowed", "%s channels code allowed/disallowed", count($channels)), count($channels)) ); } if (x($_POST,'page_channels_delete')){ foreach($channels as $uid){ channel_remove($uid,true); } notice( sprintf( tt("%s channel deleted", "%s channels deleted", count($channels)), count($channels)) ); } goaway(z_root() . '/admin/channels' ); } /** * @brief * * @param App &$a * @return string */ function admin_page_channels(&$a){ if (argc() > 2) { $uid = argv(3); $channel = q("SELECT * FROM channel WHERE channel_id = %d", intval($uid) ); if (! $channel) { notice( t('Channel not found') . EOL); goaway(z_root() . '/admin/channels' ); } switch(argv(2)) { case "delete":{ check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't'); // delete channel channel_remove($uid,true); notice( sprintf(t("Channel '%s' deleted"), $channel[0]['channel_name']) . EOL); }; break; case "block":{ check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't'); $pflags = $channel[0]['channel_pageflags'] ^ PAGE_CENSORED; q("UPDATE channel SET channel_pageflags = %d where channel_id = %d", intval($pflags), intval( $uid ) ); \Zotlabs\Daemon\Master::Summon(array('Directory',$uid,'nopush')); notice( sprintf( (($pflags & PAGE_CENSORED) ? t("Channel '%s' censored"): t("Channel '%s' uncensored")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL); }; break; case "code":{ check_form_security_token_redirectOnErr('/admin/channels', 'admin_channels', 't'); $pflags = $channel[0]['channel_pageflags'] ^ PAGE_ALLOWCODE; q("UPDATE channel SET channel_pageflags = %d where channel_id = %d", intval($pflags), intval( $uid ) ); notice( sprintf( (($pflags & PAGE_ALLOWCODE) ? t("Channel '%s' code allowed"): t("Channel '%s' code disallowed")) , $channel[0]['channel_name'] . ' (' . $channel[0]['channel_address'] . ')' ) . EOL); }; break; default: break; } goaway(z_root() . '/admin/channels' ); } $key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id'); $dir = 'asc'; if(array_key_exists('dir',$_REQUEST)) $dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc'); $base = z_root() . '/admin/channels?f='; $odir = (($dir === 'asc') ? '0' : '1'); /* get channels */ $total = q("SELECT count(*) as total FROM channel where channel_removed = 0 and channel_system = 0"); if($total) { \App::set_pager_total($total[0]['total']); \App::set_pager_itemspage(100); } $channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 order by $key $dir limit %d offset %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']) ); if($channels) { for($x = 0; $x < count($channels); $x ++) { if($channels[$x]['channel_pageflags'] & PAGE_CENSORED) $channels[$x]['blocked'] = true; else $channels[$x]['blocked'] = false; if($channels[$x]['channel_pageflags'] & PAGE_ALLOWCODE) $channels[$x]['allowcode'] = true; else $channels[$x]['allowcode'] = false; } } $t = get_markup_template("admin_channels.tpl"); $o = replace_macros($t, array( // strings // '$title' => t('Administration'), '$page' => t('Channels'), '$submit' => t('Submit'), '$select_all' => t('select all'), '$delete' => t('Delete'), '$block' => t('Censor'), '$unblock' => t('Uncensor'), '$code' => t('Allow Code'), '$uncode' => t('Disallow Code'), '$h_channels' => t('Channel'), '$base' => $base, '$odir' => $odir, '$th_channels' => array( [ t('UID'), 'channel_id' ], [ t('Name'), 'channel_name' ], [ t('Address'), 'channel_address' ]), '$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'), '$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'), '$form_security_token' => get_form_security_token("admin_channels"), // values // '$baseurl' => z_root(), '$channels' => $channels, )); $o .= paginate($a); return $o; } /** * @param array $themes * @param string $th * @param int $result */ function toggle_theme(&$themes, $th, &$result) { for($x = 0; $x < count($themes); $x ++) { if($themes[$x]['name'] === $th) { if($themes[$x]['allowed']) { $themes[$x]['allowed'] = 0; $result = 0; } else { $themes[$x]['allowed'] = 1; $result = 1; } } } } /** * @param array $themes * @param string $th * @return int */ function theme_status($themes, $th) { for($x = 0; $x < count($themes); $x ++) { if($themes[$x]['name'] === $th) { if($themes[$x]['allowed']) { return 1; } else { return 0; } } } return 0; } /** * @param array $themes * @return string */ function rebuild_theme_table($themes) { $o = ''; if(count($themes)) { foreach($themes as $th) { if($th['allowed']) { if(strlen($o)) $o .= ','; $o .= $th['name']; } } } return $o; } /** * @brief Themes admin page. * * @param App &$a * @return string */ function admin_page_themes(&$a){ $allowed_themes_str = get_config('system', 'allowed_themes'); $allowed_themes_raw = explode(',', $allowed_themes_str); $allowed_themes = array(); if(count($allowed_themes_raw)) foreach($allowed_themes_raw as $x) if(strlen(trim($x))) $allowed_themes[] = trim($x); $themes = array(); $files = glob('view/theme/*'); if($files) { foreach($files as $file) { $f = basename($file); $is_experimental = intval(file_exists($file . '/.experimental')); $is_supported = 1-(intval(file_exists($file . '/.unsupported'))); // Is not used yet $is_allowed = intval(in_array($f,$allowed_themes)); $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed); } } if(! count($themes)) { notice( t('No themes found.')); return ''; } /* * Single theme */ if (\App::$argc == 3){ $theme = \App::$argv[2]; if(! is_dir("view/theme/$theme")){ notice( t("Item not found.") ); return ''; } if (x($_GET,"a") && $_GET['a']=="t"){ check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't'); // Toggle theme status $this->toggle_theme($themes, $theme, $result); $s = $this->rebuild_theme_table($themes); if($result) info( sprintf('Theme %s enabled.', $theme)); else info( sprintf('Theme %s disabled.', $theme)); set_config('system', 'allowed_themes', $s); goaway(z_root() . '/admin/themes' ); } // display theme details require_once('library/markdown.php'); if ($this->theme_status($themes,$theme)) { $status="on"; $action= t("Disable"); } else { $status="off"; $action= t("Enable"); } $readme=Null; if (is_file("view/theme/$theme/README.md")){ $readme = file_get_contents("view/theme/$theme/README.md"); $readme = Markdown($readme); } else if (is_file("view/theme/$theme/README")){ $readme = "
". file_get_contents("view/theme/$theme/README") ."
"; } $admin_form = ''; if (is_file("view/theme/$theme/php/config.php")){ require_once("view/theme/$theme/php/config.php"); if(function_exists("theme_admin")){ $admin_form = theme_admin($a); } } $screenshot = array( get_theme_screenshot($theme), t('Screenshot')); if(! stristr($screenshot[0],$theme)) $screenshot = null; $t = get_markup_template('admin_plugins_details.tpl'); return replace_macros($t, array( '$title' => t('Administration'), '$page' => t('Themes'), '$toggle' => t('Toggle'), '$settings' => t('Settings'), '$baseurl' => z_root(), '$plugin' => $theme, '$status' => $status, '$action' => $action, '$info' => get_theme_info($theme), '$function' => 'themes', '$admin_form' => $admin_form, '$str_author' => t('Author: '), '$str_maintainer' => t('Maintainer: '), '$screenshot' => $screenshot, '$readme' => $readme, '$form_security_token' => get_form_security_token('admin_themes'), )); } /* * List themes */ $xthemes = array(); if($themes) { foreach($themes as $th) { $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name'])); } } $t = get_markup_template('admin_plugins.tpl'); return replace_macros($t, array( '$title' => t('Administration'), '$page' => t('Themes'), '$submit' => t('Submit'), '$baseurl' => z_root(), '$function' => 'themes', '$plugins' => $xthemes, '$experimental' => t('[Experimental]'), '$unsupported' => t('[Unsupported]'), '$form_security_token' => get_form_security_token('admin_themes'), )); } /** * @brief POST handler for logs admin page. * * @param App &$a */ function admin_page_logs_post(&$a) { if (x($_POST, 'page_logs')) { check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs'); $logfile = ((x($_POST,'logfile')) ? notags(trim($_POST['logfile'])) : ''); $debugging = ((x($_POST,'debugging')) ? true : false); $loglevel = ((x($_POST,'loglevel')) ? intval(trim($_POST['loglevel'])) : 0); set_config('system','logfile', $logfile); set_config('system','debugging', $debugging); set_config('system','loglevel', $loglevel); } info( t('Log settings updated.') ); goaway(z_root() . '/admin/logs' ); } /** * @brief Logs admin page. * * @param App $a * @return string */ function admin_page_logs(&$a){ $log_choices = Array( LOGGER_NORMAL => 'Normal', LOGGER_TRACE => 'Trace', LOGGER_DEBUG => 'Debug', LOGGER_DATA => 'Data', LOGGER_ALL => 'All' ); $t = get_markup_template('admin_logs.tpl'); $f = get_config('system', 'logfile'); $data = ''; if(!file_exists($f)) { $data = t("Error trying to open $f log file.\r\n
Check to see if file $f exist and is readable."); } else { $fp = fopen($f, 'r'); if(!$fp) { $data = t("Couldn't open $f log file.\r\n
Check to see if file $f is readable."); } else { $fstat = fstat($fp); $size = $fstat['size']; if($size != 0) { if($size > 5000000 || $size < 0) $size = 5000000; $seek = fseek($fp,0-$size,SEEK_END); if($seek === 0) { $data = escape_tags(fread($fp,$size)); while(! feof($fp)) $data .= escape_tags(fread($fp,4096)); } } fclose($fp); } } return replace_macros($t, array( '$title' => t('Administration'), '$page' => t('Logs'), '$submit' => t('Submit'), '$clear' => t('Clear'), '$data' => $data, '$baseurl' => z_root(), '$logname' => get_config('system','logfile'), // name, label, value, help string, extra data... '$debugging' => array('debugging', t("Debugging"),get_config('system','debugging'), ""), '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your top-level webserver directory.")), '$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices), '$form_security_token' => get_form_security_token('admin_logs'), )); } function admin_page_plugins_post($action) { switch ($action) { case 'updaterepo': if (array_key_exists('repoName', $_REQUEST)) { $repoName = $_REQUEST['repoName']; } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend'; $addonDir = $extendDir . '/addon'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); } else { if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { logger('Error creating symlink to addon folder: ' . $addonDir); json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); } } } $repoDir = __DIR__ . '/../../store/[data]/git/sys/extend/addon/' . $repoName; if (!is_dir($repoDir)) { logger('Repo directory does not exist: ' . $repoDir); json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); } if (!is_writable($repoDir)) { logger('Repo directory not writable to web server: ' . $repoDir); json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); } $git = new GitRepo('sys', null, false, $repoName, $repoDir); try { if ($git->pull()) { $files = array_diff(scandir($repoDir), array('.', '..')); foreach ($files as $file) { if (is_dir($repoDir . '/' . $file) && $file !== '.git') { $source = '../extend/addon/' . $repoName . '/' . $file; $target = realpath(__DIR__ . '/../../addon/') . '/' . $file; unlink($target); if (!symlink($source, $target)) { logger('Error linking addons to /addon'); json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); } } } json_return_and_die(array('message' => 'Repo updated.', 'success' => true)); } else { json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); } } catch (\PHPGit\Exception\GitException $e) { json_return_and_die(array('message' => 'Error updating addon repo.', 'success' => false)); } case 'removerepo': if (array_key_exists('repoName', $_REQUEST)) { $repoName = $_REQUEST['repoName']; } else { json_return_and_die(array('message' => 'No repo name provided.', 'success' => false)); } $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend'; $addonDir = $extendDir . '/addon'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); } else { if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { logger('Error creating symlink to addon folder: ' . $addonDir); json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); } } } $repoDir = __DIR__ . '/../../store/[data]/git/sys/extend/addon/' . $repoName; if (!is_dir($repoDir)) { logger('Repo directory does not exist: ' . $repoDir); json_return_and_die(array('message' => 'Invalid addon repo.', 'success' => false)); } if (!is_writable($repoDir)) { logger('Repo directory not writable to web server: ' . $repoDir); json_return_and_die(array('message' => 'Repo directory not writable to web server.', 'success' => false)); } // TODO: remove directory and unlink /addon/files if (rrmdir($repoDir)) { json_return_and_die(array('message' => 'Repo deleted.', 'success' => true)); } else { json_return_and_die(array('message' => 'Error deleting addon repo.', 'success' => false)); } case 'installrepo': require_once('library/markdown.php'); if (array_key_exists('repoURL', $_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend'; $addonDir = $extendDir . '/addon'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); } else { if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { logger('Error creating symlink to addon folder: ' . $addonDir); json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); } } } if (!is_writable($extendDir)) { logger('Directory not writable to web server: ' . $extendDir); json_return_and_die(array('message' => 'Directory not writable to web server.', 'success' => false)); } $repoName = null; if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { $repoName = $_REQUEST['repoName']; } else { $repoName = GitRepo::getRepoNameFromURL($repoURL); } if (!$repoName) { logger('Invalid git repo'); json_return_and_die(array('message' => 'Invalid git repo', 'success' => false)); } $repoDir = $addonDir . '/' . $repoName; $tempRepoBaseDir = __DIR__ . '/../../store/[data]/git/sys/temp/'; $tempAddonDir = $tempRepoBaseDir . $repoName; if (!is_writable($addonDir) || !is_writable($tempAddonDir)) { logger('Temp repo directory or /extend/addon not writable to web server: ' . $tempAddonDir); json_return_and_die(array('message' => 'Temp repo directory not writable to web server.', 'success' => false)); } rename($tempAddonDir, $repoDir); if (!is_writable(realpath(__DIR__ . '/../../addon/'))) { logger('/addon directory not writable to web server: ' . $tempAddonDir); json_return_and_die(array('message' => '/addon directory not writable to web server.', 'success' => false)); } $files = array_diff(scandir($repoDir), array('.', '..')); foreach ($files as $file) { if (is_dir($repoDir . '/' . $file) && $file !== '.git') { $source = '../extend/addon/' . $repoName . '/' . $file; $target = realpath(__DIR__ . '/../../addon/') . '/' . $file; unlink($target); if (!symlink($source, $target)) { logger('Error linking addons to /addon'); json_return_and_die(array('message' => 'Error linking addons to /addon', 'success' => false)); } } } $git = new GitRepo('sys', $repoURL, false, $repoName, $repoDir); $repo = $git->probeRepo(); json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); } case 'addrepo': require_once('library/markdown.php'); if (array_key_exists('repoURL', $_REQUEST)) { require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies $repoURL = $_REQUEST['repoURL']; $extendDir = __DIR__ . '/../../store/[data]/git/sys/extend'; $addonDir = $extendDir . '/addon'; $tempAddonDir = __DIR__ . '/../../store/[data]/git/sys/temp'; if (!file_exists($extendDir)) { if (!mkdir($extendDir, 0770, true)) { logger('Error creating extend folder: ' . $extendDir); json_return_and_die(array('message' => 'Error creating extend folder: ' . $extendDir, 'success' => false)); } else { if (!symlink(__DIR__ . '/../../extend/addon', $addonDir)) { logger('Error creating symlink to addon folder: ' . $addonDir); json_return_and_die(array('message' => 'Error creating symlink to addon folder: ' . $addonDir, 'success' => false)); } } } if (!is_dir($tempAddonDir)) { if (!mkdir($tempAddonDir, 0770, true)) { logger('Error creating temp plugin repo folder: ' . $tempAddonDir); json_return_and_die(array('message' => 'Error creating temp plugin repo folder: ' . $tempAddonDir, 'success' => false)); } } $repoName = null; if (array_key_exists('repoName', $_REQUEST) && $_REQUEST['repoName'] !== '') { $repoName = $_REQUEST['repoName']; } else { $repoName = GitRepo::getRepoNameFromURL($repoURL); } if (!$repoName) { logger('Invalid git repo'); json_return_and_die(array('message' => 'Invalid git repo: ' . $repoName, 'success' => false)); } $repoDir = $tempAddonDir . '/' . $repoName; if (!is_writable($tempAddonDir)) { logger('Temporary directory for new addon repo is not writable to web server: ' . $tempAddonDir); json_return_and_die(array('message' => 'Temporary directory for new addon repo is not writable to web server.', 'success' => false)); } // clone the repo if new automatically $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); $remotes = $git->git->remote(); $fetchURL = $remotes['origin']['fetch']; if ($fetchURL !== $git->url) { if (rrmdir($repoDir)) { $git = new GitRepo('sys', $repoURL, true, $repoName, $repoDir); } else { json_return_and_die(array('message' => 'Error deleting existing addon repo.', 'success' => false)); } } $repo = $git->probeRepo(); $repo['readme'] = $repo['manifest'] = null; foreach ($git->git->tree('master') as $object) { if ($object['type'] == 'blob' && (strtolower($object['file']) === 'readme.md' || strtolower($object['file']) === 'readme')) { $repo['readme'] = Markdown($git->git->cat->blob($object['hash'])); } else if ($object['type'] == 'blob' && strtolower($object['file']) === 'manifest.json') { $repo['manifest'] = $git->git->cat->blob($object['hash']); } } json_return_and_die(array('repo' => $repo, 'message' => '', 'success' => true)); } else { json_return_and_die(array('message' => 'No repo URL provided', 'success' => false)); } break; default: break; } } function admin_page_profs_post(&$a) { if(array_key_exists('basic',$_REQUEST)) { $arr = explode(',',$_REQUEST['basic']); for($x = 0; $x < count($arr); $x ++) if(trim($arr[$x])) $arr[$x] = trim($arr[$x]); set_config('system','profile_fields_basic',$arr); if(array_key_exists('advanced',$_REQUEST)) { $arr = explode(',',$_REQUEST['advanced']); for($x = 0; $x < count($arr); $x ++) if(trim($arr[$x])) $arr[$x] = trim($arr[$x]); set_config('system','profile_fields_advanced',$arr); } goaway(z_root() . '/admin/profs'); } if(array_key_exists('field_name',$_REQUEST)) { if($_REQUEST['id']) { $r = q("update profdef set field_name = '%s', field_type = '%s', field_desc = '%s' field_help = '%s', field_inputs = '%s' where id = %d", dbesc($_REQUEST['field_name']), dbesc($_REQUEST['field_type']), dbesc($_REQUEST['field_desc']), dbesc($_REQUEST['field_help']), dbesc($_REQUEST['field_inputs']), intval($_REQUEST['id']) ); } else { $r = q("insert into profdef ( field_name, field_type, field_desc, field_help, field_inputs ) values ( '%s' , '%s', '%s', '%s', '%s' )", dbesc($_REQUEST['field_name']), dbesc($_REQUEST['field_type']), dbesc($_REQUEST['field_desc']), dbesc($_REQUEST['field_help']), dbesc($_REQUEST['field_inputs']) ); } } // add to chosen array basic or advanced goaway(z_root() . '/admin/profs'); } function admin_page_profs(&$a) { if((argc() > 3) && argv(2) == 'drop' && intval(argv(3))) { $r = q("delete from profdef where id = %d", intval(argv(3)) ); // remove from allowed fields goaway(z_root() . '/admin/profs'); } if((argc() > 2) && argv(2) === 'new') { return replace_macros(get_markup_template('profdef_edit.tpl'),array( '$header' => t('New Profile Field'), '$field_name' => array('field_name',t('Field nickname'),$_REQUEST['field_name'],t('System name of field')), '$field_type' => array('field_type',t('Input type'),(($_REQUEST['field_type']) ? $_REQUEST['field_type'] : 'text'),''), '$field_desc' => array('field_desc',t('Field Name'),$_REQUEST['field_desc'],t('Label on profile pages')), '$field_help' => array('field_help',t('Help text'),$_REQUEST['field_help'],t('Additional info (optional)')), '$submit' => t('Save') )); } if((argc() > 2) && intval(argv(2))) { $r = q("select * from profdef where id = %d limit 1", intval(argv(2)) ); if(! $r) { notice( t('Field definition not found') . EOL); goaway(z_root() . '/admin/profs'); } return replace_macros(get_markup_template('profdef_edit.tpl'),array( '$id' => intval($r[0]['id']), '$header' => t('Edit Profile Field'), '$field_name' => array('field_name',t('Field nickname'),$r[0]['field_name'],t('System name of field')), '$field_type' => array('field_type',t('Input type'),$r[0]['field_type'],''), '$field_desc' => array('field_desc',t('Field Name'),$r[0]['field_desc'],t('Label on profile pages')), '$field_help' => array('field_help',t('Help text'),$r[0]['field_help'],t('Additional info (optional)')), '$submit' => t('Save') )); } $basic = ''; $barr = array(); $fields = get_profile_fields_basic(); if(! $fields) $fields = get_profile_fields_basic(1); if($fields) { foreach($fields as $k => $v) { if($basic) $basic .= ', '; $basic .= trim($k); $barr[] = trim($k); } } $advanced = ''; $fields = get_profile_fields_advanced(); if(! $fields) $fields = get_profile_fields_advanced(1); if($fields) { foreach($fields as $k => $v) { if(in_array(trim($k),$barr)) continue; if($advanced) $advanced .= ', '; $advanced .= trim($k); } } $all = ''; $fields = get_profile_fields_advanced(1); if($fields) { foreach($fields as $k => $v) { if($all) $all .= ', '; $all .= trim($k); } } $r = q("select * from profdef where true"); if($r) { foreach($r as $rr) { if($all) $all .= ', '; $all .= $rr['field_name']; } } $o = replace_macros(get_markup_template('admin_profiles.tpl'),array( '$title' => t('Profile Fields'), '$basic' => array('basic',t('Basic Profile Fields'),$basic,''), '$advanced' => array('advanced',t('Advanced Profile Fields'),$advanced,t('(In addition to basic fields)')), '$all' => $all, '$all_desc' => t('All available fields'), '$cust_field_desc' => t('Custom Fields'), '$cust_fields' => $r, '$edit' => t('Edit'), '$drop' => t('Delete'), '$new' => t('Create Custom Field'), '$submit' => t('Submit') )); return $o; } }