Added $user_config global based on existing config object for storing user-specific settings.
Added event to the user page so that extensions can hook into it, providing user-specific setting controls
This commit is contained in:
		
							parent
							
								
									ee3f53e108
								
							
						
					
					
						commit
						0fa2adfdd5
					
				| @ -52,6 +52,11 @@ unset($themelet); | ||||
| $page = class_exists("CustomPage") ? new CustomPage() : new Page(); | ||||
| $_tracer->end(); | ||||
| 
 | ||||
| $_shm_ctx->log_start("Loading user information"); | ||||
| $user = _get_user(); | ||||
| $user_config = new DatabaseConfig($database, "user_config","user_id", $user->id); | ||||
| $_shm_ctx->log_endok(); | ||||
| 
 | ||||
| // hook up event handlers
 | ||||
| $_tracer->begin("Loading extensions"); | ||||
| _load_event_listeners(); | ||||
|  | ||||
| @ -20,6 +20,11 @@ interface Config | ||||
|      */ | ||||
|     public function set_int(string $name, ?string $value): void; | ||||
| 
 | ||||
|     /** | ||||
|      * Set a configuration option to a new value, regardless of what the value is at the moment. | ||||
|      */ | ||||
|     public function set_float(string $name, ?string $value): void; | ||||
| 
 | ||||
|     /** | ||||
|      * Set a configuration option to a new value, regardless of what the value is at the moment. | ||||
|      */ | ||||
| @ -48,6 +53,16 @@ interface Config | ||||
|      */ | ||||
|     public function set_default_int(string $name, int $value): void; | ||||
| 
 | ||||
|     /** | ||||
|      * Set a configuration option to a new value, if there is no value currently. | ||||
|      * | ||||
|      * Extensions should generally call these from their InitExtEvent handlers. | ||||
|      * This has the advantage that the values will show up in the "advanced" setup | ||||
|      * page where they can be modified, while calling get_* with a "default" | ||||
|      * parameter won't show up. | ||||
|      */ | ||||
|     public function set_default_float(string $name, float $value): void; | ||||
| 
 | ||||
|     /** | ||||
|      * Set a configuration option to a new value, if there is no value currently. | ||||
|      * | ||||
| @ -85,6 +100,11 @@ interface Config | ||||
|      */ | ||||
|     public function get_int(string $name, ?int $default=null): ?int; | ||||
| 
 | ||||
|     /** | ||||
|      * Pick a value out of the table by name, cast to the appropriate data type. | ||||
|      */ | ||||
|     public function get_float(string $name, ?float $default=null): ?float; | ||||
| 
 | ||||
|     /** | ||||
|      * Pick a value out of the table by name, cast to the appropriate data type. | ||||
|      */ | ||||
| @ -119,6 +139,12 @@ abstract class BaseConfig implements Config | ||||
|         $this->save($name); | ||||
|     } | ||||
| 
 | ||||
|     public function set_float(string $name, ?string $value): void | ||||
|     { | ||||
|         $this->values[$name] = $value; | ||||
|         $this->save($name); | ||||
|     } | ||||
| 
 | ||||
|     public function set_string(string $name, ?string $value): void | ||||
|     { | ||||
|         $this->values[$name] = $value; | ||||
| @ -131,9 +157,13 @@ abstract class BaseConfig implements Config | ||||
|         $this->save($name); | ||||
|     } | ||||
| 
 | ||||
|     public function set_array(string $name, array $value): void | ||||
|     public function set_array(string $name, ?array $value): void | ||||
|     { | ||||
|         $this->values[$name] = implode(",", $value); | ||||
|         if($value!=null) { | ||||
|             $this->values[$name] = implode(",", $value); | ||||
|         } else { | ||||
|             $this->values[$name] = null; | ||||
|         } | ||||
|         $this->save($name); | ||||
|     } | ||||
| 
 | ||||
| @ -279,19 +309,41 @@ class DatabaseConfig extends BaseConfig | ||||
|     /** @var Database  */ | ||||
|     private $database = null; | ||||
| 
 | ||||
|     public function __construct(Database $database) | ||||
|     private $table_name; | ||||
|     private $sub_column; | ||||
|     private $sub_value; | ||||
| 
 | ||||
