Merge remote-tracking branch 'upstream/dev' into wiki
This commit is contained in:
		| @@ -3,8 +3,8 @@ | ||||
| Hubzilla - Community Server | ||||
| =========================== | ||||
|  | ||||
| Connected and linked web communities.  | ||||
| ------------------------------------- | ||||
| Groupware re-imagined and re-invented. Connect and link decentralised web communities.  | ||||
| -------------------------------------------------------------------------------------- | ||||
|  | ||||
| <p align="center" markdown="1"> | ||||
| <em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>  | ||||
|   | ||||
							
								
								
									
										189
									
								
								Zotlabs/Lib/PConfig.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								Zotlabs/Lib/PConfig.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | ||||
| <?php /** @file */ | ||||
|  | ||||
| namespace Zotlabs\Lib; | ||||
|  | ||||
|  | ||||
| class PConfig { | ||||
|  | ||||
| 	/** | ||||
| 	 * @brief Loads all configuration values of a channel into a cached storage. | ||||
| 	 * | ||||
| 	 * All configuration values of the given channel are stored in global cache | ||||
| 	 * which is available under the global variable App::$config[$uid]. | ||||
| 	 * | ||||
| 	 * @param string $uid | ||||
| 	 *  The channel_id | ||||
| 	 * @return void|false Nothing or false if $uid is false | ||||
| 	 */ | ||||
|  | ||||
| 	static public function Load($uid) { | ||||
| 		if($uid === false) | ||||
| 			return false; | ||||
|  | ||||
| 		if(! array_key_exists($uid, \App::$config)) | ||||
| 			\App::$config[$uid] = array(); | ||||
|  | ||||
| 		$r = q("SELECT * FROM pconfig WHERE uid = %d", | ||||
| 			intval($uid) | ||||
| 		); | ||||
|  | ||||
| 		if($r) { | ||||
| 			foreach($r as $rr) { | ||||
| 				$k = $rr['k']; | ||||
| 				$c = $rr['cat']; | ||||
| 				if(! array_key_exists($c, \App::$config[$uid])) { | ||||
| 					\App::$config[$uid][$c] = array(); | ||||
| 					\App::$config[$uid][$c]['config_loaded'] = true; | ||||
| 				} | ||||
| 				\App::$config[$uid][$c][$k] = $rr['v']; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @brief Get a particular channel's config variable given the category name | ||||
| 	 * ($family) and a key. | ||||
| 	 * | ||||
| 	 * Get a particular channel's config value from the given category ($family) | ||||
| 	 * and the $key from a cached storage in App::$config[$uid]. | ||||
| 	 * | ||||
| 	 * Returns false if not set. | ||||
| 	 * | ||||
| 	 * @param string $uid | ||||
| 	 *  The channel_id | ||||
| 	 * @param string $family | ||||
| 	 *  The category of the configuration value | ||||
| 	 * @param string $key | ||||
| 	 *  The configuration key to query | ||||
| 	 * @param boolean $instore (deprecated, without function) | ||||
| 	 * @return mixed Stored value or false if it does not exist | ||||
| 	 */ | ||||
|  | ||||
| 	static public function Get($uid,$family,$key,$instore = false) { | ||||
|  | ||||
| 		if($uid === false) | ||||
| 			return false; | ||||
|  | ||||
| 		if(! array_key_exists($uid, \App::$config)) | ||||
| 			load_pconfig($uid); | ||||
|  | ||||
| 		if((! array_key_exists($family, \App::$config[$uid])) || (! array_key_exists($key, \App::$config[$uid][$family]))) | ||||
| 			return false; | ||||
|  | ||||
| 		return ((! is_array(\App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', \App::$config[$uid][$family][$key]))  | ||||
| 			? unserialize(\App::$config[$uid][$family][$key]) | ||||
| 			: \App::$config[$uid][$family][$key] | ||||
| 		); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @brief Sets a configuration value for a channel. | ||||
| 	 * | ||||
| 	 * Stores a config value ($value) in the category ($family) under the key ($key) | ||||
| 	 * for the channel_id $uid. | ||||
| 	 * | ||||
| 	 * @param string $uid | ||||
| 	 *  The channel_id | ||||
| 	 * @param string $family | ||||
| 	 *  The category of the configuration value | ||||
| 	 * @param string $key | ||||
| 	 *  The configuration key to set | ||||
| 	 * @param string $value | ||||
| 	 *  The value to store | ||||
| 	 * @return mixed Stored $value or false | ||||
| 	 */ | ||||
|  | ||||
| 	static public function Set($uid, $family, $key, $value) { | ||||
|  | ||||
| 		// this catches subtle errors where this function has been called  | ||||
| 		// with local_channel() when not logged in (which returns false) | ||||
| 		// and throws an error in array_key_exists below.  | ||||
| 		// we provide a function backtrace in the logs so that we can find | ||||
| 		// and fix the calling function. | ||||
|  | ||||
| 		if($uid === false) { | ||||
| 			btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		// manage array value | ||||
| 		$dbvalue = ((is_array($value))  ? serialize($value) : $value); | ||||
| 		$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue)  : $dbvalue); | ||||
|  | ||||
| 		if(get_pconfig($uid, $family, $key) === false) { | ||||
| 			if(! array_key_exists($uid, \App::$config)) | ||||
| 				\App::$config[$uid] = array(); | ||||
| 			if(! array_key_exists($family, \App::$config[$uid])) | ||||
| 				\App::$config[$uid][$family] = array(); | ||||
|  | ||||
| 			$ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ", | ||||
| 				intval($uid), | ||||
| 				dbesc($family), | ||||
| 				dbesc($key), | ||||
| 				dbesc($dbvalue) | ||||
| 			); | ||||
|  | ||||
| 		} | ||||
| 		else { | ||||
|  | ||||
| 			$ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'", | ||||
| 				dbesc($dbvalue), | ||||
| 				intval($uid), | ||||
| 				dbesc($family), | ||||
| 				dbesc($key) | ||||
| 			); | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		// keep a separate copy for all variables which were | ||||
| 		// set in the life of this page. We need this to | ||||
| 		// synchronise channel clones. | ||||
|  | ||||
| 		if(! array_key_exists('transient', \App::$config[$uid])) | ||||
| 			\App::$config[$uid]['transient'] = array(); | ||||
| 		if(! array_key_exists($family, \App::$config[$uid]['transient'])) | ||||
| 			\App::$config[$uid]['transient'][$family] = array(); | ||||
|  | ||||
| 		\App::$config[$uid][$family][$key] = $value; | ||||
| 		\App::$config[$uid]['transient'][$family][$key] = $value; | ||||
|  | ||||
| 		if($ret) | ||||
| 			return $value; | ||||
|  | ||||
| 		return $ret; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * @brief Deletes the given key from the channel's configuration. | ||||
| 	 * | ||||
| 	 * Removes the configured value from the stored cache in App::$config[$uid] | ||||
| 	 * and removes it from the database. | ||||
| 	 * | ||||
| 	 * @param string $uid | ||||
| 	 *  The channel_id | ||||
| 	 * @param string $family | ||||
| 	 *  The category of the configuration value | ||||
| 	 * @param string $key | ||||
| 	 *  The configuration key to delete | ||||
| 	 * @return mixed | ||||
| 	 */ | ||||
|   | ||||
| 	static public function Delete($uid, $family, $key) { | ||||
|  | ||||
| 		$ret = false; | ||||
|  | ||||
| 		if(array_key_exists($key, \App::$config[$uid][$family])) | ||||
| 			unset(\App::$config[$uid][$family][$key]); | ||||
| 			$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'", | ||||
| 				intval($uid), | ||||
| 				dbesc($family), | ||||
| 				dbesc($key) | ||||
| 			); | ||||
|  | ||||
| 		return $ret; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| 		 | ||||
| @@ -15,7 +15,7 @@ class ThreadItem { | ||||
| 	private $comment_box_template = 'comment_item.tpl'; | ||||
| 	private $commentable = false; | ||||
| 	// list of supported reaction emojis - a site can over-ride this via config system.reactions | ||||
| 	private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f622','1f62e','1f634','1f61c','1f607','1f608']; | ||||
| 	private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f606','1f62e','1f634','1f61c','1f607','1f608']; | ||||
| 	private $toplevel = false; | ||||
| 	private $children = array(); | ||||
| 	private $parent = null; | ||||
|   | ||||
| @@ -32,8 +32,8 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 				case 'site': | ||||
| 					$this->admin_page_site_post($a); | ||||
| 					break; | ||||
| 				case 'users': | ||||
| 					$this->admin_page_users_post($a); | ||||
| 				case 'accounts': | ||||
| 					$this->admin_page_accounts_post($a); | ||||
| 					break; | ||||
| 				case 'channels': | ||||
| 					$this->admin_page_channels_post($a); | ||||
| @@ -127,8 +127,8 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 				case 'site': | ||||
| 					$o = $this->admin_page_site($a); | ||||
| 					break; | ||||
| 				case 'users': | ||||
| 					$o = $this->admin_page_users($a); | ||||
| 				case 'accounts': | ||||
| 					$o = $this->admin_page_accounts($a); | ||||
| 					break; | ||||
| 				case 'channels': | ||||
| 					$o = $this->admin_page_channels($a); | ||||
| @@ -872,20 +872,20 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * @brief Handle POST actions on users admin page. | ||||
| 	 * @brief Handle POST actions on accounts admin page. | ||||
| 	 * | ||||
| 	 * This function is called when on the admin user/account page the form was | ||||
| 	 * submitted to handle multiple operations at once. If one of the icons next | ||||
| 	 * to an entry are pressed the function admin_page_users() will handle this. | ||||
| 	 * to an entry are pressed the function admin_page_accounts() will handle this. | ||||
| 	 * | ||||
| 	 * @param App $a | ||||
| 	 */ | ||||
| 	function admin_page_users_post($a) { | ||||
| 	function admin_page_accounts_post($a) { | ||||
| 		$pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() ); | ||||
| 		$users   = ( x($_POST, 'user')    ? $_POST['user']    : array() ); | ||||
| 		$blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() ); | ||||
| 	 | ||||
| 		check_form_security_token_redirectOnErr('/admin/users', 'admin_users'); | ||||
| 		check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts'); | ||||
| 	 | ||||
| 		// change to switch structure? | ||||
| 		// account block/unblock button was submitted | ||||
| @@ -901,7 +901,7 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 			notice( sprintf( tt("%s account blocked/unblocked", "%s account blocked/unblocked", count($users)), count($users)) ); | ||||
| 		} | ||||
| 		// account delete button was submitted | ||||
| 		if (x($_POST, 'page_users_delete')) { | ||||
| 		if (x($_POST, 'page_accounts_delete')) { | ||||
| 			foreach ($users as $uid){ | ||||
| 				account_remove($uid, true, false); | ||||
| 			} | ||||
| @@ -920,20 +920,20 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 			} | ||||
| 		} | ||||
| 	 | ||||
| 		goaway(z_root() . '/admin/users' ); | ||||
| 		goaway(z_root() . '/admin/accounts' ); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * @brief Generate users admin page and handle single item operations. | ||||
| 	 * @brief Generate accounts admin page and handle single item operations. | ||||
| 	 * | ||||
| 	 * This function generates the users/account admin page and handles the actions | ||||
| 	 * This function generates the accounts/account admin page and handles the actions | ||||
| 	 * if an icon next to an entry was clicked. If several items were selected and | ||||
| 	 * the form was submitted it is handled by the function admin_page_users_post(). | ||||
| 	 * the form was submitted it is handled by the function admin_page_accounts_post(). | ||||
| 	 * | ||||
| 	 * @param App &$a | ||||
| 	 * @return string | ||||
| 	 */ | ||||
| 	function admin_page_users(&$a){ | ||||
| 	function admin_page_accounts(&$a){ | ||||
| 		if (argc() > 2) { | ||||
| 			$uid = argv(3); | ||||
| 			$account = q("SELECT * FROM account WHERE account_id = %d", | ||||
| @@ -942,10 +942,10 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 	 | ||||
| 			if (! $account) { | ||||
| 				notice( t('Account not found') . EOL); | ||||
| 				goaway(z_root() . '/admin/users' ); | ||||
| 				goaway(z_root() . '/admin/accounts' ); | ||||
| 			} | ||||
| 	 | ||||
| 			check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't'); | ||||
| 			check_form_security_token_redirectOnErr('/admin/accounts', 'admin_accounts', 't'); | ||||
| 	 | ||||
| 			switch (argv(2)){ | ||||
| 				case 'delete': | ||||
| @@ -972,7 +972,7 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 					break; | ||||
| 			} | ||||
| 	 | ||||
| 			goaway(z_root() . '/admin/users' ); | ||||
| 			goaway(z_root() . '/admin/accounts' ); | ||||
| 		} | ||||
| 	 | ||||
| 		/* get pending */ | ||||
| @@ -980,7 +980,7 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 			intval(ACCOUNT_PENDING) | ||||
| 		); | ||||
| 	 | ||||
| 		/* get users */ | ||||
| 		/* get accounts */ | ||||
| 	 | ||||
| 		$total = q("SELECT count(*) as total FROM account"); | ||||
| 		if (count($total)) { | ||||
| @@ -988,22 +988,20 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 			\App::set_pager_itemspage(100); | ||||
| 		} | ||||
| 	 | ||||
| 	 | ||||
| 	//	We'll still need to link email addresses to admin/users/channels or some such, but this bit doesn't exist yet. | ||||
| 	//	That's where we need to be doing last post/channel flags/etc, not here. | ||||
| 	 | ||||
| 		$serviceclass = (($_REQUEST['class']) ? " and account_service_class = '" . dbesc($_REQUEST['class']) . "' " : ''); | ||||
|  | ||||
| 		$order = " order by account_email asc "; | ||||
| 		if($_REQUEST['order'] === 'expires') | ||||
| 			$order = " order by account_expires desc "; | ||||
| 		if($_REQUEST['order'] === 'created') | ||||
| 			$order = " order by account_created desc "; | ||||
| 		$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'account_id'); | ||||
| 		$dir = 'asc'; | ||||
| 		if(array_key_exists('dir',$_REQUEST)) | ||||
| 			$dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc'); | ||||
|  | ||||
| 		$users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . 			"`account_service_class`, ( account_flags & %d )>0 as `blocked`, " . | ||||
| 		$base = z_root() . '/admin/accounts?f='; | ||||
| 		$odir = (($dir === 'asc') ? '0' : '1'); | ||||
| 	 | ||||
| 		$users = q("SELECT `account_id` , `account_email`, `account_lastlog`, `account_created`, `account_expires`, " . 			"`account_service_class`, ( account_flags & %d ) > 0 as `blocked`, " . | ||||
| 				"(SELECT %s FROM channel as ch " . | ||||
| 				"WHERE ch.channel_account_id = ac.account_id and ch.channel_removed = 0 ) as `channels` " . | ||||
| 			"FROM account as ac where true $serviceclass $order limit %d offset %d ", | ||||
| 			"FROM account as ac where true $serviceclass order by $key $dir limit %d offset %d ", | ||||
| 			intval(ACCOUNT_BLOCKED), | ||||
| 			db_concat('ch.channel_address', ' '), | ||||
| 			intval(\App::$pager['itemspage']), | ||||
| @@ -1026,14 +1024,14 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 	//	} | ||||
| 	//	$users = array_map("_setup_users", $users); | ||||
| 	 | ||||
| 		$t = get_markup_template('admin_users.tpl'); | ||||
| 		$t = get_markup_template('admin_accounts.tpl'); | ||||
| 		$o = replace_macros($t, array( | ||||
| 			// strings // | ||||
| 			'$title' => t('Administration'), | ||||
| 			'$page' => t('Users'), | ||||
| 			'$page' => t('Accounts'), | ||||
| 			'$submit' => t('Submit'), | ||||
| 			'$select_all' => t('select all'), | ||||
| 			'$h_pending' => t('User registrations waiting for confirm'), | ||||
| 			'$h_pending' => t('Registrations waiting for confirm'), | ||||
| 			'$th_pending' => array( t('Request date'), t('Email') ), | ||||
| 			'$no_pending' =>  t('No registrations.'), | ||||
| 			'$approve' => t('Approve'), | ||||
| @@ -1041,14 +1039,22 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 			'$delete' => t('Delete'), | ||||
| 			'$block' => t('Block'), | ||||
| 			'$unblock' => t('Unblock'), | ||||
| 	 | ||||
| 			'$h_users' => t('Users'), | ||||
| 			'$th_users' => array( t('ID'), t('Email'), t('All Channels'), t('Register date'), t('Last login'), t('Expires'), t('Service Class')), | ||||
| 			'$odir' => $odir, | ||||
| 			'$base' => $base, | ||||
| 			'$h_users' => t('Accounts'), | ||||
| 			'$th_users' => array(  | ||||
| 				[ t('ID'), 'account_id' ], | ||||
| 				[ t('Email'), 'account_email' ], | ||||
| 				[ t('All Channels'), 'channels' ], | ||||
| 				[ t('Register date'), 'account_created' ], | ||||
| 				[ t('Last login'), 'account_lastlog' ], | ||||
| 				[ t('Expires'), 'account_expires' ], | ||||
| 				[ t('Service Class'), 'account_service_class'] ), | ||||
| 	 | ||||
| 			'$confirm_delete_multi' => t('Selected accounts will be deleted!\n\nEverything these accounts had posted on this site will be permanently deleted!\n\nAre you sure?'), | ||||
| 			'$confirm_delete' => t('The account {0} will be deleted!\n\nEverything this account has posted on this site will be permanently deleted!\n\nAre you sure?'), | ||||
| 	 | ||||
| 			'$form_security_token' => get_form_security_token("admin_users"), | ||||
| 			'$form_security_token' => get_form_security_token("admin_accounts"), | ||||
| 	 | ||||
| 			// values // | ||||
| 			'$baseurl' => z_root(), | ||||
| @@ -1159,6 +1165,17 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 			goaway(z_root() . '/admin/channels' ); | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		$key = (($_REQUEST['key']) ? dbesc($_REQUEST['key']) : 'channel_id'); | ||||
| 		$dir = 'asc'; | ||||
| 		if(array_key_exists('dir',$_REQUEST)) | ||||
| 			$dir = ((intval($_REQUEST['dir'])) ? 'asc' : 'desc'); | ||||
|  | ||||
| 		$base = z_root() . '/admin/channels?f='; | ||||
| 		$odir = (($dir === 'asc') ? '0' : '1'); | ||||
|  | ||||
|  | ||||
| 	 | ||||
| 		/* get channels */ | ||||
| 	 | ||||
| 		$total = q("SELECT count(*) as total FROM channel where channel_removed = 0 and channel_system = 0"); | ||||
| @@ -1167,9 +1184,7 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 			\App::set_pager_itemspage(100); | ||||
| 		} | ||||
|  | ||||
| 		$order = " order by channel_name asc "; | ||||
| 	 | ||||
| 		$channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 $order limit %d offset %d ", | ||||
| 		$channels = q("SELECT * from channel where channel_removed = 0 and channel_system = 0 order by $key $dir limit %d offset %d ", | ||||
| 			intval(\App::$pager['itemspage']), | ||||
| 			intval(\App::$pager['start']) | ||||
| 		); | ||||
| @@ -1201,7 +1216,12 @@ class Admin extends \Zotlabs\Web\Controller { | ||||
| 			'$code' => t('Allow Code'), | ||||
| 			'$uncode' => t('Disallow Code'), | ||||
| 			'$h_channels' => t('Channel'), | ||||
| 			'$th_channels' => array( t('UID'), t('Name'), t('Address')), | ||||
| 			'$base' => $base, | ||||
| 			'$odir' => $odir, | ||||
| 			'$th_channels' => array(  | ||||
| 					[ t('UID'), 'channel_id' ], | ||||
| 					[ t('Name'), 'channel_name' ], | ||||
| 					[ t('Address'), 'channel_address' ]), | ||||
| 	 | ||||
| 			'$confirm_delete_multi' => t('Selected channels will be deleted!\n\nEverything that was posted in these channels on this site will be permanently deleted!\n\nAre you sure?'), | ||||
| 			'$confirm_delete' => t('The channel {0} will be deleted!\n\nEverything that was posted in this channel on this site will be permanently deleted!\n\nAre you sure?'), | ||||
|   | ||||
| @@ -1277,11 +1277,9 @@ class Photos extends \Zotlabs\Web\Controller { | ||||
| 			\App::$page['htmlhead'] .= "\r\n" . '<link rel="alternate" type="application/json+oembed" href="' . z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$cmd) . '" title="oembed" />' . "\r\n"; | ||||
| 	 | ||||
| 	 | ||||
| 		$r = q("SELECT `resource_id`, max(`imgscale`) AS `imgscale` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s'  | ||||
| 		$r = q("SELECT `resource_id`, max(`imgscale`) AS `imgscale` FROM `photo` WHERE `uid` = %d  | ||||
| 			and photo_usage in ( %d, %d ) and is_nsfw = %d $sql_extra GROUP BY `resource_id`", | ||||
| 			intval(\App::$data['channel']['channel_id']), | ||||
| 			dbesc('Contact Photos'), | ||||
| 			dbesc( t('Contact Photos')), | ||||
| 			intval(PHOTO_NORMAL), | ||||
| 			intval(PHOTO_PROFILE), | ||||
| 			intval($unsafe) | ||||
| @@ -1291,15 +1289,13 @@ class Photos extends \Zotlabs\Web\Controller { | ||||
| 			\App::set_pager_itemspage(60); | ||||
| 		} | ||||
| 		 | ||||
| 		$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo as p  | ||||
| 			INNER JOIN ( SELECT resource_id, max(imgscale) as imgscale FROM photo  | ||||
| 		$r = q("SELECT p.resource_id, p.id, p.filename, p.mimetype, p.album, p.imgscale, p.created FROM photo p  | ||||
| 			INNER JOIN ( SELECT resource_id, max(imgscale) imgscale FROM photo  | ||||
| 				WHERE uid = %d AND photo_usage IN ( %d, %d )  | ||||
| 				AND is_nsfw = %d $sql_extra group by resource_id ) as ph  | ||||
| 				AND is_nsfw = %d $sql_extra group by resource_id ) ph  | ||||
| 			ON (p.resource_id = ph.resource_id and p.imgscale = ph.imgscale)  | ||||
| 			ORDER by p.created DESC LIMIT %d OFFSET %d", | ||||
| 			intval(\App::$data['channel']['channel_id']), | ||||
| 			dbesc('Contact Photos'), | ||||
| 			dbesc( t('Contact Photos')), | ||||
| 			intval(PHOTO_NORMAL), | ||||
| 			intval(PHOTO_PROFILE), | ||||
| 			intval($unsafe), | ||||
|   | ||||
| @@ -60,201 +60,33 @@ function del_config($family, $key) { | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * @brief Loads all configuration values of a channel into a cached storage. | ||||
|  * | ||||
|  * All configuration values of the given channel are stored in global cache | ||||
|  * which is available under the global variable App::$config[$uid]. | ||||
|  * | ||||
|  * @param string $uid | ||||
|  *  The channel_id | ||||
|  * @return void|false Nothing or false if $uid is false | ||||
|  */ | ||||
|  | ||||
| function load_pconfig($uid) { | ||||
|  | ||||
| 	if($uid === false) | ||||
| 		return false; | ||||
| 	Zlib\PConfig::Load($uid); | ||||
|  | ||||
| 	if(! array_key_exists($uid, App::$config)) | ||||
| 		App::$config[$uid] = array(); | ||||
|  | ||||
| 	$r = q("SELECT * FROM pconfig WHERE uid = %d", | ||||
| 		intval($uid) | ||||
| 	); | ||||
|  | ||||
| 	if($r) { | ||||
| 		foreach($r as $rr) { | ||||
| 			$k = $rr['k']; | ||||
| 			$c = $rr['cat']; | ||||
| 			if(! array_key_exists($c, App::$config[$uid])) { | ||||
| 				App::$config[$uid][$c] = array(); | ||||
| 				App::$config[$uid][$c]['config_loaded'] = true; | ||||
| 			} | ||||
| 			App::$config[$uid][$c][$k] = $rr['v']; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief Get a particular channel's config variable given the category name | ||||
|  * ($family) and a key. | ||||
|  * | ||||
|  * Get a particular channel's config value from the given category ($family) | ||||
|  * and the $key from a cached storage in App::$config[$uid]. | ||||
|  * | ||||
|  * Returns false if not set. | ||||
|  * | ||||
|  * @param string $uid | ||||
|  *  The channel_id | ||||
|  * @param string $family | ||||
|  *  The category of the configuration value | ||||
|  * @param string $key | ||||
|  *  The configuration key to query | ||||
|  * @param boolean $instore (deprecated, without function) | ||||
|  * @return mixed Stored value or false if it does not exist | ||||
|  */ | ||||
| function get_pconfig($uid, $family, $key, $instore = false) { | ||||
| //	logger('include/config.php: get_pconfig() deprecated instore param used', LOGGER_DEBUG); | ||||
|  | ||||
| 	if($uid === false) | ||||
| 		return false; | ||||
| 	return Zlib\PConfig::Get($uid,$family,$key,$instore = false); | ||||
|  | ||||
| 	if(! array_key_exists($uid, App::$config)) | ||||
| 		load_pconfig($uid); | ||||
|  | ||||
| 	if((! array_key_exists($family, App::$config[$uid])) || (! array_key_exists($key, App::$config[$uid][$family]))) | ||||
| 		return false; | ||||
|  | ||||
| 	return ((! is_array(App::$config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', App::$config[$uid][$family][$key]))  | ||||
| 		? unserialize(App::$config[$uid][$family][$key]) | ||||
| 		: App::$config[$uid][$family][$key] | ||||
| 	); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief Sets a configuration value for a channel. | ||||
|  * | ||||
|  * Stores a config value ($value) in the category ($family) under the key ($key) | ||||
|  * for the channel_id $uid. | ||||
|  * | ||||
|  * @note Please do not store booleans - convert to 0/1 integer values! | ||||
|  * | ||||
|  * @param string $uid | ||||
|  *  The channel_id | ||||
|  * @param string $family | ||||
|  *  The category of the configuration value | ||||
|  * @param string $key | ||||
|  *  The configuration key to set | ||||
|  * @param string $value | ||||
|  *  The value to store | ||||
|  * @return mixed Stored $value or false | ||||
|  */ | ||||
|  | ||||
| function set_pconfig($uid, $family, $key, $value) { | ||||
|  | ||||
| 	// this catches subtle errors where this function has been called  | ||||
| 	// with local_channel() when not logged in (which returns false) | ||||
| 	// and throws an error in array_key_exists below.  | ||||
| 	// we provide a function backtrace in the logs so that we can find | ||||
| 	// and fix the calling function. | ||||
| 	return Zlib\PConfig::Set($uid,$family,$key,$value); | ||||
|  | ||||
| 	if($uid === false) { | ||||
| 		btlogger('UID is FALSE!', LOGGER_NORMAL, LOG_ERR); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	// manage array value | ||||
| 	$dbvalue = ((is_array($value))  ? serialize($value) : $value); | ||||
| 	$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue)  : $dbvalue); | ||||
|  | ||||
| 	if(get_pconfig($uid, $family, $key) === false) { | ||||
| 		if(! array_key_exists($uid, App::$config)) | ||||
| 			App::$config[$uid] = array(); | ||||
| 		if(! array_key_exists($family, App::$config[$uid])) | ||||
| 			App::$config[$uid][$family] = array(); | ||||
|  | ||||
| 		// keep a separate copy for all variables which were | ||||
| 		// set in the life of this page. We need this to | ||||
| 		// synchronise channel clones. | ||||
|  | ||||
| 		if(! array_key_exists('transient', App::$config[$uid])) | ||||
| 			App::$config[$uid]['transient'] = array(); | ||||
| 		if(! array_key_exists($family, App::$config[$uid]['transient'])) | ||||
| 			App::$config[$uid]['transient'][$family] = array(); | ||||
|  | ||||
| 		App::$config[$uid][$family][$key] = $value; | ||||
| 		App::$config[$uid]['transient'][$family][$key] = $value; | ||||
|  | ||||
| 		$ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ", | ||||
| 			intval($uid), | ||||
| 			dbesc($family), | ||||
| 			dbesc($key), | ||||
| 			dbesc($dbvalue) | ||||
| 		); | ||||
| 		if($ret) | ||||
| 			return $value; | ||||
|  | ||||
| 		return $ret; | ||||
| 	} | ||||
|  | ||||
| 	$ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s'", | ||||
| 		dbesc($dbvalue), | ||||
| 		intval($uid), | ||||
| 		dbesc($family), | ||||
| 		dbesc($key) | ||||
| 	); | ||||
|  | ||||
| 	// keep a separate copy for all variables which were | ||||
| 	// set in the life of this page. We need this to | ||||
| 	// synchronise channel clones. | ||||
|  | ||||
| 	if(! array_key_exists('transient', App::$config[$uid])) | ||||
| 		App::$config[$uid]['transient'] = array(); | ||||
| 	if(! array_key_exists($family, App::$config[$uid]['transient'])) | ||||
| 		App::$config[$uid]['transient'][$family] = array(); | ||||
|  | ||||
| 	App::$config[$uid][$family][$key] = $value; | ||||
| 	App::$config[$uid]['transient'][$family][$key] = $value; | ||||
|  | ||||
| 	if($ret) | ||||
| 		return $value; | ||||
|  | ||||
| 	return $ret; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief Deletes the given key from the channel's configuration. | ||||
|  * | ||||
|  * Removes the configured value from the stored cache in App::$config[$uid] | ||||
|  * and removes it from the database. | ||||
|  * | ||||
|  * @param string $uid | ||||
|  *  The channel_id | ||||
|  * @param string $family | ||||
|  *  The category of the configuration value | ||||
|  * @param string $key | ||||
|  *  The configuration key to delete | ||||
|  * @return mixed | ||||
|  */ | ||||
| function del_pconfig($uid, $family, $key) { | ||||
|  | ||||
| 	$ret = false; | ||||
| 	return Zlib\PConfig::Delete($uid,$family,$key); | ||||
|  | ||||
| 	if (x(App::$config[$uid][$family], $key)) | ||||
| 		unset(App::$config[$uid][$family][$key]); | ||||
| 		$ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s'", | ||||
| 		intval($uid), | ||||
| 		dbesc($family), | ||||
| 		dbesc($key) | ||||
| 	); | ||||
|  | ||||
| 	return $ret; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * @brief Loads a full xchan's configuration into a cached storage. | ||||
|  * | ||||
|   | ||||
| @@ -443,7 +443,7 @@ function photo_upload($channel, $observer, $args) { | ||||
|  *   * success (bool) | ||||
|  *   * albums (array) | ||||
|  */ | ||||
| function photos_albums_list($channel, $observer) { | ||||
| function photos_albums_list($channel, $observer, $sort_key = 'album', $direction = 'asc') { | ||||
|  | ||||
| 	$channel_id     = $channel['channel_id']; | ||||
| 	$observer_xchan = (($observer) ? $observer['xchan_hash'] : ''); | ||||
| @@ -451,11 +451,15 @@ function photos_albums_list($channel, $observer) { | ||||
| 	if(! perm_is_allowed($channel_id, $observer_xchan, 'view_storage')) | ||||
| 		return false; | ||||
|  | ||||
| 	/** @FIXME create a permissions SQL which works on arbitrary observers and channels, regardless of login or web status */ | ||||
|  | ||||
| 	$sql_extra = permissions_sql($channel_id); | ||||
| 	$sql_extra = permissions_sql($channel_id,$observer_xchan); | ||||
|  | ||||
| 	$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by max(created) desc", | ||||
| 	$sort_key = dbesc($sort_key); | ||||
| 	$direction = dbesc($direction); | ||||
|  | ||||
|  | ||||
|  | ||||
| 	$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by $sort_key $direction", | ||||
| 		intval($channel_id), | ||||
| 		intval(PHOTO_NORMAL), | ||||
| 		intval(PHOTO_PROFILE) | ||||
| @@ -483,20 +487,14 @@ function photos_albums_list($channel, $observer) { | ||||
| 	return $ret; | ||||
| } | ||||
|  | ||||
| function photos_album_widget($channelx,$observer,$albums = null) { | ||||
| function photos_album_widget($channelx,$observer,$sortkey = 'album',$direction = 'asc') { | ||||
|  | ||||
| 	$o = ''; | ||||
|  | ||||
| 	// If we weren't passed an album list, see if the photos module | ||||
| 	// dropped one for us to find in App::$data['albums'].  | ||||
| 	// If all else fails, load it. | ||||
|  | ||||
| 	if(! $albums) { | ||||
| 	if(array_key_exists('albums', App::$data)) | ||||
| 		$albums = App::$data['albums']; | ||||
| 	else | ||||
| 			$albums = photos_albums_list($channelx,$observer); | ||||
| 	} | ||||
| 		$albums = photos_albums_list($channelx,$observer,$sortkey,$direction); | ||||
|  | ||||
| 	if($albums['success']) { | ||||
| 		$o = replace_macros(get_markup_template('photo_albums.tpl'),array( | ||||
|   | ||||
| @@ -799,8 +799,10 @@ function widget_photo_albums($arr) { | ||||
| 	if((! $channelx) || (! perm_is_allowed(App::$profile['profile_uid'], get_observer_hash(), 'view_storage'))) | ||||
| 		return ''; | ||||
| 	require_once('include/photos.php'); | ||||
| 	$sortkey = ((array_key_exists('sortkey',$arr)) ? $arr['sortkey'] : 'album'); | ||||
| 	$direction = ((array_key_exists('direction',$arr)) ? $arr['direction'] : 'asc');	 | ||||
|  | ||||
| 	return photos_album_widget($channelx, App::get_observer()); | ||||
| 	return photos_album_widget($channelx, App::get_observer(),$sortkey,$direction); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1450,7 +1452,7 @@ function widget_admin($arr) { | ||||
|  | ||||
| 	$aside = array( | ||||
| 		'site'      => array(z_root() . '/admin/site/',     t('Site'),           'site'), | ||||
| 		'users'     => array(z_root() . '/admin/users/',    t('Accounts'),       'users', 'pending-update', t('Member registrations waiting for confirmation')), | ||||
| 		'accounts'  => array(z_root() . '/admin/accounts/', t('Accounts'),       'accounts', 'pending-update', t('Member registrations waiting for confirmation')), | ||||
| 		'channels'  => array(z_root() . '/admin/channels/', t('Channels'),       'channels'), | ||||
| 		'security'  => array(z_root() . '/admin/security/', t('Security'),       'security'), | ||||
| 		'features'  => array(z_root() . '/admin/features/', t('Features'),       'features'), | ||||
|   | ||||
| @@ -17,7 +17,6 @@ EOT; | ||||
| require_once('include/cli_startup.php'); | ||||
|  | ||||
| cli_startup(); | ||||
| $a = get_app(); | ||||
|  | ||||
| 	$plugs = get_config('system', 'addon'); | ||||
| 	$plugins_arr = array(); | ||||
|   | ||||
							
								
								
									
										27
									
								
								util/safemode
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								util/safemode
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| if [ $# == 0 ] ; then  | ||||
| 	echo Usage: $0 on '|' $0 off | ||||
| 	echo on saves current addons to addons-safemode and uninstalls all of them | ||||
| 	echo off installs all addons in addons-safemode | ||||
| 	exit | ||||
| fi | ||||
|  | ||||
|  | ||||
| if [ $1 == 'on' ] ; then | ||||
| 	util/addons list > addons-safemode | ||||
| 	for a in `cat addons-safemode` ; do | ||||
| 		util/addons uninstall $a | ||||
| 	done | ||||
| 	exit | ||||
| fi | ||||
|  | ||||
| if [ $1 == 'off' ] ; then | ||||
| 	for a in `cat addons-safemode` ; do | ||||
| 		util/addons install $a | ||||
| 	done | ||||
| 	exit | ||||
| fi | ||||
|  | ||||
|  | ||||
| 	 | ||||
| @@ -183,7 +183,7 @@ function string2bb(element) { | ||||
| 		}; | ||||
|  | ||||
| 		smilies = { | ||||
| 			match: /(^|\s)(:[a-z]{2,})$/, | ||||
| 			match: /(^|\s)(:[a-z_:]{2,})$/, | ||||
| 			index: 2, | ||||
| 			search: function(term, callback) { $.getJSON('/smilies/json').done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term) === 0 ? entry : null; })); }); }, | ||||
| 			template: function(item) { return item.icon + item.text; }, | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
| <div class="generic-content-wrapper-styled" id="adminpage"> | ||||
| 	<h1>{{$title}} - {{$page}}</h1> | ||||
| 
 | ||||
| 	<form action="{{$baseurl}}/admin/users" method="post"> | ||||
| 	<form action="{{$baseurl}}/admin/accounts" method="post"> | ||||
| 		<input type="hidden" name="form_security_token" value="{{$form_security_token}}"> | ||||
| 
 | ||||
| 		<h3>{{$h_pending}}</h3> | ||||
| @@ -52,7 +52,7 @@ | ||||
| 			<table id="users"> | ||||
| 				<thead> | ||||
| 				<tr> | ||||
| 					{{foreach $th_users as $th}}<th>{{$th}}</th>{{/foreach}} | ||||
| 					{{foreach $th_users as $th}}<th><a href="{{$base}}&key={{$th.1}}&dir={{$odir}}">{{$th.0}}</a></th>{{/foreach}} | ||||
| 					<th></th> | ||||
| 					<th></th> | ||||
| 				</tr> | ||||
| @@ -73,7 +73,7 @@ | ||||
| 						<td class="service_class">{{$u.account_service_class}}</td> | ||||
| 						<td class="checkbox_bulkedit"><input type="checkbox" class="users_ckbx" id="id_user_{{$u.account_id}}" name="user[]" value="{{$u.account_id}}"><input type="hidden" name="blocked[]" value="{{$u.blocked}}"></td> | ||||
| 						<td class="tools"> | ||||
| 							<a href="{{$baseurl}}/admin/users/{{if ($u.blocked)}}un{{/if}}block/{{$u.account_id}}?t={{$form_security_token}}"  class="btn btn-default btn-xs" title='{{if ($u.blocked)}}{{$unblock}}{{else}}{{$block}}{{/if}}'><i class="fa fa-ban admin-icons{{if ($u.blocked)}} dim{{/if}}"></i></a><a href="{{$baseurl}}/admin/users/delete/{{$u.account_id}}?t={{$form_security_token}}" class="btn btn-default btn-xs" title='{{$delete}}' onclick="return confirm_delete('{{$u.name}}')"><i class="fa fa-trash-o admin-icons"></i></a> | ||||
| 							<a href="{{$baseurl}}/admin/accounts/{{if ($u.blocked)}}un{{/if}}block/{{$u.account_id}}?t={{$form_security_token}}"  class="btn btn-default btn-xs" title='{{if ($u.blocked)}}{{$unblock}}{{else}}{{$block}}{{/if}}'><i class="fa fa-ban admin-icons{{if ($u.blocked)}} dim{{/if}}"></i></a><a href="{{$baseurl}}/admin/accounts/delete/{{$u.account_id}}?t={{$form_security_token}}" class="btn btn-default btn-xs" title='{{$delete}}' onclick="return confirm_delete('{{$u.name}}')"><i class="fa fa-trash-o admin-icons"></i></a> | ||||
| 						</td> | ||||
| 					</tr> | ||||
| 				{{/foreach}} | ||||
| @@ -21,7 +21,7 @@ | ||||
| 			<table id='channels'> | ||||
| 				<thead> | ||||
| 				<tr> | ||||
| 					{{foreach $th_channels as $th}}<th>{{$th}}</th>{{/foreach}} | ||||
| 					{{foreach $th_channels as $th}}<th><a href="{{$base}}&key={{$th.1}}&dir={{$odir}}">{{$th.0}}</a></th>{{/foreach}} | ||||
| 					<th></th> | ||||
| 					<th></th> | ||||
| 				</tr> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user