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
							
								
									88e6e68d79
								
							
						
					
					
						commit
						120cdb49a6
					
				| @ -68,7 +68,13 @@ unset($themelet); | |||||||
| $page = class_exists("CustomPage") ? new CustomPage() : new Page(); | $page = class_exists("CustomPage") ? new CustomPage() : new Page(); | ||||||
| $_tracer->end(); | $_tracer->end(); | ||||||
| 
 | 
 | ||||||
| $_tracer->begin("Loading extensions/event listeners"); | $_tracer->log_start("Loading user information"); | ||||||
|  | $user = _get_user(); | ||||||
|  | $user_config = new DatabaseConfig($database, "user_config","user_id", $user->id); | ||||||
|  | $_tracer->log_endok(); | ||||||
|  | 
 | ||||||
|  | // hook up event handlers
 | ||||||
|  | $_tracer->begin("Loading event listeners"); | ||||||
| _load_event_listeners(); | _load_event_listeners(); | ||||||
| $_tracer->end(); | $_tracer->end(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,6 +20,11 @@ interface Config | |||||||
|      */ |      */ | ||||||
|     public function set_int(string $name, ?string $value): void; |     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. |      * 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; |     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. |      * 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; |     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. |      * 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); |         $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 |     public function set_string(string $name, ?string $value): void | ||||||
|     { |     { | ||||||
|         $this->values[$name] = $value; |         $this->values[$name] = $value; | ||||||
| @ -131,9 +157,13 @@ abstract class BaseConfig implements Config | |||||||
|         $this->save($name); |         $this->save($name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function set_array(string $name, array $value): void |     public function set_array(string $name, ?array $value): void | ||||||
|     { |     { | ||||||
|  |         if($value!=null) { | ||||||
|             $this->values[$name] = implode(",", $value); |             $this->values[$name] = implode(",", $value); | ||||||
|  |         } else { | ||||||
|  |             $this->values[$name] = null; | ||||||
|  |         } | ||||||
|         $this->save($name); |         $this->save($name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -279,19 +309,41 @@ class DatabaseConfig extends BaseConfig | |||||||
|     /** @var Database  */ |     /** @var Database  */ | ||||||
|     private $database = null; |     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->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) { |         if ($cached) { | ||||||
|             $this->values = $cached; |             $this->values = $cached; | ||||||
|         } else { |         } else { | ||||||
|             $this->values = []; |             $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->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); |                 $this->save($name); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             $this->database->Execute("DELETE FROM config WHERE name = :name", ["name"=>$name]); |             $query = "DELETE FROM {$this->table_name} WHERE name = :name"; | ||||||
|             $this->database->Execute("INSERT INTO config VALUES (:name, :value)", ["name"=>$name, "value"=>$this->values[$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
 |         // rather than deleting and having some other request(s) do a thundering
 | ||||||
|         // herd of race-conditioned updates, just save the updated version once here
 |         // herd of race-conditioned updates, just save the updated version once here
 | ||||||
|  | |||||||
| @ -6,7 +6,6 @@ class Upgrade extends Extension | |||||||
|     { |     { | ||||||
|         global $config, $database; |         global $config, $database; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         if ($config->get_bool("in_upgrade")) { |         if ($config->get_bool("in_upgrade")) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @ -157,8 +156,6 @@ class Upgrade extends Extension | |||||||
|             } |             } | ||||||
|             // SQLite doesn't support altering existing columns? This seems like a problem?
 |             // SQLite doesn't support altering existing columns? This seems like a problem?
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|             log_info("upgrade", "Database at version 16"); |             log_info("upgrade", "Database at version 16"); | ||||||
|             $config->set_bool("in_upgrade", false); |             $config->set_bool("in_upgrade", false); | ||||||
|         } |         } | ||||||
| @ -217,7 +214,24 @@ class Upgrade extends Extension | |||||||
|             $config->set_bool("in_upgrade", false); |             $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); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -82,4 +82,3 @@ class UserDeletionEvent extends Event | |||||||
|         $this->id = $id; |         $this->id = $id; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -188,6 +188,17 @@ class UserPage extends Extension | |||||||
| 
 | 
 | ||||||
|         ksort($event->stats); |         ksort($event->stats); | ||||||
|         $this->theme->display_user_page($event->display_user, $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) { |         if ($user->id == $event->display_user->id) { | ||||||
|             $ubbe = new UserBlockBuildingEvent(); |             $ubbe = new UserBlockBuildingEvent(); | ||||||
|             send_event($ubbe); |             send_event($ubbe); | ||||||
|  | |||||||
| @ -243,14 +243,9 @@ class UserPageTheme extends Themelet | |||||||
|         $page->add_block(new NavBlock()); |         $page->add_block(new NavBlock()); | ||||||
|         $page->add_block(new Block("Stats", join("<br>", $stats), "main", 10)); |         $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; |         global $config, $user; | ||||||
|         $html = ""; |         $html = ""; | ||||||
| @ -266,7 +261,7 @@ class UserPageTheme extends Themelet | |||||||
| 						<tfoot><tr><td colspan='2'><input type='Submit' value='Set'></td></tr></tfoot> | 						<tfoot><tr><td colspan='2'><input type='Submit' value='Set'></td></tr></tfoot> | ||||||
| 					</table> | 					</table> | ||||||
| 				</form> | 				</form> | ||||||
| 				";
 | 				</p>";
 | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             $html .= " |             $html .= " | ||||||
| @ -285,7 +280,7 @@ class UserPageTheme extends Themelet | |||||||
| 					</tfoot> | 					</tfoot> | ||||||
| 				</table> | 				</table> | ||||||
| 			</form> | 			</form> | ||||||
| 
 |             </p> | ||||||
| 			<p>".make_form(make_link("user_admin/change_email"))." | 			<p>".make_form(make_link("user_admin/change_email"))." | ||||||
| 				<input type='hidden' name='id' value='{$duser->id}'> | 				<input type='hidden' name='id' value='{$duser->id}'> | ||||||
| 				<table class='form'> | 				<table class='form'> | ||||||
| @ -294,7 +289,7 @@ class UserPageTheme extends Themelet | |||||||
| 					<tfoot><tr><td colspan='2'><input type='Submit' value='Set'></td></tr></tfoot> | 					<tfoot><tr><td colspan='2'><input type='Submit' value='Set'></td></tr></tfoot> | ||||||
| 				</table> | 				</table> | ||||||
| 			</form> | 			</form> | ||||||
| 			";
 | 			</p>";
 | ||||||
| 
 | 
 | ||||||
|             $i_user_id = int_escape($duser->id); |             $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> | 							<tfoot><tr><td><input type='submit' value='Set'></td></tr></tfoot> | ||||||
| 						</table> | 						</table> | ||||||
| 					</form> | 					</form> | ||||||
| 				";
 | 				</p>";
 | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if ($user->can(Permissions::DELETE_USER)) { |             if ($user->can(Permissions::DELETE_USER)) { | ||||||
| @ -337,8 +332,12 @@ class UserPageTheme extends Themelet | |||||||
| 							</tfoot> | 							</tfoot> | ||||||
| 						</table> | 						</table> | ||||||
| 					</form> | 					</form> | ||||||
| 				";
 | 				</p>";
 | ||||||
|             } |             } | ||||||
|  |             foreach ($event->parts as $part) { | ||||||
|  |                 $html .= $part; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
|         return $html; |         return $html; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -90,7 +90,6 @@ $_tracer->begin($_SERVER["REQUEST_URI"] ?? "No Request"); | |||||||
| try { | try { | ||||||
| 
 | 
 | ||||||
|     // start the page generation waterfall
 |     // start the page generation waterfall
 | ||||||
|     $user = _get_user(); |  | ||||||
|     if (PHP_SAPI === 'cli' || PHP_SAPI == 'phpdbg') { |     if (PHP_SAPI === 'cli' || PHP_SAPI == 'phpdbg') { | ||||||
|         send_event(new CommandEvent($argv)); |         send_event(new CommandEvent($argv)); | ||||||
|     } else { |     } else { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user