]> git.mxchange.org Git - friendica.git/blob - mod/admin.php
d9a17dcad7010939fdbd2208c778e60914f0613c
[friendica.git] / mod / admin.php
1 <?php
2
3  /**
4   * Friendica admin
5   */
6 require_once("include/remoteupdate.php");
7 require_once("include/enotify.php");
8 require_once("include/text.php");
9
10
11 /**
12  * @param App $a
13  */
14 function admin_post(&$a){
15
16
17         if(!is_site_admin()) {
18                 return;
19         }
20
21         // do not allow a page manager to access the admin panel at all.
22
23         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
24                 return;
25
26
27
28         // urls
29         if ($a->argc > 1){
30                 switch ($a->argv[1]){
31                         case 'site':
32                                 admin_page_site_post($a);
33                                 break;
34                         case 'users':
35                                 admin_page_users_post($a);
36                                 break;
37                         case 'plugins':
38                                 if ($a->argc > 2 &&
39                                         is_file("addon/".$a->argv[2]."/".$a->argv[2].".php")){
40                                                 @include_once("addon/".$a->argv[2]."/".$a->argv[2].".php");
41                                                 if(function_exists($a->argv[2].'_plugin_admin_post')) {
42                                                         $func = $a->argv[2].'_plugin_admin_post';
43                                                         $func($a);
44                                                 }
45                                 }
46                                 goaway($a->get_baseurl(true) . '/admin/plugins/' . $a->argv[2] );
47                                 return; // NOTREACHED
48                                 break;
49                         case 'themes':
50                                 if ($a->argc < 2) {
51                                         if(is_ajax()) return;
52                                         goaway($a->get_baseurl(true) . '/admin/' );
53                                         return;
54                                 }
55
56                                 $theme = $a->argv[2];
57                                 if (is_file("view/theme/$theme/config.php")){
58                                         function __call_theme_admin_post(&$a, $theme) {
59                                                 $orig_theme = $a->theme;
60                                                 $orig_page = $a->page;
61                                                 $orig_session_theme = $_SESSION['theme'];
62                                                 require_once("view/theme/$theme/theme.php");
63                                                 require_once("view/theme/$theme/config.php");
64                                                 $_SESSION['theme'] = $theme;
65
66
67                                                 $init = $theme."_init";
68                                                 if(function_exists($init)) $init($a);
69                                                 if(function_exists("theme_admin_post")){
70                                                         $admin_form = theme_admin_post($a);
71                                                 }
72
73                                                 $_SESSION['theme'] = $orig_session_theme;
74                                                 $a->theme = $orig_theme;
75                                                 $a->page = $orig_page;
76                                                 return $admin_form;
77                                         }
78                                         __call_theme_admin_post($a, $theme);
79                                 }
80                                 info(t('Theme settings updated.'));
81                                 if(is_ajax()) return;
82
83                                 goaway($a->get_baseurl(true) . '/admin/themes/' . $theme );
84                                 return;
85                                 break;
86                         case 'logs':
87                                 admin_page_logs_post($a);
88                                 break;
89                         case 'dbsync':
90                                 admin_page_dbsync_post($a);
91                                 break;
92                         case 'update':
93                                 admin_page_remoteupdate_post($a);
94                                 break;
95                 }
96         }
97
98         goaway($a->get_baseurl(true) . '/admin' );
99         return; // NOTREACHED
100 }
101
102 /**
103  * @param App $a
104  * @return string
105  */
106 function admin_content(&$a) {
107
108         if(!is_site_admin()) {
109                 return login(false);
110         }
111
112         if(x($_SESSION,'submanage') && intval($_SESSION['submanage']))
113                 return "";
114
115         // APC deactivated, since there are problems with PHP 5.5
116         //if (function_exists("apc_delete")) {
117         //      $toDelete = new APCIterator('user', APC_ITER_VALUE);
118         //      apc_delete($toDelete);
119         //}
120
121         /**
122          * Side bar links
123          */
124
125         // array( url, name, extra css classes )
126         $aside = Array(
127                 'site'   =>     Array($a->get_baseurl(true)."/admin/site/", t("Site") , "site"),
128                 'users'  =>     Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"),
129                 'plugins'=>     Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
130                 'themes' =>     Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
131                 'dbsync' =>     Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
132                 'queue'  =>     Array($a->get_baseurl(true)."/admin/queue/", t('Inspect Queue'), "queue"),
133                 //'update' =>   Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
134         );
135
136         /* get plugins admin page */
137
138         $r = q("SELECT `name` FROM `addon` WHERE `plugin_admin`=1 ORDER BY `name`");
139         $aside['plugins_admin']=Array();
140         foreach ($r as $h){
141                 $plugin =$h['name'];
142                 $aside['plugins_admin'][] = Array($a->get_baseurl(true)."/admin/plugins/".$plugin, $plugin, "plugin");
143                 // temp plugins with admin
144                 $a->plugins_admin[] = $plugin;
145         }
146
147         $aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
148         $aside['diagnostics_probe'] = Array($a->get_baseurl(true).'/probe/', t('probe address'), 'probe');
149         $aside['diagnostics_webfinger'] = Array($a->get_baseurl(true).'/webfinger/', t('check webfinger'), 'webfinger');
150
151         $t = get_markup_template("admin_aside.tpl");
152         $a->page['aside'] .= replace_macros( $t, array(
153                         '$admin' => $aside,
154                         '$admtxt' => t('Admin'),
155                         '$plugadmtxt' => t('Plugin Features'),
156                         '$logtxt' => t('Logs'),
157                         '$diagnosticstxt' => t('diagnostics'),
158                         '$h_pending' => t('User registrations waiting for confirmation'),
159                         '$admurl'=> $a->get_baseurl(true)."/admin/"
160         ));
161
162
163
164         /**
165          * Page content
166          */
167         $o = '';
168         // urls
169         if ($a->argc > 1){
170                 switch ($a->argv[1]){
171                         case 'site':
172                                 $o = admin_page_site($a);
173                                 break;
174                         case 'users':
175                                 $o = admin_page_users($a);
176                                 break;
177                         case 'plugins':
178                                 $o = admin_page_plugins($a);
179                                 break;
180                         case 'themes':
181                                 $o = admin_page_themes($a);
182                                 break;
183                         case 'logs':
184                                 $o = admin_page_logs($a);
185                                 break;
186                         case 'dbsync':
187                                 $o = admin_page_dbsync($a);
188                                 break;
189                         case 'update':
190                                 $o = admin_page_remoteupdate($a);
191                                 break;
192                         case 'queue':
193                                 $o = admin_page_queue($a);
194                                 break;
195                         default:
196                                 notice( t("Item not found.") );
197                 }
198         } else {
199                 $o = admin_page_summary($a);
200         }
201
202         if(is_ajax()) {
203                 echo $o;
204                 killme();
205                 return '';
206         } else {
207                 return $o;
208         }
209 }
210
211 /**
212  * Admin Inspect Queue Page
213  * @param App $a
214  * return string
215  */
216 function admin_page_queue(&$a) {
217         // get content from the queue table
218         $r = q("SELECT c.name,c.nurl,q.id,q.network,q.created,q.last from queue as q, contact as c where c.id=q.cid order by q.cid, q.created;");
219
220         $t = get_markup_template("admin_queue.tpl");
221         return replace_macros($t, array(
222                 '$title' => t('Administration'),
223                 '$page' => t('Inspect Queue'),
224                 '$count' => sizeof($r),
225                 'id_header' => t('ID'),
226                 '$to_header' => t('Recipient Name'),
227                 '$url_header' => t('Recipient Profile'),
228                 '$network_header' => t('Network'),
229                 '$created_header' => t('Created'),
230                 '$last_header' => t('Last Tried'),
231                 '$info' => t('This page lists the content of the queue for outgoing postings. These are postings the initial delivery failed for. They will be resend later and eventually deleted if the delivery fails permanently.'),
232                 '$entries' => $r,
233         ));
234 }
235 /**
236  * Admin Summary Page
237  * @param App $a
238  * @return string
239  */
240 function admin_page_summary(&$a) {
241         $r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
242         $accounts = Array(
243                 Array( t('Normal Account'), 0),
244                 Array( t('Soapbox Account'), 0),
245                 Array( t('Community/Celebrity Account'), 0),
246                 Array( t('Automatic Friend Account'), 0),
247                 Array( t('Blog Account'), 0),
248                 Array( t('Private Forum'), 0)
249         );
250
251         $users=0;
252         foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; }
253
254         logger('accounts: ' . print_r($accounts,true),LOGGER_DATA);
255
256         $r = q("SELECT COUNT(id) as `count` FROM `register`");
257         $pending = $r[0]['count'];
258
259         $r = q("select count(*) as total from deliverq where 1");
260         $deliverq = (($r) ? $r[0]['total'] : 0);
261
262         $r = q("select count(*) as total from queue where 1");
263         $queue = (($r) ? $r[0]['total'] : 0);
264
265         // We can do better, but this is a quick queue status
266
267         $queues = array( 'label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue );
268
269
270         $t = get_markup_template("admin_summary.tpl");
271         return replace_macros($t, array(
272                 '$title' => t('Administration'),
273                 '$page' => t('Summary'),
274                 '$queues' => $queues,
275                 '$users' => Array( t('Registered users'), $users),
276                 '$accounts' => $accounts,
277                 '$pending' => Array( t('Pending registrations'), $pending),
278                 '$version' => Array( t('Version'), FRIENDICA_VERSION),
279                 '$baseurl' => $a->get_baseurl(),
280                 '$platform' => FRIENDICA_PLATFORM,
281                 '$codename' => FRIENDICA_CODENAME,
282                 '$build' =>  get_config('system','build'),
283                 '$plugins' => Array( t('Active plugins'), $a->plugins )
284         ));
285 }
286
287
288 /**
289  * Admin Site Page
290  *  @param App $a
291  */
292 function admin_page_site_post(&$a){
293         if (!x($_POST,"page_site")){
294                 return;
295         }
296
297         check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
298
299         // relocate
300         if (x($_POST,'relocate') && x($_POST,'relocate_url') && $_POST['relocate_url']!=""){
301                 $new_url = $_POST['relocate_url'];
302                 $new_url = rtrim($new_url,"/");
303
304                 $parsed = @parse_url($new_url);
305                 if (!$parsed || (!x($parsed,'host') || !x($parsed,'scheme'))) {
306                         notice(t("Can not parse base url. Must have at least <scheme>://<domain>"));
307                         goaway($a->get_baseurl(true) . '/admin/site' );
308                 }
309
310                 /* steps:
311                  * replace all "baseurl" to "new_url" in config, profile, term, items and contacts
312                  * send relocate for every local user
313                  * */
314
315                 $old_url = $a->get_baseurl(true);
316
317                 function update_table($table_name, $fields, $old_url, $new_url) {
318                         global $db, $a;
319
320                         $dbold = dbesc($old_url);
321                         $dbnew = dbesc($new_url);
322
323                         $upd = array();
324                         foreach ($fields as $f) {
325                                 $upd[] = "`$f` = REPLACE(`$f`, '$dbold', '$dbnew')";
326                         }
327
328                         $upds = implode(", ", $upd);
329
330
331
332                         $q = sprintf("UPDATE %s SET %s;", $table_name, $upds);
333                         $r = q($q);
334                         if (!$r) {
335                                 notice( "Failed updating '$table_name': " . $db->error );
336                                 goaway($a->get_baseurl(true) . '/admin/site' );
337                         }
338                 }
339
340                 // update tables
341                 update_table("profile", array('photo', 'thumb'), $old_url, $new_url);
342                 update_table("term", array('url'), $old_url, $new_url);
343                 update_table("contact", array('photo','thumb','micro','url','nurl','request','notify','poll','confirm','poco'), $old_url, $new_url);
344                 update_table("unique_contacts", array('url'), $old_url, $new_url);
345                 update_table("item", array('owner-link','owner-avatar','author-name','author-link','author-avatar','body','plink','tag'), $old_url, $new_url);
346
347                 // update config
348                 $a->set_baseurl($new_url);
349                 set_config('system','url',$new_url);
350
351                 // send relocate
352                 $users = q("SELECT uid FROM user WHERE account_removed = 0 AND account_expired = 0");
353
354                 foreach ($users as $user) {
355                         proc_run('php', 'include/notifier.php', 'relocate', $user['uid']);
356                 }
357
358                 info("Relocation started. Could take a while to complete.");
359
360                 goaway($a->get_baseurl(true) . '/admin/site' );
361         }
362         // end relocate
363
364         $sitename               =       ((x($_POST,'sitename'))                 ? notags(trim($_POST['sitename']))              : '');
365         $hostname               =       ((x($_POST,'hostname'))                 ? notags(trim($_POST['hostname']))              : '');
366         $sender_email           =       ((x($_POST,'sender_email'))             ? notags(trim($_POST['sender_email']))          : '');
367         $banner                 =       ((x($_POST,'banner'))                   ? trim($_POST['banner'])                        : false);
368         $shortcut_icon          =       ((x($_POST,'shortcut_icon'))            ? notags(trim($_POST['shortcut_icon']))         : '');
369         $touch_icon             =       ((x($_POST,'touch_icon'))               ? notags(trim($_POST['touch_icon']))            : '');
370         $info                   =       ((x($_POST,'info'))                     ? trim($_POST['info'])                  : false);
371         $language               =       ((x($_POST,'language'))                 ? notags(trim($_POST['language']))              : '');
372         $theme                  =       ((x($_POST,'theme'))                    ? notags(trim($_POST['theme']))                 : '');
373         $theme_mobile           =       ((x($_POST,'theme_mobile'))             ? notags(trim($_POST['theme_mobile']))          : '');
374         $maximagesize           =       ((x($_POST,'maximagesize'))             ? intval(trim($_POST['maximagesize']))          :  0);
375         $maximagelength         =       ((x($_POST,'maximagelength'))           ? intval(trim($_POST['maximagelength']))        :  MAX_IMAGE_LENGTH);
376         $jpegimagequality       =       ((x($_POST,'jpegimagequality'))         ? intval(trim($_POST['jpegimagequality']))      :  JPEG_QUALITY);
377
378
379         $register_policy        =       ((x($_POST,'register_policy'))          ? intval(trim($_POST['register_policy']))       :  0);
380         $daily_registrations    =       ((x($_POST,'max_daily_registrations'))  ? intval(trim($_POST['max_daily_registrations']))       :0);
381         $abandon_days           =       ((x($_POST,'abandon_days'))             ? intval(trim($_POST['abandon_days']))          :  0);
382
383         $register_text          =       ((x($_POST,'register_text'))            ? notags(trim($_POST['register_text']))         : '');
384
385         $allowed_sites          =       ((x($_POST,'allowed_sites'))            ? notags(trim($_POST['allowed_sites']))         : '');
386         $allowed_email          =       ((x($_POST,'allowed_email'))            ? notags(trim($_POST['allowed_email']))         : '');
387         $block_public           =       ((x($_POST,'block_public'))             ? True                                          : False);
388         $force_publish          =       ((x($_POST,'publish_all'))              ? True                                          : False);
389         $global_directory       =       ((x($_POST,'directory'))                ? notags(trim($_POST['directory']))     : '');
390         $thread_allow           =       ((x($_POST,'thread_allow'))             ? True                                          : False);
391         $newuser_private                =       ((x($_POST,'newuser_private'))          ? True                                          : False);
392         $enotify_no_content             =       ((x($_POST,'enotify_no_content'))       ? True                                          : False);
393         $private_addons                 =       ((x($_POST,'private_addons'))           ? True                                          : False);
394         $disable_embedded               =       ((x($_POST,'disable_embedded'))         ? True                                          : False);
395         $allow_users_remote_self        =       ((x($_POST,'allow_users_remote_self'))          ? True                                          : False);
396
397         $no_multi_reg           =       ((x($_POST,'no_multi_reg'))             ? True                                          : False);
398         $no_openid              =       !((x($_POST,'no_openid'))               ? True                                          : False);
399         $no_regfullname         =       !((x($_POST,'no_regfullname'))          ? True                                          : False);
400         $no_utf                 =       !((x($_POST,'no_utf'))                  ? True                                          : False);
401         $community_page_style   =       ((x($_POST,'community_page_style'))     ? intval(trim($_POST['community_page_style']))  : 0);
402         $max_author_posts_community_page        =       ((x($_POST,'max_author_posts_community_page'))  ? intval(trim($_POST['max_author_posts_community_page']))       : 0);
403
404         $verifyssl              =       ((x($_POST,'verifyssl'))                ? True                                          : False);
405         $proxyuser              =       ((x($_POST,'proxyuser'))                ? notags(trim($_POST['proxyuser']))             : '');
406         $proxy                  =       ((x($_POST,'proxy'))                    ? notags(trim($_POST['proxy']))                 : '');
407         $timeout                =       ((x($_POST,'timeout'))                  ? intval(trim($_POST['timeout']))               : 60);
408         $delivery_interval      =       ((x($_POST,'delivery_interval'))        ? intval(trim($_POST['delivery_interval']))     : 0);
409         $poll_interval          =       ((x($_POST,'poll_interval'))            ? intval(trim($_POST['poll_interval']))         : 0);
410         $maxloadavg             =       ((x($_POST,'maxloadavg'))               ? intval(trim($_POST['maxloadavg']))            : 50);
411         $maxloadavg_frontend    =       ((x($_POST,'maxloadavg_frontend'))      ? intval(trim($_POST['maxloadavg_frontend']))   : 50);
412         $poco_completion        =       ((x($_POST,'poco_completion'))          ? intval(trim($_POST['poco_completion']))       : false);
413         $poco_requery_days      =       ((x($_POST,'poco_requery_days'))        ? intval(trim($_POST['poco_requery_days']))     : 7);
414         $poco_discovery         =       ((x($_POST,'poco_discovery'))           ? intval(trim($_POST['poco_discovery']))        : 0);
415         $poco_discovery_since   =       ((x($_POST,'poco_discovery_since'))     ? intval(trim($_POST['poco_discovery_since']))  : 30);
416         $poco_local_search      =       ((x($_POST,'poco_local_search'))        ? intval(trim($_POST['poco_local_search']))     : false);
417         $nodeinfo               =       ((x($_POST,'nodeinfo'))                 ? intval(trim($_POST['nodeinfo']))              : false);
418         $dfrn_only              =       ((x($_POST,'dfrn_only'))                ? True                                          : False);
419         $ostatus_disabled       =       !((x($_POST,'ostatus_disabled'))        ? True                                          : False);
420         $ostatus_poll_interval  =       ((x($_POST,'ostatus_poll_interval'))    ? intval(trim($_POST['ostatus_poll_interval'])) :  0);
421         $diaspora_enabled       =       ((x($_POST,'diaspora_enabled'))         ? True                                          : False);
422         $ssl_policy             =       ((x($_POST,'ssl_policy'))               ? intval($_POST['ssl_policy'])                  : 0);
423         $force_ssl              =       ((x($_POST,'force_ssl'))                ? True                                          : False);
424         $old_share              =       ((x($_POST,'old_share'))                ? True                                          : False);
425         $hide_help              =       ((x($_POST,'hide_help'))                ? True                                          : False);
426         $suppress_language      =       ((x($_POST,'suppress_language'))        ? True                                          : False);
427         $suppress_tags          =       ((x($_POST,'suppress_tags'))            ? True                                          : False);
428         $use_fulltext_engine    =       ((x($_POST,'use_fulltext_engine'))      ? True                                          : False);
429         $itemcache              =       ((x($_POST,'itemcache'))                ? notags(trim($_POST['itemcache']))             : '');
430         $itemcache_duration     =       ((x($_POST,'itemcache_duration'))       ? intval($_POST['itemcache_duration'])          : 0);
431         $max_comments           =       ((x($_POST,'max_comments'))             ? intval($_POST['max_comments'])                : 0);
432         $lockpath               =       ((x($_POST,'lockpath'))                 ? notags(trim($_POST['lockpath']))              : '');
433         $temppath               =       ((x($_POST,'temppath'))                 ? notags(trim($_POST['temppath']))              : '');
434         $basepath               =       ((x($_POST,'basepath'))                 ? notags(trim($_POST['basepath']))              : '');
435         $singleuser             =       ((x($_POST,'singleuser'))               ? notags(trim($_POST['singleuser']))            : '');
436         $proxy_disabled         =       ((x($_POST,'proxy_disabled'))           ? True                                          : False);
437         $old_pager              =       ((x($_POST,'old_pager'))                ? True                                          : False);
438         $only_tag_search        =       ((x($_POST,'only_tag_search'))          ? True                                          : False);
439         $rino                   =       ((x($_POST,'rino'))                             ? intval($_POST['rino'])                                : 0);
440         $embedly                =       ((x($_POST,'embedly'))                  ? notags(trim($_POST['embedly']))               : '');
441
442         if ($a->get_path() != "")
443                 $diaspora_enabled = false;
444
445         if (!$thread_allow)
446                 $ostatus_disabled = true;
447
448         if($ssl_policy != intval(get_config('system','ssl_policy'))) {
449                 if($ssl_policy == SSL_POLICY_FULL) {
450                         q("update `contact` set
451                                 `url`     = replace(`url`    , 'http:' , 'https:'),
452                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
453                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:'),
454                                 `micro`   = replace(`micro`  , 'http:' , 'https:'),
455                                 `request` = replace(`request`, 'http:' , 'https:'),
456                                 `notify`  = replace(`notify` , 'http:' , 'https:'),
457                                 `poll`    = replace(`poll`   , 'http:' , 'https:'),
458                                 `confirm` = replace(`confirm`, 'http:' , 'https:'),
459                                 `poco`    = replace(`poco`   , 'http:' , 'https:')
460                                 where `self` = 1"
461                         );
462                         q("update `profile` set
463                                 `photo`   = replace(`photo`  , 'http:' , 'https:'),
464                                 `thumb`   = replace(`thumb`  , 'http:' , 'https:')
465                                 where 1 "
466                         );
467                 }
468                 elseif($ssl_policy == SSL_POLICY_SELFSIGN) {
469                         q("update `contact` set
470                                 `url`     = replace(`url`    , 'https:' , 'http:'),
471                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
472                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:'),
473                                 `micro`   = replace(`micro`  , 'https:' , 'http:'),
474                                 `request` = replace(`request`, 'https:' , 'http:'),
475                                 `notify`  = replace(`notify` , 'https:' , 'http:'),
476                                 `poll`    = replace(`poll`   , 'https:' , 'http:'),
477                                 `confirm` = replace(`confirm`, 'https:' , 'http:'),
478                                 `poco`    = replace(`poco`   , 'https:' , 'http:')
479                                 where `self` = 1"
480                         );
481                         q("update `profile` set
482                                 `photo`   = replace(`photo`  , 'https:' , 'http:'),
483                                 `thumb`   = replace(`thumb`  , 'https:' , 'http:')
484                                 where 1 "
485                         );
486                 }
487         }
488         set_config('system','ssl_policy',$ssl_policy);
489         set_config('system','delivery_interval',$delivery_interval);
490         set_config('system','poll_interval',$poll_interval);
491         set_config('system','maxloadavg',$maxloadavg);
492         set_config('system','maxloadavg_frontend',$maxloadavg_frontend);
493         set_config('system','poco_completion',$poco_completion);
494         set_config('system','poco_requery_days',$poco_requery_days);
495         set_config('system','poco_discovery',$poco_discovery);
496         set_config('system','poco_discovery_since',$poco_discovery_since);
497         set_config('system','poco_local_search',$poco_local_search);
498         set_config('system','nodeinfo',$nodeinfo);
499         set_config('config','sitename',$sitename);
500         set_config('config','hostname',$hostname);
501         set_config('config','sender_email', $sender_email);
502         set_config('system','suppress_language',$suppress_language);
503         set_config('system','suppress_tags',$suppress_tags);
504         set_config('system','shortcut_icon',$shortcut_icon);
505         set_config('system','touch_icon',$touch_icon);
506
507         if ($banner==""){
508                 // don't know why, but del_config doesn't work...
509                 q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
510                         dbesc("system"),
511                         dbesc("banner")
512                 );
513         } else {
514                 set_config('system','banner', $banner);
515         }
516         if ($info=="") {
517                 del_config('config','info');
518         } else {
519                 set_config('config','info',$info);
520         }
521         set_config('system','language', $language);
522         set_config('system','theme', $theme);
523         if ( $theme_mobile === '---' ) {
524                 del_config('system','mobile-theme');
525         } else {
526                 set_config('system','mobile-theme', $theme_mobile);
527                 }
528                 if ( $singleuser === '---' ) {
529                         del_config('system','singleuser');
530                 } else {
531                         set_config('system','singleuser', $singleuser);
532                 }
533         set_config('system','maximagesize', $maximagesize);
534         set_config('system','max_image_length', $maximagelength);
535         set_config('system','jpeg_quality', $jpegimagequality);
536
537         set_config('config','register_policy', $register_policy);
538         set_config('system','max_daily_registrations', $daily_registrations);
539         set_config('system','account_abandon_days', $abandon_days);
540         set_config('config','register_text', $register_text);
541         set_config('system','allowed_sites', $allowed_sites);
542         set_config('system','allowed_email', $allowed_email);
543         set_config('system','block_public', $block_public);
544         set_config('system','publish_all', $force_publish);
545         set_config('system','directory', $global_directory);
546         set_config('system','thread_allow', $thread_allow);
547         set_config('system','newuser_private', $newuser_private);
548         set_config('system','enotify_no_content', $enotify_no_content);
549         set_config('system','disable_embedded', $disable_embedded);
550         set_config('system','allow_users_remote_self', $allow_users_remote_self);
551
552         set_config('system','block_extended_register', $no_multi_reg);
553         set_config('system','no_openid', $no_openid);
554         set_config('system','no_regfullname', $no_regfullname);
555         set_config('system','community_page_style', $community_page_style);
556         set_config('system','max_author_posts_community_page', $max_author_posts_community_page);
557         set_config('system','no_utf', $no_utf);
558         set_config('system','verifyssl', $verifyssl);
559         set_config('system','proxyuser', $proxyuser);
560         set_config('system','proxy', $proxy);
561         set_config('system','curl_timeout', $timeout);
562         set_config('system','dfrn_only', $dfrn_only);
563         set_config('system','ostatus_disabled', $ostatus_disabled);
564         set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
565         set_config('system','diaspora_enabled', $diaspora_enabled);
566
567         set_config('config','private_addons', $private_addons);
568
569         set_config('system','force_ssl', $force_ssl);
570         set_config('system','old_share', $old_share);
571         set_config('system','hide_help', $hide_help);
572         set_config('system','use_fulltext_engine', $use_fulltext_engine);
573         set_config('system','itemcache', $itemcache);
574         set_config('system','itemcache_duration', $itemcache_duration);
575         set_config('system','max_comments', $max_comments);
576         set_config('system','lockpath', $lockpath);
577         set_config('system','temppath', $temppath);
578         set_config('system','basepath', $basepath);
579         set_config('system','proxy_disabled', $proxy_disabled);
580         set_config('system','old_pager', $old_pager);
581         set_config('system','only_tag_search', $only_tag_search);
582
583
584         if ($rino==2 and !function_exists('mcrypt_create_iv')){
585                 notice(t("RINO2 needs mcrypt php extension to work."));
586         } else {
587                 set_config('system','rino_encrypt', $rino);
588         }
589
590         set_config('system','embedly', $embedly);
591
592
593         info( t('Site settings updated.') . EOL);
594         goaway($a->get_baseurl(true) . '/admin/site' );
595         return; // NOTREACHED
596
597 }
598
599 /**
600  * @param  App $a
601  * @return string
602  */
603 function admin_page_site(&$a) {
604
605         /* Installed langs */
606         $lang_choices = get_avaiable_languages();
607
608         if (strlen(get_config('system','directory_submit_url')) AND
609                 !strlen(get_config('system','directory'))) {
610                 set_config('system','directory', dirname(get_config('system','directory_submit_url')));
611                 del_config('system','directory_submit_url');
612         }
613
614         /* Installed themes */
615         $theme_choices = array();
616         $theme_choices_mobile = array();
617         $theme_choices_mobile["---"] = t("No special theme for mobile devices");
618         $files = glob('view/theme/*'); /**/
619         if($files) {
620                 foreach($files as $file) {
621                         if (intval(file_exists($file . '/unsupported')))
622                                 continue;
623
624                         $f = basename($file);
625                         $theme_name = ((file_exists($file . '/experimental')) ?  sprintf("%s - \x28Experimental\x29", $f) : $f);
626                         if (file_exists($file . '/mobile')) {
627                                 $theme_choices_mobile[$f] = $theme_name;
628                         } else {
629                                 $theme_choices[$f] = $theme_name;
630                         }
631                 }
632         }
633
634         /* Community page style */
635         $community_page_style_choices = array(
636                 CP_NO_COMMUNITY_PAGE => t("No community page"),
637                 CP_USERS_ON_SERVER => t("Public postings from users of this site"),
638                 CP_GLOBAL_COMMUNITY => t("Global community page")
639                 );
640
641         /* OStatus conversation poll choices */
642         $ostatus_poll_choices = array(
643                 "-2" => t("Never"),
644                 "-1" => t("At post arrival"),
645                 "0" => t("Frequently"),
646                 "60" => t("Hourly"),
647                 "720" => t("Twice daily"),
648                 "1440" => t("Daily")
649                 );
650
651         $poco_discovery_choices = array(
652                 "0" => t("Disabled"),
653                 "1" => t("Users"),
654                 "2" => t("Users, Global Contacts"),
655                 "3" => t("Users, Global Contacts/fallback"),
656                 );
657
658         $poco_discovery_since_choices = array(
659                 "30" => t("One month"),
660                 "91" => t("Three months"),
661                 "182" => t("Half a year"),
662                 "365" => t("One year"),
663                 );
664
665         /* get user names to make the install a personal install of X */
666         $user_names = array();
667         $user_names['---'] = t('Multi user instance');
668         $users = q("SELECT username, nickname FROM `user`");
669         foreach ($users as $user) {
670                 $user_names[$user['nickname']] = $user['username'];
671         }
672
673         /* Banner */
674         $banner = get_config('system','banner');
675         if($banner == false)
676                 $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>';
677         $banner = htmlspecialchars($banner);
678         $info = get_config('config','info');
679         $info = htmlspecialchars($info);
680
681         // Automatically create temporary paths
682         get_temppath();
683         get_lockpath();
684         get_itemcachepath();
685
686         //echo "<pre>"; var_dump($lang_choices); die("</pre>");
687
688         /* Register policy */
689         $register_choices = Array(
690                 REGISTER_CLOSED => t("Closed"),
691                 REGISTER_APPROVE => t("Requires approval"),
692                 REGISTER_OPEN => t("Open")
693         );
694
695         $ssl_choices = array(
696                 SSL_POLICY_NONE => t("No SSL policy, links will track page SSL state"),
697                 SSL_POLICY_FULL => t("Force all links to use SSL"),
698                 SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)")
699         );
700
701         if ($a->config['hostname'] == "")
702                 $a->config['hostname'] = $a->get_hostname();
703
704         $diaspora_able = ($a->get_path() == "");
705
706         $t = get_markup_template("admin_site.tpl");
707         return replace_macros($t, array(
708                 '$title' => t('Administration'),
709                 '$page' => t('Site'),
710                 '$submit' => t('Save Settings'),
711                 '$registration' => t('Registration'),
712                 '$upload' => t('File upload'),
713                 '$corporate' => t('Policies'),
714                 '$advanced' => t('Advanced'),
715                 '$portable_contacts' => t('Auto Discovered Contact Directory'),
716                 '$performance' => t('Performance'),
717                 '$relocate'=> t('Relocate - WARNING: advanced function. Could make this server unreachable.'),
718                 '$baseurl' => $a->get_baseurl(true),
719                 // name, label, value, help string, extra data...
720                 '$sitename'             => array('sitename', t("Site name"), $a->config['sitename'],''),
721                 '$hostname'             => array('hostname', t("Host name"), $a->config['hostname'], ""),
722                 '$sender_email'         => array('sender_email', t("Sender Email"), $a->config['sender_email'], t("The email address your server shall use to send notification emails from."), "", "", "email"),
723                 '$banner'               => array('banner', t("Banner/Logo"), $banner, ""),
724                 '$shortcut_icon'        => array('shortcut_icon', t("Shortcut icon"), get_config('system','shortcut_icon'),  t("Link to an icon that will be used for browsers.")),
725                 '$touch_icon'           => array('touch_icon', t("Touch icon"), get_config('system','touch_icon'),  t("Link to an icon that will be used for tablets and mobiles.")),
726                 '$info' => array('info',t('Additional Info'), $info, sprintf(t('For public servers: you can add additional information here that will be listed at %s/siteinfo.'), get_server())),
727                 '$language'             => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
728                 '$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),
729                 '$theme_mobile'         => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
730                 '$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),
731                 '$force_ssl'            => array('force_ssl', t("Force SSL"), get_config('system','force_ssl'), t("Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.")),
732                 '$old_share'            => array('old_share', t("Old style 'Share'"), get_config('system','old_share'), t("Deactivates the bbcode element 'share' for repeating items.")),
733                 '$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.")),
734                 '$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),
735                 '$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.")),
736                 '$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.")),
737                 '$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.")),
738
739                 '$register_policy'      => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
740                 '$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.")),
741                 '$register_text'        => array('register_text', t("Register text"), $a->config['register_text'], t("Will be displayed prominently on the registration page.")),
742                 '$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.')),
743                 '$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")),
744                 '$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")),
745                 '$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.")),
746                 '$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.")),
747                 '$global_directory'     => array('directory', t("Global directory URL"), get_config('system','directory'), t("URL to the global directory. If this is not set, the global directory is completely unavailable to the application.")),
748                 '$thread_allow'         => array('thread_allow', t("Allow threaded items"), get_config('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
749                 '$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.")),
750                 '$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.")),
751                 '$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.")),
752                 '$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.")),
753                 '$allow_users_remote_self'      => array('allow_users_remote_self', t('Allow Users to set remote_self'), get_config('system','allow_users_remote_self'), t('With checking this, every user is allowed to mark every contact as a remote_self in the repair contact dialog. Setting this flag on a contact causes mirroring every posting of that contact in the users stream.')),
754                 '$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.")),
755                 '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
756                 '$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")),
757                 '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
758                 '$community_page_style' => array('community_page_style', t("Community Page Style"), get_config('system','community_page_style'), t("Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."), $community_page_style_choices),
759                 '$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")),
760                 '$ostatus_disabled'     => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),
761                 '$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),
762                 '$ostatus_not_able'     => t("OStatus support can only be enabled if threading is enabled."),
763                 '$diaspora_able'        => $diaspora_able,
764                 '$diaspora_not_able'    => t("Diaspora support can't be enabled because Friendica was installed into a sub directory."),
765                 '$diaspora_enabled'     => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
766                 '$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.")),
767                 '$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.")),
768                 '$proxyuser'            => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
769                 '$proxy'                => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
770                 '$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).")),
771                 '$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.")),
772                 '$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.")),
773                 '$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.")),
774                 '$maxloadavg_frontend'  => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(get_config('system','maxloadavg_frontend')) > 0)?get_config('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")),
775
776                 '$poco_completion'      => array('poco_completion', t("Periodical check of global contacts"), get_config('system','poco_completion'), t("If enabled, the global contacts are checked periodically for missing or outdated data and the vitality of the contacts and servers.")),
777                 '$poco_requery_days'    => array('poco_requery_days', t("Days between requery"), get_config('system','poco_requery_days'), t("Number of days after which a server is requeried for his contacts.")),
778                 '$poco_discovery'       => array('poco_discovery', t("Discover contacts from other servers"), (string) intval(get_config('system','poco_discovery')), t("Periodically query other servers for contacts. You can choose between 'users': the users on the remote system, 'Global Contacts': active contacts that are known on the system. The fallback is meant for Redmatrix servers and older friendica servers, where global contacts weren't available. The fallback increases the server load, so the recommened setting is 'Users, Global Contacts'."), $poco_discovery_choices),
779                 '$poco_discovery_since' => array('poco_discovery_since', t("Timeframe for fetching global contacts"), (string) intval(get_config('system','poco_discovery_since')), t("When the discovery is activated, this value defines the timeframe for the activity of the global contacts that are fetched from other servers."), $poco_discovery_since_choices),
780                 '$poco_local_search'    => array('poco_local_search', t("Search the local directory"), get_config('system','poco_local_search'), t("Search the local directory instead of the global directory. When searching locally, every search will be executed on the global directory in the background. This improves the search results when the search is repeated.")),
781
782                 '$nodeinfo'             => array('nodeinfo', t("Publish server information"), get_config('system','nodeinfo'), t("If enabled, general server and usage data will be published. The data contains the name and version of the server, number of users with public profiles, number of posts and the activated protocols and connectors. See <a href='http://the-federation.info/'>the-federation.info</a> for details.")),
783
784                 '$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.")),
785                 '$suppress_language'    => array('suppress_language', t("Suppress Language"), get_config('system','suppress_language'), t("Suppress language information in meta information about a posting.")),
786                 '$suppress_tags'        => array('suppress_tags', t("Suppress Tags"), get_config('system','suppress_tags'), t("Suppress showing a list of hashtags at the end of the posting.")),
787                 '$itemcache'            => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), t("The item caches buffers generated bbcode and external images.")),
788                 '$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). To disable the item cache, set the value to -1.")),
789                 '$max_comments'         => array('max_comments', t("Maximum numbers of comments per post"), get_config('system','max_comments'), t("How much comments should be shown for each post? Default value is 100.")),
790                 '$lockpath'             => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), t("The lock file is used to avoid multiple pollers at one time. Only define a folder here.")),
791                 '$temppath'             => array('temppath', t("Temp path"), get_config('system','temppath'), t("If you have a restricted system where the webserver can't access the system temp path, enter another path here.")),
792                 '$basepath'             => array('basepath', t("Base path to installation"), get_config('system','basepath'), t("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.")),
793                 '$proxy_disabled'       => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")),
794                 '$old_pager'            => array('old_pager', t("Enable old style pager"), get_config('system','old_pager'), t("The old style pager has page numbers but slows down massively the page speed.")),
795                 '$only_tag_search'      => array('only_tag_search', t("Only search in tags"), get_config('system','only_tag_search'), t("On large systems the text search can slow down the system extremely.")),
796
797                 '$relocate_url'         => array('relocate_url', t("New base url"), $a->get_baseurl(), t("Change base url for this server. Sends relocate message to all DFRN contacts of all users.")),
798
799                 '$rino'                 => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
800                 '$embedly'              => array('embedly', t("Embedly API key"), get_config('system','embedly'), t("<a href='http://embed.ly'>Embedly</a> is used to fetch additional data for web pages. This is an optional parameter.")),
801
802                 '$form_security_token' => get_form_security_token("admin_site")
803
804         ));
805
806 }
807
808
809 function admin_page_dbsync(&$a) {
810
811         $o = '';
812
813         if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
814                 set_config('database', 'update_' . intval($a->argv[3]), 'success');
815                 $curr = get_config('system','build');
816                 if(intval($curr) == intval($a->argv[3]))
817                         set_config('system','build',intval($curr) + 1);
818                 info( t('Update has been marked successful') . EOL);
819                 goaway($a->get_baseurl(true) . '/admin/dbsync');
820         }
821
822         if(($a->argc > 2) AND (intval($a->argv[2]) OR ($a->argv[2] === 'check'))) {
823                 require_once("include/dbstructure.php");
824                 $retval = update_structure(false, true);
825                 if (!$retval) {
826                         $o .= sprintf(t("Database structure update %s was successfully applied."), DB_UPDATE_VERSION)."<br />";
827                         set_config('database', 'dbupdate_'.DB_UPDATE_VERSION, 'success');
828                 } else
829                         $o .= sprintf(t("Executing of database structure update %s failed with error: %s"),
830                                         DB_UPDATE_VERSION, $retval)."<br />";
831                 if ($a->argv[2] === 'check')
832                         return $o;
833         }
834
835         if ($a->argc > 2 && intval($a->argv[2])) {
836                 require_once('update.php');
837                 $func = 'update_' . intval($a->argv[2]);
838                 if(function_exists($func)) {
839                         $retval = $func();
840                         if($retval === UPDATE_FAILED) {
841                                 $o .= sprintf(t("Executing %s failed with error: %s"), $func, $retval);
842                         }
843                         elseif($retval === UPDATE_SUCCESS) {
844                                 $o .= sprintf(t('Update %s was successfully applied.', $func));
845                                 set_config('database',$func, 'success');
846                         }
847                         else
848                                 $o .= sprintf(t('Update %s did not return a status. Unknown if it succeeded.'), $func);
849                 } else {
850                         $o .= sprintf(t('There was no additional update function %s that needed to be called.'), $func)."<br />";
851                         set_config('database',$func, 'success');
852                 }
853                 return $o;
854         }
855
856         $failed = array();
857         $r = q("select k, v from config where `cat` = 'database' ");
858         if(count($r)) {
859                 foreach($r as $rr) {
860                         $upd = intval(substr($rr['k'],7));
861                         if($upd < 1139 || $rr['v'] === 'success')
862                                 continue;
863                         $failed[] = $upd;
864                 }
865         }
866         if(! count($failed)) {
867                 $o = replace_macros(get_markup_template('structure_check.tpl'),array(
868                         '$base' => $a->get_baseurl(true),
869                         '$banner' => t('No failed updates.'),
870                         '$check' => t('Check database structure'),
871                 ));
872         } else {
873                 $o = replace_macros(get_markup_template('failed_updates.tpl'),array(
874                         '$base' => $a->get_baseurl(true),
875                         '$banner' => t('Failed Updates'),
876                         '$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
877                         '$mark' => t('Mark success (if update was manually applied)'),
878                         '$apply' => t('Attempt to execute this update step automatically'),
879                         '$failed' => $failed
880                 ));
881         }
882
883         return $o;
884
885 }
886
887 /**
888  * Users admin page
889  *
890  * @param App $a
891  */
892 function admin_page_users_post(&$a){
893         $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() );
894         $users = ( x($_POST, 'user') ? $_POST['user'] : Array() );
895         $nu_name = ( x($_POST, 'new_user_name') ? $_POST['new_user_name'] : '');
896         $nu_nickname = ( x($_POST, 'new_user_nickname') ? $_POST['new_user_nickname'] : '');
897         $nu_email = ( x($_POST, 'new_user_email') ? $_POST['new_user_email'] : '');
898
899         check_form_security_token_redirectOnErr('/admin/users', 'admin_users');
900
901         if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) {
902                 require_once('include/user.php');
903
904                 $result = create_user( array('username'=>$nu_name, 'email'=>$nu_email, 'nickname'=>$nu_nickname, 'verified'=>1)  );
905                 if(! $result['success']) {
906                         notice($result['message']);
907                         return;
908                 }
909                 $nu = $result['user'];
910                 $preamble = deindent(t('
911                         Dear %1$s,
912                                 the administrator of %2$s has set up an account for you.'));
913                 $body = deindent(t('
914                         The login details are as follows:
915
916                         Site Location:  %1$s
917                         Login Name:             %2$s
918                         Password:               %3$s
919
920                         You may change your password from your account "Settings" page after logging
921                         in.
922
923                         Please take a few moments to review the other account settings on that page.
924
925                         You may also wish to add some basic information to your default profile
926                         (on the "Profiles" page) so that other people can easily find you.
927
928                         We recommend setting your full name, adding a profile photo,
929                         adding some profile "keywords" (very useful in making new friends) - and
930                         perhaps what country you live in; if you do not wish to be more specific
931                         than that.
932
933                         We fully respect your right to privacy, and none of these items are necessary.
934                         If you are new and do not know anybody here, they may help
935                         you to make some new and interesting friends.
936
937                         Thank you and welcome to %4$s.'));
938
939                 $preamble = sprintf($preamble, $nu['username'], $a->config['sitename']);
940                 $body = sprintf($body, $a->get_baseurl(), $nu['email'], $result['password'], $a->config['sitename']);
941
942                 notification(array(
943                         'type' => "SYSTEM_EMAIL",
944                         'to_email' => $nu['email'],
945                         'subject'=> sprintf( t('Registration details for %s'), $a->config['sitename']),
946                         'preamble'=> $preamble,
947                         'body' => $body));
948
949         }
950
951         if (x($_POST,'page_users_block')){
952                 foreach($users as $uid){
953                         q("UPDATE `user` SET `blocked`=1-`blocked` WHERE `uid`=%s",
954                                 intval( $uid )
955                         );
956                 }
957                 notice( sprintf( tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)) );
958         }
959         if (x($_POST,'page_users_delete')){
960                 require_once("include/Contact.php");
961                 foreach($users as $uid){
962                         user_remove($uid);
963                 }
964                 notice( sprintf( tt("%s user deleted", "%s users deleted", count($users)), count($users)) );
965         }
966
967         if (x($_POST,'page_users_approve')){
968                 require_once("mod/regmod.php");
969                 foreach($pending as $hash){
970                         user_allow($hash);
971                 }
972         }
973         if (x($_POST,'page_users_deny')){
974                 require_once("mod/regmod.php");
975                 foreach($pending as $hash){
976                         user_deny($hash);
977                 }
978         }
979         goaway($a->get_baseurl(true) . '/admin/users' );
980         return; // NOTREACHED
981 }
982
983 /**
984  * @param App $a
985  * @return string
986  */
987 function admin_page_users(&$a){
988         if ($a->argc>2) {
989                 $uid = $a->argv[3];
990                 $user = q("SELECT username, blocked FROM `user` WHERE `uid`=%d", intval($uid));
991                 if (count($user)==0){
992                         notice( 'User not found' . EOL);
993                         goaway($a->get_baseurl(true) . '/admin/users' );
994                         return ''; // NOTREACHED
995                 }
996                 switch($a->argv[2]){
997                         case "delete":{
998                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
999                                 // delete user
1000                                 require_once("include/Contact.php");
1001                                 user_remove($uid);
1002
1003                                 notice( sprintf(t("User '%s' deleted"), $user[0]['username']) . EOL);
1004                         }; break;
1005                         case "block":{
1006                                 check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
1007                                 q("UPDATE `user` SET `blocked`=%d WHERE `uid`=%s",
1008                                         intval( 1-$user[0]['blocked'] ),
1009                                         intval( $uid )
1010                                 );
1011                                 notice( sprintf( ($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']) . EOL);
1012                         }; break;
1013                 }
1014                 goaway($a->get_baseurl(true) . '/admin/users' );
1015                 return ''; // NOTREACHED
1016
1017         }
1018
1019         /* get pending */
1020         $pending = q("SELECT `register`.*, `contact`.`name`, `user`.`email`
1021                                  FROM `register`
1022                                  LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid`
1023                                  LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;");
1024
1025
1026         /* get users */
1027
1028         $total = q("SELECT count(*) as total FROM `user` where 1");
1029         if(count($total)) {
1030                 $a->set_pager_total($total[0]['total']);
1031                 $a->set_pager_itemspage(100);
1032         }
1033
1034
1035         $users = q("SELECT `user` . * , `contact`.`name` , `contact`.`url` , `contact`.`micro`, `lastitem`.`lastitem_date`, `user`.`account_expired`
1036                                 FROM
1037                                         (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid`
1038                                         FROM `item`
1039                                         WHERE `item`.`type` = 'wall'
1040                                         GROUP BY `item`.`uid`) AS `lastitem`
1041                                                  RIGHT OUTER JOIN `user` ON `user`.`uid` = `lastitem`.`uid`,
1042                                            `contact`
1043                                 WHERE
1044                                            `user`.`uid` = `contact`.`uid`
1045                                                 AND `user`.`verified` =1
1046                                         AND `contact`.`self` =1
1047                                 ORDER BY `contact`.`name` LIMIT %d, %d
1048                                 ",
1049                                 intval($a->pager['start']),
1050                                 intval($a->pager['itemspage'])
1051                                 );
1052
1053         $adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
1054         $_setup_users = function ($e) use ($adminlist){
1055                 $accounts = Array(
1056                         t('Normal Account'),
1057                         t('Soapbox Account'),
1058                         t('Community/Celebrity Account'),
1059                                                 t('Automatic Friend Account')
1060                 );
1061                 $e['page-flags'] = $accounts[$e['page-flags']];
1062                 $e['register_date'] = relative_date($e['register_date']);
1063                 $e['login_date'] = relative_date($e['login_date']);
1064                 $e['lastitem_date'] = relative_date($e['lastitem_date']);
1065                 //$e['is_admin'] = ($e['email'] === $a->config['admin_email']);
1066                 $e['is_admin'] = in_array($e['email'], $adminlist);
1067                 $e['is_deletable'] = (intval($e['uid']) != local_user());
1068                 $e['deleted'] = ($e['account_removed']?relative_date($e['account_expires_on']):False);
1069                 return $e;
1070         };
1071         $users = array_map($_setup_users, $users);
1072
1073
1074         // Get rid of dashes in key names, Smarty3 can't handle them
1075         // and extracting deleted users
1076
1077         $tmp_users = Array();
1078         $deleted = Array();
1079
1080         while(count($users)) {
1081                 $new_user = Array();
1082                 foreach( array_pop($users) as $k => $v) {
1083                         $k = str_replace('-','_',$k);
1084                         $new_user[$k] = $v;
1085                 }
1086                 if($new_user['deleted']) {
1087                         array_push($deleted, $new_user);
1088                 }
1089                 else {
1090                         array_push($tmp_users, $new_user);
1091                 }
1092         }
1093         //Reversing the two array, and moving $tmp_users to $users
1094         array_reverse($deleted);
1095         while(count($tmp_users)) {
1096                 array_push($users, array_pop($tmp_users));
1097         }
1098
1099         $t = get_markup_template("admin_users.tpl");
1100         $o = replace_macros($t, array(
1101                 // strings //
1102                 '$title' => t('Administration'),
1103                 '$page' => t('Users'),
1104                 '$submit' => t('Add User'),
1105                 '$select_all' => t('select all'),
1106                 '$h_pending' => t('User registrations waiting for confirm'),
1107                 '$h_deleted' => t('User waiting for permanent deletion'),
1108                 '$th_pending' => array( t('Request date'), t('Name'), t('Email') ),
1109                 '$no_pending' =>  t('No registrations.'),
1110                 '$approve' => t('Approve'),
1111                 '$deny' => t('Deny'),
1112                 '$delete' => t('Delete'),
1113                 '$block' => t('Block'),
1114                 '$unblock' => t('Unblock'),
1115                 '$siteadmin' => t('Site admin'),
1116                 '$accountexpired' => t('Account expired'),
1117
1118                 '$h_users' => t('Users'),
1119                 '$h_newuser' => t('New User'),
1120                 '$th_deleted' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'), t('Deleted since') ),
1121                 '$th_users' => array( t('Name'), t('Email'), t('Register date'), t('Last login'), t('Last item'),  t('Account') ),
1122
1123                 '$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?'),
1124                 '$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?'),
1125
1126                 '$form_security_token' => get_form_security_token("admin_users"),
1127
1128                 // values //
1129                 '$baseurl' => $a->get_baseurl(true),
1130
1131                 '$pending' => $pending,
1132                 'deleted' => $deleted,
1133                 '$users' => $users,
1134                 '$newusername'  => array('new_user_name', t("Name"), '', t("Name of the new user.")),
1135                 '$newusernickname'  => array('new_user_nickname', t("Nickname"), '', t("Nickname of the new user.")),
1136                 '$newuseremail'  => array('new_user_email', t("Email"), '', t("Email address of the new user."), '', '', 'email'),
1137         ));
1138         $o .= paginate($a);
1139         return $o;
1140 }
1141
1142
1143 /**
1144  * Plugins admin page
1145  *
1146  * @param App $a
1147  * @return string
1148  */
1149 function admin_page_plugins(&$a){
1150
1151         /**
1152          * Single plugin
1153          */
1154         if ($a->argc == 3){
1155                 $plugin = $a->argv[2];
1156                 if (!is_file("addon/$plugin/$plugin.php")){
1157                         notice( t("Item not found.") );
1158                         return '';
1159                 }
1160
1161                 if (x($_GET,"a") && $_GET['a']=="t"){
1162                         check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
1163
1164                         // Toggle plugin status
1165                         $idx = array_search($plugin, $a->plugins);
1166                         if ($idx !== false){
1167                                 unset($a->plugins[$idx]);
1168                                 uninstall_plugin($plugin);
1169                                 info( sprintf( t("Plugin %s disabled."), $plugin ) );
1170                         } else {
1171                                 $a->plugins[] = $plugin;
1172                                 install_plugin($plugin);
1173                                 info( sprintf( t("Plugin %s enabled."), $plugin ) );
1174                         }
1175                         set_config("system","addon", implode(", ",$a->plugins));
1176                         goaway($a->get_baseurl(true) . '/admin/plugins' );
1177                         return ''; // NOTREACHED
1178                 }
1179                 // display plugin details
1180                 require_once('library/markdown.php');
1181
1182                 if (in_array($plugin, $a->plugins)){
1183                         $status="on"; $action= t("Disable");
1184                 } else {
1185                         $status="off"; $action= t("Enable");
1186                 }
1187
1188                 $readme=Null;
1189                 if (is_file("addon/$plugin/README.md")){
1190                         $readme = file_get_contents("addon/$plugin/README.md");
1191                         $readme = Markdown($readme);
1192                 } else if (is_file("addon/$plugin/README")){
1193                         $readme = "<pre>". file_get_contents("addon/$plugin/README") ."</pre>";
1194                 }
1195
1196                 $admin_form="";
1197                 if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){
1198                         @require_once("addon/$plugin/$plugin.php");
1199                         $func = $plugin.'_plugin_admin';
1200                         $func($a, $admin_form);
1201                 }
1202
1203                 $t = get_markup_template("admin_plugins_details.tpl");
1204
1205                 return replace_macros($t, array(
1206                         '$title' => t('Administration'),
1207                         '$page' => t('Plugins'),
1208                         '$toggle' => t('Toggle'),
1209                         '$settings' => t('Settings'),
1210                         '$baseurl' => $a->get_baseurl(true),
1211
1212                         '$plugin' => $plugin,
1213                         '$status' => $status,
1214                         '$action' => $action,
1215                         '$info' => get_plugin_info($plugin),
1216                         '$str_author' => t('Author: '),
1217                         '$str_maintainer' => t('Maintainer: '),
1218
1219                         '$admin_form' => $admin_form,
1220                         '$function' => 'plugins',
1221                         '$screenshot' => '',
1222                         '$readme' => $readme,
1223
1224                         '$form_security_token' => get_form_security_token("admin_themes"),
1225                 ));
1226         }
1227
1228
1229
1230         /**
1231          * List plugins
1232          */
1233
1234         if (x($_GET,"a") && $_GET['a']=="r"){
1235                 check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/plugins', 'admin_themes', 't');
1236                 reload_plugins();
1237                 info("Plugins reloaded");
1238                 goaway($a->get_baseurl().'/admin/plugins');
1239         }
1240
1241         $plugins = array();
1242         $files = glob("addon/*/"); /* */
1243         if($files) {
1244                 foreach($files as $file) {
1245                         if (is_dir($file)){
1246                                 list($tmp, $id)=array_map("trim", explode("/",$file));
1247                                 $info = get_plugin_info($id);
1248                                 $show_plugin = true;
1249
1250                                 // If the addon is unsupported, then only show it, when it is enabled
1251                                 if ((strtolower($info["status"]) == "unsupported") AND !in_array($id,  $a->plugins))
1252                                         $show_plugin = false;
1253
1254                                 // Override the above szenario, when the admin really wants to see outdated stuff
1255                                 if (get_config("system", "show_unsupported_addons"))
1256                                         $show_plugin = true;
1257
1258                                 if ($show_plugin)
1259                                         $plugins[] = array($id, (in_array($id,  $a->plugins)?"on":"off") , $info);
1260                         }
1261                 }
1262         }
1263
1264         $t = get_markup_template("admin_plugins.tpl");
1265         return replace_macros($t, array(
1266                 '$title' => t('Administration'),
1267                 '$page' => t('Plugins'),
1268                 '$submit' => t('Save Settings'),
1269                 '$reload' => t('Reload active plugins'),
1270                 '$baseurl' => $a->get_baseurl(true),
1271                 '$function' => 'plugins',
1272                 '$plugins' => $plugins,
1273                 '$form_security_token' => get_form_security_token("admin_themes"),
1274         ));
1275 }
1276
1277 /**
1278  * @param array $themes
1279  * @param string $th
1280  * @param int $result
1281  */
1282 function toggle_theme(&$themes,$th,&$result) {
1283         for($x = 0; $x < count($themes); $x ++) {
1284                 if($themes[$x]['name'] === $th) {
1285                         if($themes[$x]['allowed']) {
1286                                 $themes[$x]['allowed'] = 0;
1287                                 $result = 0;
1288                         }
1289                         else {
1290                                 $themes[$x]['allowed'] = 1;
1291                                 $result = 1;
1292                         }
1293                 }
1294         }
1295 }
1296
1297 /**
1298  * @param array $themes
1299  * @param string $th
1300  * @return int
1301  */
1302 function theme_status($themes,$th) {
1303         for($x = 0; $x < count($themes); $x ++) {
1304                 if($themes[$x]['name'] === $th) {
1305                         if($themes[$x]['allowed']) {
1306                                 return 1;
1307                         }
1308                         else {
1309                                 return 0;
1310                         }
1311                 }
1312         }
1313         return 0;
1314 }
1315
1316
1317 /**
1318  * @param array $themes
1319  * @return string
1320  */
1321 function rebuild_theme_table($themes) {
1322         $o = '';
1323         if(count($themes)) {
1324                 foreach($themes as $th) {
1325                         if($th['allowed']) {
1326                                 if(strlen($o))
1327                                         $o .= ',';
1328                                 $o .= $th['name'];
1329                         }
1330                 }
1331         }
1332         return $o;
1333 }
1334
1335
1336 /**
1337  * Themes admin page
1338  *
1339  * @param App $a
1340  * @return string
1341  */
1342 function admin_page_themes(&$a){
1343
1344         $allowed_themes_str = get_config('system','allowed_themes');
1345         $allowed_themes_raw = explode(',',$allowed_themes_str);
1346         $allowed_themes = array();
1347         if(count($allowed_themes_raw))
1348                 foreach($allowed_themes_raw as $x)
1349                         if(strlen(trim($x)))
1350                                 $allowed_themes[] = trim($x);
1351
1352         $themes = array();
1353         $files = glob('view/theme/*'); /* */
1354         if($files) {
1355                 foreach($files as $file) {
1356                         $f = basename($file);
1357                         $is_experimental = intval(file_exists($file . '/experimental'));
1358                         $is_supported = 1-(intval(file_exists($file . '/unsupported')));
1359                         $is_allowed = intval(in_array($f,$allowed_themes));
1360
1361                         if ($is_allowed OR $is_supported OR get_config("system", "show_unsupported_themes"))
1362                                 $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed);
1363                 }
1364         }
1365
1366         if(! count($themes)) {
1367                 notice( t('No themes found.'));
1368                 return '';
1369         }
1370
1371         /**
1372          * Single theme
1373          */
1374
1375         if ($a->argc == 3){
1376                 $theme = $a->argv[2];
1377                 if(! is_dir("view/theme/$theme")){
1378                         notice( t("Item not found.") );
1379                         return '';
1380                 }
1381
1382                 if (x($_GET,"a") && $_GET['a']=="t"){
1383                         check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't');
1384
1385                         // Toggle theme status
1386
1387                         toggle_theme($themes,$theme,$result);
1388                         $s = rebuild_theme_table($themes);
1389                         if($result) {
1390                                 install_theme($theme);
1391                                 info( sprintf('Theme %s enabled.',$theme));
1392                         }
1393                         else {
1394                                 uninstall_theme($theme);
1395                                 info( sprintf('Theme %s disabled.',$theme));
1396                         }
1397
1398                         set_config('system','allowed_themes',$s);
1399                         goaway($a->get_baseurl(true) . '/admin/themes' );
1400                         return ''; // NOTREACHED
1401                 }
1402
1403                 // display theme details
1404                 require_once('library/markdown.php');
1405
1406                 if (theme_status($themes,$theme)) {
1407                         $status="on"; $action= t("Disable");
1408                 } else {
1409                         $status="off"; $action= t("Enable");
1410                 }
1411
1412                 $readme=Null;
1413                 if (is_file("view/theme/$theme/README.md")){
1414                         $readme = file_get_contents("view/theme/$theme/README.md");
1415                         $readme = Markdown($readme);
1416                 } else if (is_file("view/theme/$theme/README")){
1417                         $readme = "<pre>". file_get_contents("view/theme/$theme/README") ."</pre>";
1418                 }
1419
1420                 $admin_form="";
1421                 if (is_file("view/theme/$theme/config.php")){
1422                         function __get_theme_admin_form(&$a, $theme) {
1423                                 $orig_theme = $a->theme;
1424                                 $orig_page = $a->page;
1425                                 $orig_session_theme = $_SESSION['theme'];
1426                                 require_once("view/theme/$theme/theme.php");
1427                                 require_once("view/theme/$theme/config.php");
1428                                 $_SESSION['theme'] = $theme;
1429
1430
1431                                 $init = $theme."_init";
1432                                 if(function_exists($init)) $init($a);
1433                                 if(function_exists("theme_admin")){
1434                                         $admin_form = theme_admin($a);
1435                                 }
1436
1437                                 $_SESSION['theme'] = $orig_session_theme;
1438                                 $a->theme = $orig_theme;
1439                                 $a->page = $orig_page;
1440                                 return $admin_form;
1441                         }
1442                         $admin_form = __get_theme_admin_form($a, $theme);
1443                 }
1444
1445                 $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
1446                 if(! stristr($screenshot[0],$theme))
1447                         $screenshot = null;
1448
1449                 $t = get_markup_template("admin_plugins_details.tpl");
1450                 return replace_macros($t, array(
1451                         '$title' => t('Administration'),
1452                         '$page' => t('Themes'),
1453                         '$toggle' => t('Toggle'),
1454                         '$settings' => t('Settings'),
1455                         '$baseurl' => $a->get_baseurl(true),
1456
1457                         '$plugin' => $theme,
1458                         '$status' => $status,
1459                         '$action' => $action,
1460                         '$info' => get_theme_info($theme),
1461                         '$function' => 'themes',
1462                         '$admin_form' => $admin_form,
1463                         '$str_author' => t('Author: '),
1464                         '$str_maintainer' => t('Maintainer: '),
1465                         '$screenshot' => $screenshot,
1466                         '$readme' => $readme,
1467
1468                         '$form_security_token' => get_form_security_token("admin_themes"),
1469                 ));
1470         }
1471
1472
1473         // reload active themes
1474         if (x($_GET,"a") && $_GET['a']=="r"){
1475                 check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/themes', 'admin_themes', 't');
1476                 if ($themes) {
1477                         foreach($themes as $th) {
1478                                 if ($th['allowed']) {
1479                                         uninstall_theme($th['name']);
1480                                         install_theme($th['name']);
1481                                 }
1482                         }
1483                 }
1484                 info("Themes reloaded");
1485                 goaway($a->get_baseurl().'/admin/themes');
1486         }
1487
1488         /**
1489          * List themes
1490          */
1491
1492         $xthemes = array();
1493         if($themes) {
1494                 foreach($themes as $th) {
1495                         $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name']));
1496                 }
1497         }
1498
1499
1500         $t = get_markup_template("admin_plugins.tpl");
1501         return replace_macros($t, array(
1502                 '$title' => t('Administration'),
1503                 '$page' => t('Themes'),
1504                 '$submit' => t('Save Settings'),
1505                 '$reload' => t('Reload active themes'),
1506                 '$baseurl' => $a->get_baseurl(true),
1507                 '$function' => 'themes',
1508                 '$plugins' => $xthemes,
1509                 '$experimental' => t('[Experimental]'),
1510                 '$unsupported' => t('[Unsupported]'),
1511                 '$form_security_token' => get_form_security_token("admin_themes"),
1512         ));
1513 }
1514
1515
1516 /**
1517  * Logs admin page
1518  *
1519  * @param App $a
1520  */
1521
1522 function admin_page_logs_post(&$a) {
1523         if (x($_POST,"page_logs")) {
1524                 check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
1525
1526                 $logfile                =       ((x($_POST,'logfile'))          ? notags(trim($_POST['logfile']))       : '');
1527                 $debugging              =       ((x($_POST,'debugging'))        ? true                                                          : false);
1528                 $loglevel               =       ((x($_POST,'loglevel'))         ? intval(trim($_POST['loglevel']))      : 0);
1529
1530                 set_config('system','logfile', $logfile);
1531                 set_config('system','debugging',  $debugging);
1532                 set_config('system','loglevel', $loglevel);
1533
1534
1535         }
1536
1537         info( t("Log settings updated.") );
1538         goaway($a->get_baseurl(true) . '/admin/logs' );
1539         return; // NOTREACHED
1540 }
1541
1542 /**
1543  * @param App $a
1544  * @return string
1545  */
1546 function admin_page_logs(&$a){
1547
1548         $log_choices = Array(
1549                 LOGGER_NORMAL => 'Normal',
1550                 LOGGER_TRACE => 'Trace',
1551                 LOGGER_DEBUG => 'Debug',
1552                 LOGGER_DATA => 'Data',
1553                 LOGGER_ALL => 'All'
1554         );
1555
1556         $t = get_markup_template("admin_logs.tpl");
1557
1558         $f = get_config('system','logfile');
1559
1560         $data = '';
1561
1562         if(!file_exists($f)) {
1563                 $data = t("Error trying to open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f exist and is
1564 readable.");
1565         }
1566         else {
1567                 $fp = fopen($f, 'r');
1568                 if(!$fp) {
1569                         $data = t("Couldn't open <strong>$f</strong> log file.\r\n<br/>Check to see if file $f is readable.");
1570                 }
1571                 else {
1572                         $fstat = fstat($fp);
1573                         $size = $fstat['size'];
1574                         if($size != 0)
1575                         {
1576                                 if($size > 5000000 || $size < 0)
1577                                         $size = 5000000;
1578                                 $seek = fseek($fp,0-$size,SEEK_END);
1579                                 if($seek === 0) {
1580                                         $data = escape_tags(fread($fp,$size));
1581                                         while(! feof($fp))
1582                                                 $data .= escape_tags(fread($fp,4096));
1583                                 }
1584                         }
1585                         fclose($fp);
1586                 }
1587         }
1588
1589         return replace_macros($t, array(
1590                 '$title' => t('Administration'),
1591                 '$page' => t('Logs'),
1592                 '$submit' => t('Save Settings'),
1593                 '$clear' => t('Clear'),
1594                 '$data' => $data,
1595                 '$baseurl' => $a->get_baseurl(true),
1596                 '$logname' =>  get_config('system','logfile'),
1597
1598                                                                         // name, label, value, help string, extra data...
1599                 '$debugging'            => array('debugging', t("Enable Debugging"),get_config('system','debugging'), ""),
1600                 '$logfile'                      => array('logfile', t("Log file"), get_config('system','logfile'), t("Must be writable by web server. Relative to your Friendica top-level directory.")),
1601                 '$loglevel'             => array('loglevel', t("Log level"), get_config('system','loglevel'), "", $log_choices),
1602
1603                 '$form_security_token' => get_form_security_token("admin_logs"),
1604         ));
1605 }
1606
1607 /**
1608  * @param App $a
1609  */
1610 function admin_page_remoteupdate_post(&$a) {
1611         // this function should be called via ajax post
1612         if(!is_site_admin()) {
1613                 return;
1614         }
1615
1616
1617         if (x($_POST,'remotefile') && $_POST['remotefile']!=""){
1618                 $remotefile = $_POST['remotefile'];
1619                 $ftpdata = (x($_POST['ftphost'])?$_POST:false);
1620                 doUpdate($remotefile, $ftpdata);
1621         } else {
1622                 echo "No remote file to download. Abort!";
1623         }
1624
1625         killme();
1626 }
1627
1628 /**
1629  * @param App $a
1630  * @return string
1631  */
1632 function admin_page_remoteupdate(&$a) {
1633         if(!is_site_admin()) {
1634                 return login(false);
1635         }
1636
1637         $canwrite = canWeWrite();
1638         $canftp = function_exists('ftp_connect');
1639
1640         $needupdate = true;
1641         $u = checkUpdate();
1642         if (!is_array($u)){
1643                 $needupdate = false;
1644                 $u = array('','','');
1645         }
1646
1647         $tpl = get_markup_template("admin_remoteupdate.tpl");
1648         return replace_macros($tpl, array(
1649                 '$baseurl' => $a->get_baseurl(true),
1650                 '$submit' => t("Update now"),
1651                 '$close' => t("Close"),
1652                 '$localversion' => FRIENDICA_VERSION,
1653                 '$remoteversion' => $u[1],
1654                 '$needupdate' => $needupdate,
1655                 '$canwrite' => $canwrite,
1656                 '$canftp'       => $canftp,
1657                 '$ftphost'      => array('ftphost', t("FTP Host"), '',''),
1658                 '$ftppath'      => array('ftppath', t("FTP Path"), '/',''),
1659                 '$ftpuser'      => array('ftpuser', t("FTP User"), '',''),
1660                 '$ftppwd'       => array('ftppwd', t("FTP Password"), '',''),
1661                 '$remotefile'=>array('remotefile','', $u['2'],''),
1662         ));
1663
1664 }