6 require_once("include/remoteupdate.php");
12 function admin_post(&$a){
15 if(!is_site_admin()) {
19 // do not allow a page manager to access the admin panel at all.
21 if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
30 admin_page_site_post($a);
33 admin_page_users_post($a);
37 is_file("addon/".$a->argv[2]."/".$a->argv[2].".php")){
38 @include_once("addon/".$a->argv[2]."/".$a->argv[2].".php");
39 if(function_exists($a->argv[2].'_plugin_admin_post')) {
40 $func = $a->argv[2].'_plugin_admin_post';
44 goaway($a->get_baseurl(true) . '/admin/plugins/' . $a->argv[2] );
49 if (is_file("view/theme/$theme/config.php")){
50 require_once("view/theme/$theme/config.php");
51 if (function_exists("theme_admin_post")){
55 info(t('Theme settings updated.'));
58 goaway($a->get_baseurl(true) . '/admin/themes/' . $theme );
62 admin_page_logs_post($a);
65 admin_page_dbsync_post($a);
68 admin_page_remoteupdate_post($a);
73 goaway($a->get_baseurl(true) . '/admin' );
81 function admin_content(&$a) {
83 if(!is_site_admin()) {
87 if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
94 // array( url, name, extra css classes )
96 'site' => Array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"),
97 'users' => Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"),
98 'plugins'=> Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
99 'themes' => Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
100 'dbsync' => Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
101 //'update' => Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
104 /* get plugins admin page */
106 $r = q("SELECT * FROM `addon` WHERE `plugin_admin`=1");
107 $aside['plugins_admin']=Array();
110 $aside['plugins_admin'][] = Array($a->get_baseurl(true)."/admin/plugins/".$plugin, $plugin, "plugin");
111 // temp plugins with admin
112 $a->plugins_admin[] = $plugin;
115 $aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
117 $t = get_markup_template("admin_aside.tpl");
118 $a->page['aside'] .= replace_macros( $t, array(
120 '$admtxt' => t('Admin'),
121 '$plugadmtxt' => t('Plugin Features'),
122 '$logtxt' => t('Logs'),
123 '$h_pending' => t('User registrations waiting for confirmation'),
124 '$admurl'=> $a->get_baseurl(true)."/admin/"
135 switch ($a->argv[1]){
137 $o = admin_page_site($a);
140 $o = admin_page_users($a);
143 $o = admin_page_plugins($a);
146 $o = admin_page_themes($a);
149 $o = admin_page_logs($a);
152 $o = admin_page_dbsync($a);
155 $o = admin_page_remoteupdate($a);
158 notice( t("Item not found.") );
161 $o = admin_page_summary($a);
179 function admin_page_summary(&$a) {
180 $r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
182 Array( t('Normal Account'), 0),
183 Array( t('Soapbox Account'), 0),
184 Array( t('Community/Celebrity Account'), 0),
185 Array( t('Automatic Friend Account'), 0),
186 Array( t('Blog Account'), 0),
187 Array( t('Private Forum'), 0)
191 foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; }
193 logger('accounts: ' . print_r($accounts,true),LOGGER_DATA);
195 $r = q("SELECT COUNT(id) as `count` FROM `register`");
196 $pending = $r[0]['count'];
198 $r = q("select count(*) as total from deliverq where 1");
199 $deliverq = (($r) ? $r[0]['total'] : 0);
201 $r = q("select count(*) as total from queue where 1");
202 $queue = (($r) ? $r[0]['total'] : 0);
204 // We can do better, but this is a quick queue status
206 $queues = array( 'label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue );
209 $t = get_markup_template("admin_summary.tpl");
210 return replace_macros($t, array(
211 '$title' => t('Administration'),
212 '$page' => t('Summary'),
213 '$queues' => $queues,
214 '$users' => Array( t('Registered users'), $users),
215 '$accounts' => $accounts,
216 '$pending' => Array( t('Pending registrations'), $pending),
217 '$version' => Array( t('Version'), FRIENDICA_VERSION),
218 '$build' => get_config('system','build'),
219 '$plugins' => Array( t('Active plugins'), $a->plugins )
228 function admin_page_site_post(&$a){
229 if (!x($_POST,"page_site")){
233 check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
235 $sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : '');
236 $banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false);
237 $language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : '');
238 $theme = ((x($_POST,'theme')) ? notags(trim($_POST['theme'])) : '');
239 $theme_mobile = ((x($_POST,'theme_mobile')) ? notags(trim($_POST['theme_mobile'])) : '');
240 $maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
241 $maximagelength = ((x($_POST,'maximagelength')) ? intval(trim($_POST['maximagelength'])) : MAX_IMAGE_LENGTH);
242 $jpegimagequality = ((x($_POST,'jpegimagequality')) ? intval(trim($_POST['jpegimagequality'])) : JPEG_QUALITY);
245 $register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
246 $daily_registrations = ((x($_POST,'max_daily_registrations')) ? intval(trim($_POST['max_daily_registrations'])) :0);
247 $abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
249 $register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : '');
251 $allowed_sites = ((x($_POST,'allowed_sites')) ? notags(trim($_POST['allowed_sites'])) : '');
252 $allowed_email = ((x($_POST,'allowed_email')) ? notags(trim($_POST['allowed_email'])) : '');
253 $block_public = ((x($_POST,'block_public')) ? True : False);
254 $force_publish = ((x($_POST,'publish_all')) ? True : False);
255 $global_directory = ((x($_POST,'directory_submit_url')) ? notags(trim($_POST['directory_submit_url'])) : '');
256 $thread_allow = ((x($_POST,'thread_allow')) ? True : False);
257 $newuser_private = ((x($_POST,'newuser_private')) ? True : False);
258 $enotify_no_content = ((x($_POST,'enotify_no_content')) ? True : False);
259 $private_addons = ((x($_POST,'private_addons')) ? True : False);
260 $disable_embedded = ((x($_POST,'disable_embedded')) ? True : False);
262 $no_multi_reg = ((x($_POST,'no_multi_reg')) ? True : False);
263 $no_openid = !((x($_POST,'no_openid')) ? True : False);
264 $no_regfullname = !((x($_POST,'no_regfullname')) ? True : False);
265 $no_utf = !((x($_POST,'no_utf')) ? True : False);
266 $no_community_page = !((x($_POST,'no_community_page')) ? True : False);
268 $verifyssl = ((x($_POST,'verifyssl')) ? True : False);
269 $proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
270 $proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : '');
271 $timeout = ((x($_POST,'timeout')) ? intval(trim($_POST['timeout'])) : 60);
272 $delivery_interval = ((x($_POST,'delivery_interval')) ? intval(trim($_POST['delivery_interval'])) : 0);
273 $poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0);
274 $maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
275 $dfrn_only = ((x($_POST,'dfrn_only')) ? True : False);
276 $ostatus_disabled = !((x($_POST,'ostatus_disabled')) ? True : False);
277 $ostatus_poll_interval = ((x($_POST,'ostatus_poll_interval')) ? intval(trim($_POST['ostatus_poll_interval'])) : 0);
278 $diaspora_enabled = ((x($_POST,'diaspora_enabled')) ? True : False);
279 $ssl_policy = ((x($_POST,'ssl_policy')) ? intval($_POST['ssl_policy']) : 0);
280 $new_share = ((x($_POST,'new_share')) ? True : False);
281 $hide_help = ((x($_POST,'hide_help')) ? True : False);
282 $use_fulltext_engine = ((x($_POST,'use_fulltext_engine')) ? True : False);
283 $itemcache = ((x($_POST,'itemcache')) ? notags(trim($_POST['itemcache'])) : '');
284 $itemcache_duration = ((x($_POST,'itemcache_duration')) ? intval($_POST['itemcache_duration']) : 0);
285 $lockpath = ((x($_POST,'lockpath')) ? notags(trim($_POST['lockpath'])) : '');
286 $temppath = ((x($_POST,'temppath')) ? notags(trim($_POST['temppath'])) : '');
287 $basepath = ((x($_POST,'basepath')) ? notags(trim($_POST['basepath'])) : '');
288 $singleuser = ((x($_POST,'singleuser')) ? notags(trim($_POST['singleuser'])) : '');
289 if($ssl_policy != intval(get_config('system','ssl_policy'))) {
290 if($ssl_policy == SSL_POLICY_FULL) {
291 q("update `contact` set
292 `url` = replace(`url` , 'http:' , 'https:'),
293 `photo` = replace(`photo` , 'http:' , 'https:'),
294 `thumb` = replace(`thumb` , 'http:' , 'https:'),
295 `micro` = replace(`micro` , 'http:' , 'https:'),
296 `request` = replace(`request`, 'http:' , 'https:'),
297 `notify` = replace(`notify` , 'http:' , 'https:'),
298 `poll` = replace(`poll` , 'http:' , 'https:'),
299 `confirm` = replace(`confirm`, 'http:' , 'https:'),
300 `poco` = replace(`poco` , 'http:' , 'https:')
303 q("update `profile` set
304 `photo` = replace(`photo` , 'http:' , 'https:'),
305 `thumb` = replace(`thumb` , 'http:' , 'https:')
309 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
310 q("update `contact` set
311 `url` = replace(`url` , 'https:' , 'http:'),
312 `photo` = replace(`photo` , 'https:' , 'http:'),
313 `thumb` = replace(`thumb` , 'https:' , 'http:'),
314 `micro` = replace(`micro` , 'https:' , 'http:'),
315 `request` = replace(`request`, 'https:' , 'http:'),
316 `notify` = replace(`notify` , 'https:' , 'http:'),
317 `poll` = replace(`poll` , 'https:' , 'http:'),
318 `confirm` = replace(`confirm`, 'https:' , 'http:'),
319 `poco` = replace(`poco` , 'https:' , 'http:')
322 q("update `profile` set
323 `photo` = replace(`photo` , 'https:' , 'http:'),
324 `thumb` = replace(`thumb` , 'https:' , 'http:')
329 set_config('system','ssl_policy',$ssl_policy);
330 set_config('system','delivery_interval',$delivery_interval);
331 set_config('system','poll_interval',$poll_interval);
332 set_config('system','maxloadavg',$maxloadavg);
333 set_config('config','sitename',$sitename);
335 // don't know why, but del_config doesn't work...
336 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
341 set_config('system','banner', $banner);
343 set_config('system','language', $language);
344 set_config('system','theme', $theme);
345 if ( $theme_mobile === '---' ) {
346 del_config('system','mobile-theme');
348 set_config('system','mobile-theme', $theme_mobile);
350 if ( $singleuser === '---' ) {
351 del_config('system','singleuser');
353 set_config('system','singleuser', $singleuser);
355 set_config('system','maximagesize', $maximagesize);
356 set_config('system','max_image_length', $maximagelength);
357 set_config('system','jpeg_quality', $jpegimagequality);
359 set_config('config','register_policy', $register_policy);
360 set_config('system','max_daily_registrations', $daily_registrations);
361 set_config('system','account_abandon_days', $abandon_days);
362 set_config('config','register_text', $register_text);
363 set_config('system','allowed_sites', $allowed_sites);
364 set_config('system','allowed_email', $allowed_email);
365 set_config('system','block_public', $block_public);
366 set_config('system','publish_all', $force_publish);
367 if ($global_directory==""){
368 // don't know why, but del_config doesn't work...
369 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
371 dbesc("directory_submit_url")
374 set_config('system','directory_submit_url', $global_directory);
376 set_config('system','thread_allow', $thread_allow);
377 set_config('system','newuser_private', $newuser_private);
378 set_config('system','enotify_no_content', $enotify_no_content);
379 set_config('system','disable_embedded', $disable_embedded);
381 set_config('system','block_extended_register', $no_multi_reg);
382 set_config('system','no_openid', $no_openid);
383 set_config('system','no_regfullname', $no_regfullname);
384 set_config('system','no_community_page', $no_community_page);
385 set_config('system','no_utf', $no_utf);
386 set_config('system','verifyssl', $verifyssl);
387 set_config('system','proxyuser', $proxyuser);
388 set_config('system','proxy', $proxy);
389 set_config('system','curl_timeout', $timeout);
390 set_config('system','dfrn_only', $dfrn_only);
391 set_config('system','ostatus_disabled', $ostatus_disabled);
392 set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
393 set_config('system','diaspora_enabled', $diaspora_enabled);
394 set_config('config','private_addons', $private_addons);
396 set_config('system','new_share', $new_share);
397 set_config('system','hide_help', $hide_help);
398 set_config('system','use_fulltext_engine', $use_fulltext_engine);
399 set_config('system','itemcache', $itemcache);
400 set_config('system','itemcache_duration', $itemcache_duration);
401 set_config('system','lockpath', $lockpath);
402 set_config('system','temppath', $temppath);
403 set_config('system','basepath', $basepath);
405 info( t('Site settings updated.') . EOL);
406 goaway($a->get_baseurl(true) . '/admin/site' );
407 return; // NOTREACHED
415 function admin_page_site(&$a) {
417 /* Installed langs */
418 $lang_choices = array();
419 $langs = glob('view/*/strings.php');
421 if(is_array($langs) && count($langs)) {
422 if(! in_array('view/en/strings.php',$langs))
423 $langs[] = 'view/en/';
425 foreach($langs as $l) {
426 $t = explode("/",$l);
427 $lang_choices[$t[1]] = $t[1];
431 /* Installed themes */
432 $theme_choices = array();
433 $theme_choices_mobile = array();
434 $theme_choices_mobile["---"] = t("No special theme for mobile devices");
435 $files = glob('view/theme/*');
437 foreach($files as $file) {
438 $f = basename($file);
439 $theme_name = ((file_exists($file . '/experimental')) ? sprintf("%s - \x28Experimental\x29", $f) : $f);
440 if (file_exists($file . '/mobile')) {
441 $theme_choices_mobile[$f] = $theme_name;
444 $theme_choices[$f] = $theme_name;
449 /* OStatus conversation poll choices */
450 $ostatus_poll_choices = array(
452 "0" => t("Frequently"),
454 "720" => t("Twice daily"),
458 /* get user names to make the install a personal install of X */
459 $user_names = array();
460 $user_names['---'] = t('Multi user instance');
461 $users = q("SELECT username, nickname FROM `user`");
462 foreach ($users as $user) {
463 $user_names[$user['nickname']] = $user['username'];
467 $banner = get_config('system','banner');
469 $banner = '<a href="http://friendica.com"><img id="logo-img" src="images/friendica-32.png" alt="logo" /></a><span id="logo-text"><a href="http://friendica.com">Friendica</a></span>';
470 $banner = htmlspecialchars($banner);
472 //echo "<pre>"; var_dump($lang_choices); die("</pre>");
474 /* Register policy */
475 $register_choices = Array(
476 REGISTER_CLOSED => t("Closed"),
477 REGISTER_APPROVE => t("Requires approval"),
478 REGISTER_OPEN => t("Open")
481 $ssl_choices = array(
482 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
483 SSL_POLICY_FULL => t("Force all links to use SSL"),
484 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
487 $t = get_markup_template("admin_site.tpl");
488 return replace_macros($t, array(
489 '$title' => t('Administration'),
490 '$page' => t('Site'),
491 '$submit' => t('Submit'),
492 '$registration' => t('Registration'),
493 '$upload' => t('File upload'),
494 '$corporate' => t('Policies'),
495 '$advanced' => t('Advanced'),
496 '$performance' => t('Performance'),
498 '$baseurl' => $a->get_baseurl(true),
499 // name, label, value, help string, extra data...
500 '$sitename' => array('sitename', t("Site name"), htmlentities($a->config['sitename'], ENT_QUOTES), 'UTF-8'),
501 '$banner' => array('banner', t("Banner/Logo"), $banner, ""),
502 '$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
503 '$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
504 '$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
505 '$ssl_policy' => array('ssl_policy', t("SSL link policy"), (string) intval(get_config('system','ssl_policy')), t("Determines whether generated links should be forced to use SSL"), $ssl_choices),
506 '$new_share' => array('new_share', t("'Share' element"), get_config('system','new_share'), t("Activates the bbcode element 'share' for repeating items.")),
507 '$hide_help' => array('hide_help', t("Hide help entry from navigation menu"), get_config('system','hide_help'), t("Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly.")),
508 '$singleuser' => array('singleuser', t("Single user instance"), get_config('system','singleuser'), t("Make this instance multi-user or single-user for the named user"), $user_names),
509 '$maximagesize' => array('maximagesize', t("Maximum image size"), get_config('system','maximagesize'), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
510 '$maximagelength' => array('maximagelength', t("Maximum image length"), get_config('system','max_image_length'), t("Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.")),
511 '$jpegimagequality' => array('jpegimagequality', t("JPEG image quality"), get_config('system','jpeg_quality'), t("Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality.")),
513 '$register_policy' => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
514 '$daily_registrations' => array('max_daily_registrations', t("Maximum Daily Registrations"), get_config('system', 'max_daily_registrations'), t("If registration is permitted above, this sets the maximum number of new user registrations to accept per day. If register is set to closed, this setting has no effect.")),
515 '$register_text' => array('register_text', t("Register text"), htmlentities($a->config['register_text'], ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")),
516 '$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.')),
517 '$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")),
518 '$allowed_email' => array('allowed_email', t("Allowed email domains"), get_config('system','allowed_email'), t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")),
519 '$block_public' => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.")),
520 '$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.")),
521 '$global_directory' => array('directory_submit_url', t("Global directory update URL"), get_config('system','directory_submit_url'), t("URL to update the global directory. If this is not set, the global directory is completely unavailable to the application.")),
522 '$thread_allow' => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
523 '$newuser_private' => array('newuser_private', t("Private posts by default for new users"), get_config('system','newuser_private'), t("Set default post permissions for all new members to the default privacy group rather than public.")),
524 '$enotify_no_content' => array('enotify_no_content', t("Don't include post content in email notifications"), get_config('system','enotify_no_content'), t("Don't include the content of a post/comment/private message/etc. in the email notifications that are sent out from this site, as a privacy measure.")),
525 '$private_addons' => array('private_addons', t("Disallow public access to addons listed in the apps menu."), get_config('config','private_addons'), t("Checking this box will restrict addons listed in the apps menu to members only.")),
526 '$disable_embedded' => array('disable_embedded', t("Don't embed private images in posts"), get_config('system','disable_embedded'), t("Don't replace locally-hosted private photos in posts with an embedded copy of the image. This means that contacts who receive posts containing private photos will have to authenticate and load each image, which may take a while.")),
528 '$no_multi_reg' => array('no_multi_reg', t("Block multiple registrations"), get_config('system','block_extended_register'), t("Disallow users to register additional accounts for use as pages.")),
529 '$no_openid' => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
530 '$no_regfullname' => array('no_regfullname', t("Fullname check"), !get_config('system','no_regfullname'), t("Force users to register with a space between firstname and lastname in Full name, as an antispam measure")),
531 '$no_utf' => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
532 '$no_community_page' => array('no_community_page', t("Show Community Page"), !get_config('system','no_community_page'), t("Display a Community page showing all recent public postings on this site.")),
533 '$ostatus_disabled' => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28identi.ca, status.net, etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),
534 '$ostatus_poll_interval' => array('ostatus_poll_interval', t("OStatus conversation completion interval"), (string) intval(get_config('system','ostatus_poll_interval')), t("How often shall the poller check for new entries in OStatus conversations? This can be a very ressource task."), $ostatus_poll_choices),
535 '$diaspora_enabled' => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
536 '$dfrn_only' => array('dfrn_only', t('Only allow Friendica contacts'), get_config('system','dfrn_only'), t("All contacts must use Friendica protocols. All other built-in communication protocols disabled.")),
537 '$verifyssl' => array('verifyssl', t("Verify SSL"), get_config('system','verifyssl'), t("If you wish, you can turn on strict certificate checking. This will mean you cannot connect (at all) to self-signed SSL sites.")),
538 '$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
539 '$proxy' => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
540 '$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).")),
541 '$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.")),
542 '$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.")),
543 '$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.")),
545 '$use_fulltext_engine' => array('use_fulltext_engine', t("Use MySQL full text engine"), get_config('system','use_fulltext_engine'), t("Activates the full text engine. Speeds up search - but can only search for four and more characters.")),
546 '$itemcache' => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), "The item caches buffers generated bbcode and external images."),
547 '$itemcache_duration' => array('itemcache_duration', t("Cache duration in seconds"), get_config('system','itemcache_duration'), t("How long should the cache files be hold? Default value is 86400 seconds (One day).")),
548 '$lockpath' => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), "The lock file is used to avoid multiple pollers at one time. Only define a folder here."),
549 '$temppath' => array('temppath', t("Temp path"), get_config('system','temppath'), "If you have a restricted system where the webserver can't access the system temp path, enter another path here."),
550 '$basepath' => array('basepath', t("Base path to installation"), get_config('system','basepath'), "If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."),
551 '$form_security_token' => get_form_security_token("admin_site"),
558 function admin_page_dbsync(&$a) {
562 if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
563 set_config('database', 'update_' . intval($a->argv[3]), 'success');
564 $curr = get_config('system','build');
565 if(intval($curr) == intval($a->argv[3]))
566 set_config('system','build',intval($curr) + 1);
567 info( t('Update has been marked successful') . EOL);
568 goaway($a->get_baseurl(true) . '/admin/dbsync');
571 if($a->argc > 2 && intval($a->argv[2])) {
572 require_once('update.php');
573 $func = 'update_' . intval($a->argv[2]);
574 if(function_exists($func)) {
576 if($retval === UPDATE_FAILED) {
577 $o .= sprintf( t('Executing %s failed. Check system logs.'), $func);
579 elseif($retval === UPDATE_SUCCESS) {
580 $o .= sprintf( t('Update %s was successfully applied.', $func));
581 set_config('database',$func, 'success');
584 $o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $func);
587 $o .= sprintf( t('Update function %s could not be found.'), $func);
592 $r = q("select * from config where `cat` = 'database' ");
595 $upd = intval(substr($rr['k'],7));
596 if($upd < 1139 || $rr['v'] === 'success')
602 return '<h3>' . t('No failed updates.') . '</h3>';
604 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
605 '$base' => $a->get_baseurl(true),
606 '$banner' => t('Failed Updates'),
607 '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
608 '$mark' => t('Mark success (if update was manually applied)'),
609 '$apply' => t('Attempt to execute this update step automatically'),
622 function admin_page_users_post(&$a){
623 $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
624 $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
625 $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : '');
626 $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : '');
627 $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
629 check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
631 if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) {
632 require_once('include/user.php');
633 require_once('include/email.php');
634 $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1) );
635 if(! $result['success']) {
636 notice($result['message']);
639 $nu = $result['user'];
640 $email_tpl = get_intltext_template("register_adminadd_eml.tpl");
641 $email_tpl = replace_macros($email_tpl, array(
642 '$sitename' => $a->config['sitename'],
643 '$siteurl' => $a->get_baseurl(),
644 '$username' => $nu['username'],
645 '$email' => $nu['email'],
646 '$password' => $result['password'],
647 '$uid' => $nu['uid'] ));
649 $res = mail($nu['email'], email_header_encode( sprintf( t('Registration details for %s'), $a->config['sitename']),'UTF-8'),
651 'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME'] . "\n"
652 . 'Content-type: text/plain; charset=UTF-8' . "\n"
653 . 'Content-transfer-encoding: 8bit' );
655 info( t('Registration successful. Email send to user').EOL );
659 if (x($_POST,'page_users_block')){
660 foreach($users as $uid){
661 q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
665 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
667 if (x($_POST,'page_users_delete')){
668 require_once("include/Contact.php");
669 foreach($users as $uid){
672 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
675 if (x($_POST,'page_users_approve')){
676 require_once("mod/regmod.php");
677 foreach($pending as $hash){
681 if (x($_POST,'page_users_deny')){
682 require_once("mod/regmod.php");
683 foreach($pending as $hash){
687 goaway($a->get_baseurl(true) . '/admin/users' );
688 return; // NOTREACHED
695 function admin_page_users(&$a){
698 $user = q("SELECT * FROM `user` WHERE `uid`=%d", intval($uid));
699 if (count($user)==0){
700 notice( 'User not found' . EOL);
701 goaway($a->get_baseurl(true) . '/admin/users' );
702 return ''; // NOTREACHED
706 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
708 require_once("include/Contact.php");
711 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
714 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
715 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
716 intval( 1-$user[0]['blocked'] ),
719 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
722 goaway($a->get_baseurl(true) . '/admin/users' );
723 return ''; // NOTREACHED
728 $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
730 LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
731 LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
736 $total = q("SELECT count(*) as total FROM `user` where 1");
738 $a->set_pager_total($total[0]['total']);
739 $a->set_pager_itemspage(100);
743 $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
745 (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
747 WHERE `item`.`type` = 'wall'
748 GROUP BY `item`.`uid`) AS `lastitem`
749 RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
752 `user`.`uid` = `contact`.`uid`
753 AND `user`.`verified` =1
754 AND `contact`.`self` =1
755 ORDER BY `contact`.`name` LIMIT %d, %d
757 intval($a->pager['start']),
758 intval($a->pager['itemspage'])
761 function _setup_users($e){
765 t('Soapbox Account'),
766 t('Community/Celebrity Account'),
767 t('Automatic Friend Account')
769 $e['page-flags'] = $accounts[$e['page-flags']];
770 $e['register_date'] = relative_date($e['register_date']);
771 $e['login_date'] = relative_date($e['login_date']);
772 $e['lastitem_date'] = relative_date($e['lastitem_date']);
773 $e['is_admin'] = ($e['email'] === $a->config['admin_email']);
774 $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
777 $users = array_map("_setup_users", $users);
780 // Get rid of dashes in key names, Smarty3 can't handle them
781 // and extracting deleted users
783 $tmp_users = Array();
786 while(count($users)) {
788 foreach( array_pop($users) as $k => $v) {
789 $k = str_replace('-','_',$k);
792 if($new_user['deleted']) {
793 array_push($deleted, $new_user);
796 array_push($tmp_users, $new_user);
799 //Reversing the two array, and moving $tmp_users to $users
800 array_reverse($deleted);
801 while(count($tmp_users)) {
802 array_push($users, array_pop($tmp_users));
805 $t = get_markup_template("admin_users.tpl");
806 $o = replace_macros($t, array(
808 '$title' => t('Administration'),
809 '$page' => t('Users'),
810 '$submit' => t('Submit'),
811 '$select_all' => t('select all'),
812 '$h_pending' => t('User registrations waiting for confirm'),
813 '$h_deleted' => t('User waiting for permanent deletion'),
814 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
815 '$no_pending' => t('No registrations.'),
816 '$approve' => t('Approve'),
817 '$deny' => t('Deny'),
818 '$delete' => t('Delete'),
819 '$block' => t('Block'),
820 '$unblock' => t('Unblock'),
821 '$siteadmin' => t('Site admin'),
822 '$accountexpired' => t('Account expired'),
824 '$h_users' => t('Users'),
825 '$h_newuser' => t('New User'),
826 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
827 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Account') ),
829 '$confirm_delete_multi' => t('Selected users will be deleted!\n\nEverything these users had posted on this site will be permanently deleted!\n\nAre you sure?'),
830 '$confirm_delete' => t('The user {0} will be deleted!\n\nEverything this user has posted on this site will be permanently deleted!\n\nAre you sure?'),
832 '$form_security_token' => get_form_security_token("admin_users"),
835 '$baseurl' => $a->get_baseurl(true),
837 '$pending' => $pending,
838 'deleted' => $deleted,
840 '$newusername' => array('new_user_name', t("Name"), '', t("Name of the new user.")),
841 '$newusernickname' => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")),
842 '$newuseremail' => array('new_user_email', t("Email"), '', t("Email address of the new user.")),
855 function admin_page_plugins(&$a){
861 $plugin = $a->argv[2];
862 if (!is_file("addon/$plugin/$plugin.php")){
863 notice( t("Item not found.") );
867 if (x($_GET,"a") && $_GET['a']=="t"){
868 check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
870 // Toggle plugin status
871 $idx = array_search($plugin, $a->plugins);
873 unset($a->plugins[$idx]);
874 uninstall_plugin($plugin);
875 info( sprintf( t("Plugin %s disabled."), $plugin ) );
877 $a->plugins[] = $plugin;
878 install_plugin($plugin);
879 info( sprintf( t("Plugin %s enabled."), $plugin ) );
881 set_config("system","addon", implode(", ",$a->plugins));
882 goaway($a->get_baseurl(true) . '/admin/plugins' );
883 return ''; // NOTREACHED
885 // display plugin details
886 require_once('library/markdown.php');
888 if (in_array($plugin, $a->plugins)){
889 $status="on"; $action= t("Disable");
891 $status="off"; $action= t("Enable");
895 if (is_file("addon/$plugin/README.md")){
896 $readme = file_get_contents("addon/$plugin/README.md");
897 $readme = Markdown($readme);
898 } else if (is_file("addon/$plugin/README")){
899 $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
903 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
904 @require_once("addon/$plugin/$plugin.php");
905 $func = $plugin.'_plugin_admin';
906 $func($a, $admin_form);
909 $t = get_markup_template("admin_plugins_details.tpl");
911 return replace_macros($t, array(
912 '$title' => t('Administration'),
913 '$page' => t('Plugins'),
914 '$toggle' => t('Toggle'),
915 '$settings' => t('Settings'),
916 '$baseurl' => $a->get_baseurl(true),
918 '$plugin' => $plugin,
919 '$status' => $status,
920 '$action' => $action,
921 '$info' => get_plugin_info($plugin),
922 '$str_author' => t('Author: '),
923 '$str_maintainer' => t('Maintainer: '),
925 '$admin_form' => $admin_form,
926 '$function' => 'plugins',
928 '$readme' => $readme,
930 '$form_security_token' => get_form_security_token("admin_themes"),
941 $files = glob("addon/*/");
943 foreach($files as $file) {
945 list($tmp, $id)=array_map("trim", explode("/",$file));
946 $info = get_plugin_info($id);
947 $plugins[] = array( $id, (in_array($id, $a->plugins)?"on":"off") , $info);
952 $t = get_markup_template("admin_plugins.tpl");
953 return replace_macros($t, array(
954 '$title' => t('Administration'),
955 '$page' => t('Plugins'),
956 '$submit' => t('Submit'),
957 '$baseurl' => $a->get_baseurl(true),
958 '$function' => 'plugins',
959 '$plugins' => $plugins,
960 '$form_security_token' => get_form_security_token("admin_themes"),
965 * @param array $themes
969 function toggle_theme(&$themes,$th,&$result) {
970 for($x = 0; $x < count($themes); $x ++) {
971 if($themes[$x]['name'] === $th) {
972 if($themes[$x]['allowed']) {
973 $themes[$x]['allowed'] = 0;
977 $themes[$x]['allowed'] = 1;
985 * @param array $themes
989 function theme_status($themes,$th) {
990 for($x = 0; $x < count($themes); $x ++) {
991 if($themes[$x]['name'] === $th) {
992 if($themes[$x]['allowed']) {
1005 * @param array $themes
1008 function rebuild_theme_table($themes) {
1010 if(count($themes)) {
1011 foreach($themes as $th) {
1012 if($th['allowed']) {
1029 function admin_page_themes(&$a){
1031 $allowed_themes_str = get_config('system','allowed_themes');
1032 $allowed_themes_raw = explode(',',$allowed_themes_str);
1033 $allowed_themes = array();
1034 if(count($allowed_themes_raw))
1035 foreach($allowed_themes_raw as $x)
1036 if(strlen(trim($x)))
1037 $allowed_themes[] = trim($x);
1040 $files = glob('view/theme/*');
1042 foreach($files as $file) {
1043 $f = basename($file);
1044 $is_experimental = intval(file_exists($file . '/experimental'));
1045 $is_supported = 1-(intval(file_exists($file . '/unsupported'))); // Is not used yet
1046 $is_allowed = intval(in_array($f,$allowed_themes));
1047 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1051 if(! count($themes)) {
1052 notice( t('No themes found.'));
1061 $theme = $a->argv[2];
1062 if(! is_dir("view/theme/$theme")){
1063 notice( t("Item not found.") );
1067 if (x($_GET,"a") && $_GET['a']=="t"){
1068 check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1070 // Toggle theme status
1072 toggle_theme($themes,$theme,$result);
1073 $s = rebuild_theme_table($themes);
1075 install_theme($theme);
1076 info( sprintf('Theme %s enabled.',$theme));
1079 uninstall_theme($theme);
1080 info( sprintf('Theme %s disabled.',$theme));
1083 set_config('system','allowed_themes',$s);
1084 goaway($a->get_baseurl(true) . '/admin/themes' );
1085 return ''; // NOTREACHED
1088 // display theme details
1089 require_once('library/markdown.php');
1091 if (theme_status($themes,$theme)) {
1092 $status="on"; $action= t("Disable");
1094 $status="off"; $action= t("Enable");
1098 if (is_file("view/theme/$theme/README.md")){
1099 $readme = file_get_contents("view/theme/$theme/README.md");
1100 $readme = Markdown($readme);
1101 } else if (is_file("view/theme/$theme/README")){
1102 $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1106 if (is_file("view/theme/$theme/config.php")){
1107 require_once("view/theme/$theme/config.php");
1108 if(function_exists("theme_admin")){
1109 $admin_form = theme_admin($a);
1114 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1115 if(! stristr($screenshot[0],$theme))
1118 $t = get_markup_template("admin_plugins_details.tpl");
1119 return replace_macros($t, array(
1120 '$title' => t('Administration'),
1121 '$page' => t('Themes'),
1122 '$toggle' => t('Toggle'),
1123 '$settings' => t('Settings'),
1124 '$baseurl' => $a->get_baseurl(true),
1126 '$plugin' => $theme,
1127 '$status' => $status,
1128 '$action' => $action,
1129 '$info' => get_theme_info($theme),
1130 '$function' => 'themes',
1131 '$admin_form' => $admin_form,
1132 '$str_author' => t('Author: '),
1133 '$str_maintainer' => t('Maintainer: '),
1134 '$screenshot' => $screenshot,
1135 '$readme' => $readme,
1137 '$form_security_token' => get_form_security_token("admin_themes"),
1147 foreach($themes as $th) {
1148 $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1152 $t = get_markup_template("admin_plugins.tpl");
1153 return replace_macros($t, array(
1154 '$title' => t('Administration'),
1155 '$page' => t('Themes'),
1156 '$submit' => t('Submit'),
1157 '$baseurl' => $a->get_baseurl(true),
1158 '$function' => 'themes',
1159 '$plugins' => $xthemes,
1160 '$experimental' => t('[Experimental]'),
1161 '$unsupported' => t('[Unsupported]'),
1162 '$form_security_token' => get_form_security_token("admin_themes"),
1173 function admin_page_logs_post(&$a) {
1174 if (x($_POST,"page_logs")) {
1175 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1177 $logfile = ((x($_POST,'logfile')) ? notags(trim($_POST['logfile'])) : '');
1178 $debugging = ((x($_POST,'debugging')) ? true : false);
1179 $loglevel = ((x($_POST,'loglevel')) ? intval(trim($_POST['loglevel'])) : 0);
1181 set_config('system','logfile', $logfile);
1182 set_config('system','debugging', $debugging);
1183 set_config('system','loglevel', $loglevel);
1188 info( t("Log settings updated.") );
1189 goaway($a->get_baseurl(true) . '/admin/logs' );
1190 return; // NOTREACHED
1197 function admin_page_logs(&$a){
1199 $log_choices = Array(
1200 LOGGER_NORMAL => 'Normal',
1201 LOGGER_TRACE => 'Trace',
1202 LOGGER_DEBUG => 'Debug',
1203 LOGGER_DATA => 'Data',
1207 $t = get_markup_template("admin_logs.tpl");
1209 $f = get_config('system','logfile');
1213 if(!file_exists($f)) {
1214 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1218 $fp = fopen($f, 'r');
1220 $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1223 $fstat = fstat($fp);
1224 $size = $fstat['size'];
1227 if($size > 5000000 || $size < 0)
1229 $seek = fseek($fp,0-$size,SEEK_END);
1231 $data = escape_tags(fread($fp,$size));
1233 $data .= escape_tags(fread($fp,4096));
1240 return replace_macros($t, array(
1241 '$title' => t('Administration'),
1242 '$page' => t('Logs'),
1243 '$submit' => t('Submit'),
1244 '$clear' => t('Clear'),
1246 '$baseurl' => $a->get_baseurl(true),
1247 '$logname' => get_config('system','logfile'),
1249 // name, label, value, help string, extra data...
1250 '$debugging' => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1251 '$logfile' => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1252 '$loglevel' => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1254 '$form_security_token' => get_form_security_token("admin_logs"),
1261 function admin_page_remoteupdate_post(&$a) {
1262 // this function should be called via ajax post
1263 if(!is_site_admin()) {
1268 if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1269 $remotefile = $_POST['remotefile'];
1270 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1271 doUpdate($remotefile, $ftpdata);
1273 echo "No remote file to download. Abort!";
1283 function admin_page_remoteupdate(&$a) {
1284 if(!is_site_admin()) {
1285 return login(false);
1288 $canwrite = canWeWrite();
1289 $canftp = function_exists('ftp_connect');
1294 $needupdate = false;
1295 $u = array('','','');
1298 $tpl = get_markup_template("admin_remoteupdate.tpl");
1299 return replace_macros($tpl, array(
1300 '$baseurl' => $a->get_baseurl(true),
1301 '$submit' => t("Update now"),
1302 '$close' => t("Close"),
1303 '$localversion' => FRIENDICA_VERSION,
1304 '$remoteversion' => $u[1],
1305 '$needupdate' => $needupdate,
1306 '$canwrite' => $canwrite,
1307 '$canftp' => $canftp,
1308 '$ftphost' => array('ftphost', t("FTP Host"), '',''),
1309 '$ftppath' => array('ftppath', t("FTP Path"), '/',''),
1310 '$ftpuser' => array('ftpuser', t("FTP User"), '',''),
1311 '$ftppwd' => array('ftppwd', t("FTP Password"), '',''),
1312 '$remotefile'=>array('remotefile','', $u['2'],''),