|     public function __construct(Database $database, string $table_name = "config", | ||||
|                                 string $sub_column = null, string $sub_value = null) | ||||
|     { | ||||
|         $this->database = $database; | ||||
|         $this->table_name = $table_name; | ||||
|         $this->sub_value = $sub_value; | ||||
|         $this->sub_column = $sub_column; | ||||
| 
 | ||||
|         $cached = $this->database->cache->get("config"); | ||||
|         $cache_name = "config"; | ||||
|         if(!empty($sub_value)) { | ||||
|             $cache_name .= "_".$sub_value; | ||||
|         } | ||||
| 
 | ||||
|         $cached = $this->database->cache->get($cache_name); | ||||
|         if ($cached) { | ||||
|             $this->values = $cached; | ||||
|         } else { | ||||
|             $this->values = []; | ||||
|             foreach ($this->database->get_all("SELECT name, value FROM config") as $row) { | ||||
| 
 | ||||
|             $query = "SELECT name, value FROM {$this->table_name}"; | ||||
|             $args = []; | ||||
| 
 | ||||
|             if(!empty($sub_column)&&!empty($sub_value)) { | ||||
|                 $query .= " WHERE $sub_column = :sub_value"; | ||||
|                 $args["sub_value"] = $sub_value; | ||||
|             } | ||||
| 
 | ||||
|             foreach ($this->database->get_all($query, $args ) as $row) { | ||||
|                 $this->values[$row["name"]] = $row["value"]; | ||||
|             } | ||||
|             $this->database->cache->set("config", $this->values); | ||||
|             $this->database->cache->set($cache_name, $this->values); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -303,8 +355,23 @@ class DatabaseConfig extends BaseConfig | ||||
|                 $this->save($name); | ||||
|             } | ||||
|         } else { | ||||
|             $this->database->Execute("DELETE FROM config WHERE name = :name", ["name"=>$name]); | ||||
|             $this->database->Execute("INSERT INTO config VALUES (:name, :value)", ["name"=>$name, "value"=>$this->values[$name]]); | ||||
|             $query = "DELETE FROM {$this->table_name} WHERE name = :name"; | ||||
|             $args = ["name"=>$name]; | ||||
|             $cols = ["name","value"]; | ||||
|             $params = [":name",":value"]; | ||||
|             if(!empty($this->sub_column)&&!empty($this->sub_value)) { | ||||
|                 $query .= " AND $this->sub_column = :sub_value"; | ||||
|                 $args["sub_value"] = $this->sub_value; | ||||
|                 $cols[] = $this->sub_column; | ||||
|                 $params[] = ":sub_value"; | ||||
|             } | ||||
| 
 | ||||
|             $this->database->Execute($query, $args); | ||||
| 
 | ||||
|             $args["value"] =$this->values[$name]; | ||||
|             $this->database->Execute( | ||||
|                 "INSERT INTO {$this->table_name} (".join(",",$cols).") VALUES (".join(",",$params).")", | ||||
|                 $args); | ||||
|         } | ||||
|         // rather than deleting and having some other request(s) do a thundering
 | ||||
|         // herd of race-conditioned updates, just save the updated version once here
 | ||||
|  | ||||
| @ -224,7 +224,24 @@ class Upgrade extends Extension | ||||
|             $config->set_bool("in_upgrade", false); | ||||
|         } | ||||
| 
 | ||||
