Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add repository layer to handlers for better and centralized entity and session management #625

Merged
merged 12 commits into from
Feb 16, 2024
Merged
9 changes: 0 additions & 9 deletions config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -724,15 +724,6 @@
// */
// 'feeds',

// /*
// | ----
// | POP3
// | ----
// |
// | POP3 E-mail account support
// */
// 'pop3',

// /*
// | -----
// | JMAP
Expand Down
1 change: 1 addition & 0 deletions lib/framework.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
define('VERSION', .1);

/* load the framework */
require APP_PATH.'lib/repository.php';
require APP_PATH.'lib/module.php';
require APP_PATH.'lib/modules.php';
require APP_PATH.'lib/modules_exec.php';
Expand Down
1 change: 1 addition & 0 deletions lib/module.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ abstract class Hm_Handler_Module {
public $user_config;

public $cache;

/**
* Assign input and state sources
* @param object $parent instance of the Hm_Request_Handler class
Expand Down
13 changes: 13 additions & 0 deletions lib/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,19 @@ function add_handler($page, $mod, $logged_in, $source=false, $marker=false, $pla
Hm_Handler_Modules::add($page, $mod, $logged_in, $marker, $placement, $queue, $source);
}

/**
* Add a repository to the module
*
* Repository name for ProfileRepository class is 'profile'
* Filename for ProfileRepository class is 'profile'
*
* @param $class_name
* @return void
*/
function add_repository($repository_name) {

}

/**
* Add an output module to a specific page
* @param string $mod name of the module to add
Expand Down
147 changes: 147 additions & 0 deletions lib/repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?php

trait Hm_Repository {

protected static $name;
protected static $user_config;
protected static $session;
protected static $entities;

protected static function initRepo($name, $user_config, $session, &$entities, callable $init = null) {
self::$name = $name;
self::$user_config = $user_config;
self::$session = $session;
self::$entities = &$entities;
self::migrateFromIntegerIds();
$initial = self::$user_config->get(self::$name, []);
if ($init) {
$init($initial);
} else {
foreach ($initial as $entity) {
self::add($entity, false);
}
}
}

protected static function generateId() {
return uniqid();
}

public static function save() {
self::$user_config->set(self::$name, self::$entities);
self::$session->set('user_data', self::$user_config->dump());
}

public static function add($entity, $save = true) {
if (is_array($entity)) {
if (! array_key_exists('id', $entity)) {
$entity['id'] = self::generateId();
}
$id = $entity['id'];
} elseif (method_exists($entity, 'value')) {
if (! $entity->value('id')) {
$entity->update('id', self::generateId());
}
$id = $entity->value('id');
} else {
throw new Exception('Unrecognized entity found in the repository.');
}
self::$entities[$id] = $entity;
if ($save) {
self::save();
}
return $id;
}

public static function edit($id, $entity) {
if (array_key_exists($id, self::$entities)) {
self::$entities[$id] = $entity;
self::save();
return true;
}
return false;
}

public static function del($id) {
if (array_key_exists($id, self::$entities)) {
unset(self::$entities[$id]);
self::save();
return true;
}
return false;

}

public static function get($id) {
if (array_key_exists($id, self::$entities)) {
return self::$entities[$id];
}
return false;
}

public static function getAll() {
return self::$entities;
}

public static function count() {
return count(self::$entities);
}

protected static function migrateFromIntegerIds() {
$config = self::$user_config->dump();
$replacements = [
'imap' => [],
'smtp' => [],
];
$changed = false;
if (! empty($config['imap_servers'])) {
$replacements['imap'] = self::replaceIntegerIds($config['imap_servers']);
$changed = $changed || ! empty($replacements['imap']);
}
if (! empty($config['smtp_servers'])) {
$replacements['smtp'] = self::replaceIntegerIds($config['smtp_servers']);
$changed = $changed || ! empty($replacements['smtp']);
}
if (! empty($config['feeds'])) {
$result = self::replaceIntegerIds($config['feeds']);
$changed = $changed || ! empty($result);
}
if (! empty($config['profiles'])) {
$result = self::replaceIntegerIds($config['profiles']);
$changed = $changed || ! empty($result);
foreach ($config['profiles'] as $id => $profile) {
if (isset($profile['smtp_id']) && is_numeric($profile['smtp_id']) && isset($replacements['smtp'][$profile['smtp_id']])) {
$config['profiles'][$id]['smtp_id'] = $replacements['smtp'][$profile['smtp_id']];
$changed = true;
}
}
}
if (! empty($config['special_imap_folders'])) {
foreach ($config['special_imap_folders'] as $id => $special) {
if (is_numeric($id) && isset($replacements['imap'][$id])) {
$config['special_imap_folders'][$replacements['imap'][$id]] = $special;
unset($config['special_imap_folders'][$id]);
$changed = true;
}
}
}
if ($changed) {
self::$user_config->reload($config, self::$session->get('username'));
self::$session->set('user_data', self::$user_config->dump());
}
}

protected static function replaceIntegerIds(&$list) {
$replacements = [];
foreach ($list as $id => $server) {
if (is_numeric($id)) {
$new_id = self::generateId();
$server['id'] = $new_id;
$list[$new_id] = $server;
unset($list[$id]);
$replacements[$id] = $new_id;
}
}
return $replacements;
}
}
45 changes: 17 additions & 28 deletions lib/servers.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ public static function connect($id, $cache=false, $user=false, $pass=false, $sav
return false;
}
$server = self::$server_list[$id];

if ($server['object']) {
return $server['object'];
}
list($user, $pass) = self::user_and_pass($user, $pass, $server);
if ($user === false || $pass === false) {
return false;
}

if (self::service_connect($id, $server, $user, $pass, $cache)) {
return self::enable_server($id, $user, $pass, $save_credentials);
}
Expand Down Expand Up @@ -173,35 +175,25 @@ public static function toggle_hidden($id, $hide) {
trait Hm_Server_List {

use Hm_Server_Modify;
use Hm_Repository {
Hm_Repository::add as repo_add;
Hm_Repository::get as repo_get;
}

public static function init($name, $user_config) {
self::initRepo($name, $user_config, self::$server_list);
}

/**
* Add a server definition
* @param array $atts server details
* @param int $id server id
* @return void
*/
public static function add($atts, $id=false) {
public static function add($atts) {
$atts['object'] = false;
$atts['connected'] = false;
if ($id !== false) {
self::$server_list[$id] = $atts;
}
else {
self::$server_list[] = $atts;
}
}

/**
* Remove a server
* @param int $id server id
* @return bool true on success
*/
public static function del($id) {
if (array_key_exists($id, self::$server_list)) {
unset(self::$server_list[$id]);
return true;
}
return false;
return self::repo_add($atts);
}

/**
Expand Down Expand Up @@ -230,22 +222,19 @@ public static function dump($id=false, $full=false) {
* @return array
*/
public static function get($id, $full) {
if (array_key_exists($id, self::$server_list)) {
$server = self::$server_list[$id];
if (!$full) {
return self::clean($server);
}
return $server;
$server = self::repo_get($id);
if ($server && ! $full) {
return self::clean($server);
}
return array();
return $server;
}

/*
* @param array $server
* @return array
*/
public static function clean($server) {
if (!array_key_exists('pass', $server) || !$server['pass']) {
if (! array_key_exists('pass', $server) || ! $server['pass']) {
$server['nopass'] = true;
}
unset($server['pass']);
Expand Down
13 changes: 5 additions & 8 deletions modules/carddav_contacts/hm-carddav.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,8 @@ private function xml_find($xml, $path, $multi=false) {
}

private function url_concat($path) {
if (substr($this->url, -1) == '/' && substr($path, -1) == '/') {
return sprintf('%s%s', substr($this->url, 0, -1), $path);
}
if (substr($this->url, -1) != '/' && substr($path, -1) != '/') {
return sprintf('%s/%s', $this->url, $path);
}
return sprintf('%s%s', $this->url, $path);
$parsed = parse_url($this->url);
return sprintf('%s://%s/%s', $parsed['scheme'], $parsed['host'], preg_replace('#^/#', '', $path));
}

private function auth_headers() {
Expand Down Expand Up @@ -282,10 +277,12 @@ private function list_addressbooks() {
}

private function report($url) {
$headers = $this->auth_headers();
$headers[] = 'Depth: 1';
$req_xml = '<card:addressbook-query xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">'.
'<d:prop><d:getetag /><card:address-data /></d:prop></card:addressbook-query>';
Hm_Debug::add(sprintf('CARDDAV: Sending contacts XML: %s', $req_xml));
return $this->api->command($url, $this->auth_headers(), array(), $req_xml, 'REPORT');
return $this->api->command($url, $headers, array(), $req_xml, 'REPORT');
}

private function delete_server_contact($url) {
Expand Down
Loading