|         if ($config->get_int("db_version") < 18) { | ||||
|             $config->set_bool("in_upgrade", true); | ||||
|             $config->set_int("db_version", 18); | ||||
| 
 | ||||
|             log_info("upgrade", "Adding user config table"); | ||||
| 
 | ||||
|             $database->create_table("user_config", " | ||||
|                 user_id INTEGER NOT NULL, | ||||
|                 name VARCHAR(128) NOT NULL, | ||||
|                 value TEXT, | ||||
|                 PRIMARY KEY (user_id, name), | ||||
| 			    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | ||||
| 		    ");
 | ||||
|             $database->execute("CREATE INDEX user_config_user_id_idx ON user_config(user_id)"); | ||||
| 
 | ||||
|             log_info("upgrade", "Database at version 18"); | ||||
|             $config->set_bool("in_upgrade", false); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -19,6 +19,17 @@ class UserBlockBuildingEvent extends Event | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| class UserOptionsBuildingEvent extends Event | ||||
| { | ||||
|     /** @var array  */ | ||||
|     public $parts = []; | ||||
| 
 | ||||
|     public function add__html(string $html) | ||||
|     { | ||||
|         $this->parts[] = $html; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| class UserPageBuildingEvent extends Event | ||||
| { | ||||
|     /** @var User */ | ||||
| @ -254,6 +265,17 @@ class UserPage extends Extension | ||||
| 
 | ||||
|         ksort($event->stats); | ||||
|         $this->theme->display_user_page($event->display_user, $event->stats); | ||||
| 
 | ||||
|         if (!$user->is_anonymous()) { | ||||
|             if ($user->id == $event->display_user->id || $user->can("edit_user_info")) { | ||||
|                 $uobe = new UserOptionsBuildingEvent(); | ||||
|                 send_event($uobe); | ||||
| 
 | ||||
|                 $page->add_block(new Block("Options", $this->theme->build_options($event->display_user, $uobe), "main", 60)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         if ($user->id == $event->display_user->id) { | ||||
|             $ubbe = new UserBlockBuildingEvent(); | ||||
|             send_event($ubbe); | ||||
|  | ||||
| @ -243,14 +243,9 @@ class UserPageTheme extends Themelet | ||||
|         $page->add_block(new NavBlock()); | ||||
|         $page->add_block(new Block("Stats", join("<br>", $stats), "main", 10)); | ||||
| 
 | ||||
|         if (!$user->is_anonymous()) { | ||||
|             if ($user->id == $duser->id || $user->can("edit_user_info")) { | ||||
|                 $page->add_block(new Block("Options", $this->build_options($duser), "main", 60)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected function build_options(User $duser) | ||||
|     public function build_options(User $duser, UserOptionsBuildingEvent $event) | ||||
|     { | ||||
|         global $config, $user; | ||||
|         $html = ""; | ||||
| @ -266,7 +261,7 @@ class UserPageTheme extends Themelet | ||||
| 						<tfoot><tr><td colspan='2'><input type='Submit' value='Set'></td></tr></tfoot> | ||||
| 					</table> | ||||
| 				</form> | ||||
| 				";
 | ||||
| 				</p>";
 | ||||
|             } | ||||
| 
 | ||||
|             $html .= " | ||||
| @ -285,7 +280,7 @@ class UserPageTheme extends Themelet | ||||
| 					</tfoot> | ||||
| 				</table> | ||||
| 			</form> | ||||
| 
 | ||||
|             </p> | ||||
| 			<p>".make_form(make_link("user_admin/change_email"))." | ||||
| 				<input type='hidden' name='id' value='{$duser->id}'> | ||||
| 				<table class='form'> | ||||
| @ -294,7 +289,7 @@ class UserPageTheme extends Themelet | ||||
| 					<tfoot><tr><td colspan='2'><input type='Submit' value='Set'></td></tr></tfoot> | ||||
| 				</table> | ||||
| 			</form> | ||||
| 			";
 | ||||
| 			</p>";
 | ||||
| 
 | ||||
|             $i_user_id = int_escape($duser->id); | ||||
| 
 | ||||
| @ -316,7 +311,7 @@ class UserPageTheme extends Themelet | ||||
| 							<tfoot><tr><td><input type='submit' value='Set'></td></tr></tfoot> | ||||
| 						</table> | ||||
| 					</form> | ||||
| 				";
 | ||||
| 				</p>";
 | ||||
|             } | ||||
| 
 | ||||
|             if ($user->can(Permissions::DELETE_USER)) { | ||||
| @ -337,8 +332,12 @@ class UserPageTheme extends Themelet | ||||
| 							</tfoot> | ||||
| 						</table> | ||||
| 					</form> | ||||
| 				";
 | ||||
| 				</p>";
 | ||||
|             } | ||||
|             foreach ($event->parts as $part) { | ||||
|                 $html .= $part; | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user