4
0
Эх сурвалжийг харах

Refactor FreshRSS_Share object to be more usable

- FreshRSS_Share is the only object we manipulate
- Add a way to register new share options easily
- Move some i18n keys from index.php to gen.php

See https://github.com/FreshRSS/FreshRSS/issues/730
Marien Fressinaud 11 жил өмнө
parent
commit
0140448a56

+ 3 - 0
app/FreshRSS.php

@@ -32,6 +32,9 @@ class FreshRSS extends Minz_FrontController {
 		FreshRSS_Context::init();
 
 		$this->initI18n();
+
+		FreshRSS_Share::load(join_path(DATA_PATH, 'shares.php'));
+
 		$this->loadStylesAndScripts();
 		$this->loadNotifications();
 		$this->loadExtensions();

+ 214 - 18
app/Models/Share.php

@@ -1,44 +1,240 @@
 <?php
 
+/**
+ * Manage the sharing options in FreshRSS.
+ */
 class FreshRSS_Share {
+	/**
+	 * The list of available sharing options.
+	 */
+	private static $list_sharing = array();
 
-	static public function generateUrl($options, $selected, $link, $title) {
-		$share = $options[$selected['type']];
+	/**
+	 * Register a new sharing option.
+	 * @param $share_options is an array defining the share option.
+	 */
+	public static function register($share_options) {
+		$type = $share_options['type'];
+
+		if (isset(self::$list_sharing[$type])) {
+			return;
+		}
+
+		$help_url = isset($share_options['help']) ? $share_options['help'] : '';
+		self::$list_sharing[$type] = new FreshRSS_Share(
+			$type, $share_options['url'], $share_options['transform'],
+			$share_options['form'], $help_url
+		);
+	}
+
+	/**
+	 * Register sharing options in a file.
+	 * @param $filename the name of the file to load.
+	 */
+	public static function load($filename) {
+		$shares_from_file = @include($filename);
+		if (!is_array($shares_from_file)) {
+			$shares_from_file = array();
+		}
+
+		foreach ($shares_from_file as $share_type => $share_options) {
+			$share_options['type'] = $share_type;
+			self::register($share_options);
+		}
+	}
+
+	/**
+	 * Return the list of sharing options.
+	 * @return an array of FreshRSS_Share objects.
+	 */
+	public static function enum() {
+		return self::$list_sharing;
+	}
+
+	/**
+	 * Return FreshRSS_Share object related to the given type.
+	 * @param $type the share type, null if $type is not registered.
+	 */
+	public static function get($type) {
+		if (!isset(self::$list_sharing[$type])) {
+			return null;
+		}
+
+		return self::$list_sharing[$type];
+	}
+
+	/**
+	 *
+	 */
+	private $type = '';
+	private $name = '';
+	private $url_transform = '';
+	private $transform = array();
+	private $form_type = 'simple';
+	private $help_url = '';
+	private $custom_name = null;
+	private $base_url = null;
+	private $title = null;
+	private $link = null;
+
+	/**
+	 * Create a FreshRSS_Share object.
+	 * @param $type is a unique string defining the kind of share option.
+	 * @param $url_transform defines the url format to use in order to share.
+	 * @param $transform is an array of transformations to apply on link and title.
+	 * @param $form_type defines which form we have to use to complete. "simple"
+	 *        is typically for a centralized service while "advanced" is for
+	 *        decentralized ones.
+	 * @param $help_url is an optional url to give help on this option.
+	 */
+	private function __construct($type, $url_transform, $transform = array(),
+	                             $form_type, $help_url = '') {
+		$this->type = $type;
+		$this->name = _t('gen.share.' . $type);
+		$this->url_transform = $url_transform;
+		$this->help_url = $help_url;
+
+		if (!is_array($transform)) {
+			$transform = array();
+		}
+		$this->transform = $transform;
+
+		if (!in_array($form_type, array('simple', 'advanced'))) {
+			$form_type = 'simple';
+		}
+		$this->form_type = $form_type;
+	}
+
+	/**
+	 * Update a FreshRSS_Share object with information from an array.
+	 * @param $options is a list of informations to update where keys should be
+	 *        in this list: name, url, title, link.
+	 */
+	public function update($options) {
+		$available_options = array(
+			'name' => 'custom_name',
+			'url' => 'base_url',
+			'title' => 'title',
+			'link' => 'link',
+		);
+
+		foreach ($options as $key => $value) {
+			if (!isset($available_options[$key])) {
+				continue;
+			}
+
+			$this->$available_options[$key] = $value;
+		}
+	}
+
+	/**
+	 * Return the current type of the share option.
+	 */
+	public function type() {
+		return $this->type;
+	}
+
+	/**
+	 * Return the current form type of the share option.
+	 */
+	public function formType() {
+		return $this->form_type;
+	}
+
+	/**
+	 * Return the current help url of the share option.
+	 */
+	public function help() {
+		return $this->help_url;
+	}
+
+	/**
+	 * Return the current name of the share option.
+	 */
+	public function name($real = false) {
+		if ($real || is_null($this->custom_name)) {
+			return $this->name;
+		} else {
+			return $this->custom_name;
+		}
+	}
+
+	/**
+	 * Return the current base url of the share option.
+	 */
+	public function baseUrl() {
+		return $this->base_url;
+	}
+
+	/**
+	 * Return the current url by merging url_transform and base_url.
+	 */
+	public function url() {
 		$matches = array(
 			'~URL~',
 			'~TITLE~',
 			'~LINK~',
 		);
 		$replaces = array(
-			$selected['url'],
-			self::transformData($title, self::getTransform($share, 'title')),
-			self::transformData($link, self::getTransform($share, 'link')),
+			$this->base_url,
+			$this->title(),
+			$this->link(),
 		);
-		$url = str_replace($matches, $replaces, $share['url']);
-		return $url;
+		return str_replace($matches, $replaces, $this->url_transform);
 	}
 
-	static private function transformData($data, $transform) {
-		if (!is_array($transform)) {
-			return $data;
+	/**
+	 * Return the title.
+	 * @param $raw true if we should get the title without transformations.
+	 */
+	public function title($raw = false) {
+		if ($raw) {
+			return $this->title;
 		}
-		if (count($transform) === 0) {
+
+		return $this->transform($this->title, $this->getTransform('title'));
+	}
+
+	/**
+	 * Return the link.
+	 * @param $raw true if we should get the link without transformations.
+	 */
+	public function link($raw = false) {
+		if ($raw) {
+			return $this->link;
+		}
+
+		return $this->transform($this->link, $this->getTransform('link'));
+	}
+
+	/**
+	 * Transform a data with the given functions.
+	 * @param $data the data to transform.
+	 * @param $tranform an array containing a list of functions to apply.
+	 * @return the transformed data.
+	 */
+	private static function transform($data, $transform) {
+		if (!is_array($transform) || empty($transform)) {
 			return $data;
 		}
+
 		foreach ($transform as $action) {
 			$data = call_user_func($action, $data);
 		}
+
 		return $data;
 	}
 
-	static private function getTransform($options, $type) {
-		$transform = $options['transform'];
-
-		if (array_key_exists($type, $transform)) {
-			return $transform[$type];
+	/**
+	 * Get the list of transformations for the given attribute.
+	 * @param $attr the attribute of which we want the transformations.
+	 * @return an array containing a list of transformations to apply.
+	 */
+	private function getTransform($attr) {
+		if (array_key_exists($attr, $this->transform)) {
+			return $this->transform[$attr];
 		}
 
-		return $transform;
+		return $this->transform;
 	}
-
 }

+ 11 - 0
app/i18n/en/gen.php

@@ -128,6 +128,17 @@ return array(
 		'nothing_to_load' => 'There are no more articles',
 		'previous' => 'Previous',
 	),
+	'share' => array(
+		'blogotext' => 'Blogotext',
+		'diaspora' => 'Diaspora*',
+		'email' => 'Email',
+		'facebook' => 'Facebook',
+		'g+' => 'Google+',
+		'print' => 'Print',
+		'shaarli' => 'Shaarli',
+		'twitter' => 'Twitter',
+		'wallabag' => 'wallabag',
+	),
 	'short' => array(
 		'attention' => 'Attention!',
 		'blank_to_disable' => 'Leave blank to disable',

+ 1 - 12
app/i18n/en/index.php

@@ -55,18 +55,7 @@ return array(
 		'subscription' => 'Subscriptions management',
 		'unread' => 'Show only unread',
 	),
-	'share' => array(
-		'_' => 'Share',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
-		'facebook' => 'Facebook',
-		'g+' => 'Google+',
-		'print' => 'Print',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
-	),
+	'share' => 'Share',
 	'tag' => array(
 		'related' => 'Related tags',
 	),

+ 1 - 1
app/i18n/fr/conf.php

@@ -121,7 +121,7 @@ return array(
 		'_' => 'Partage',
 		'blogotext' => 'Blogotext',
 		'diaspora' => 'Diaspora*',
-		'email' => 'Email',
+		'email' => 'Courriel',
 		'facebook' => 'Facebook',
 		'g+' => 'Google+',
 		'more_information' => 'Plus d’informations',

+ 11 - 0
app/i18n/fr/gen.php

@@ -128,6 +128,17 @@ return array(
 		'nothing_to_load' => 'Fin des articles',
 		'previous' => 'Précédent',
 	),
+	'share' => array(
+		'blogotext' => 'Blogotext',
+		'diaspora' => 'Diaspora*',
+		'email' => 'Courriel',
+		'facebook' => 'Facebook',
+		'g+' => 'Google+',
+		'print' => 'Imprimer',
+		'shaarli' => 'Shaarli',
+		'twitter' => 'Twitter',
+		'wallabag' => 'wallabag',
+	),
 	'short' => array(
 		'attention' => 'Attention !',
 		'blank_to_disable' => 'Laissez vide pour désactiver',

+ 1 - 12
app/i18n/fr/index.php

@@ -55,18 +55,7 @@ return array(
 		'subscription' => 'Gestion des abonnements',
 		'unread' => 'Afficher les non lus',
 	),
-	'share' => array(
-		'_' => 'Partager',
-		'blogotext' => 'Blogotext',
-		'diaspora' => 'Diaspora*',
-		'email' => 'Courriel',
-		'facebook' => 'Facebook',
-		'g+' => 'Google+',
-		'print' => 'Imprimer',
-		'shaarli' => 'Shaarli',
-		'twitter' => 'Twitter',
-		'wallabag' => 'wallabag',
-	),
+	'share' => 'Partager',
 	'tag' => array(
 		'related' => 'Tags associés',
 	),

+ 16 - 11
app/views/configure/sharing.phtml

@@ -15,22 +15,25 @@
 			<a target="_blank" class="btn" title="<?php echo _t('conf.sharing.more_information'); ?>" href="##help##"><?php echo _i('help'); ?></a>
 			</div></div>'>
 		<legend><?php echo _t('conf.sharing'); ?></legend>
-		<?php foreach (FreshRSS_Context::$user_conf->sharing as $key => $sharing) { ?>
-			<?php $share = FreshRSS_Context::$user_conf->shares[$sharing['type']]; ?>
-			<div class="form-group" id="group-share-<?php echo $key; ?>">
+		<?php
+			foreach (FreshRSS_Context::$user_conf->sharing as $key => $share_options) {
+				$share = FreshRSS_Share::get($share_options['type']);
+				$share->update($share_options);
+		?>
+			<div class="form-group group-share" id="group-share-<?php echo $key; ?>">
 				<label class="group-name">
-					<?php echo _t('conf.sharing.' . $sharing['type']); ?>
+					<?php echo $share->name(true); ?>
 				</label>
 				<div class="group-controls">
-					<input type='hidden' id='share_<?php echo $key;?>_type' name="share[<?php echo $key;?>][type]" value='<?php echo $sharing['type']?>' />
-					<?php if ($share['form'] === 'advanced') { ?>
+					<input type='hidden' id='share_<?php echo $key; ?>_type' name="share[<?php echo $key; ?>][type]" value='<?php echo $share->type(); ?>' />
+					<?php if ($share->formType() === 'advanced') { ?>
 						<div class="stick">
-							<input type="text" id="share_<?php echo $key;?>_name" name="share[<?php echo $key;?>][name]" class="extend" value="<?php echo $sharing['name']?>" placeholder="<?php echo _t('conf.sharing.share_name'); ?>" size="64" />
-							<input type="url" id="share_<?php echo $key;?>_url" name="share[<?php echo $key;?>][url]" class="extend" value="<?php echo $sharing['url']?>" placeholder="<?php echo _t('conf.sharing.share_url'); ?>" size="64" />
+							<input type="text" id="share_<?php echo $key; ?>_name" name="share[<?php echo $key; ?>][name]" class="extend" value="<?php echo $share->name(); ?>" placeholder="<?php echo _t('conf.sharing.share_name'); ?>" size="64" />
+							<input type="url" id="share_<?php echo $key; ?>_url" name="share[<?php echo $key; ?>][url]" class="extend" value="<?php echo $share->baseUrl(); ?>" placeholder="<?php echo _t('conf.sharing.share_url'); ?>" size="64" />
 							<a href='#' class='remove btn btn-attention' data-remove="group-share-<?php echo $key; ?>"><?php echo _i('close'); ?></a>
 						</div>
 
-						<a target="_blank" class="btn" title="<?php echo _t('conf.sharing.more_information'); ?>" href="<?php echo $share['help']?>"><?php echo _i('help'); ?></a>
+						<a target="_blank" class="btn" title="<?php echo _t('conf.sharing.more_information'); ?>" href="<?php echo $share->help(); ?>"><?php echo _i('help'); ?></a>
 					<?php } else { ?>
 					<a href='#' class='remove btn btn-attention' data-remove="group-share-<?php echo $key; ?>"><?php echo _i('close'); ?></a>
 					<?php } ?>
@@ -41,8 +44,10 @@
 		<div class="form-group">
 			<div class="group-controls">
 				<select>
-					<?php foreach(FreshRSS_Context::$user_conf->shares as $key => $params) { ?>
-						<option value='<?php echo $key?>' data-form='<?php echo $params['form']?>' data-help='<?php if (!empty($params['help'])) {echo $params['help'];}?>'><?php echo _t('conf.sharing.' . $key) ?></option>
+					<?php foreach (FreshRSS_Share::enum() as $share) { ?>
+					<option value='<?php echo $share->type(); ?>' data-form='<?php echo $share->formType(); ?>' data-help='<?php echo $share->help(); ?>'>
+						<?php echo $share->name(true); ?>
+					</option>
 					<?php } ?>
 				</select>
 				<a href='#' class='share add btn'><?php echo _i('add'); ?></a>

+ 13 - 15
app/views/index/normal.phtml

@@ -129,8 +129,6 @@ if (!empty($this->entries)) {
 				} ?>
 				<li class="item"><?php
 						if ($bottomline_sharing) {
-							$link = urlencode($item->link());
-							$title = urlencode($item->title() . ' · ' . $feed->name());
 					?><div class="dropdown">
 						<div id="dropdown-share-<?php echo $item->id();?>" class="dropdown-target"></div>
 						<a class="dropdown-toggle" href="#dropdown-share-<?php echo $item->id();?>">
@@ -139,19 +137,19 @@ if (!empty($this->entries)) {
 						</a>
 
 						<ul class="dropdown-menu">
-							<li class="dropdown-close"><a href="#close">❌</a></li>
-							<?php
-								foreach ($sharing as $share) {
-									$type_share = FreshRSS_Context::$user_conf->shares[$share['type']];
-									$has_specific_title = ($type_share['form'] === 'advanced');
-							?>
-								<li class="item share">
-									<a target="_blank" href="<?php echo FreshRSS_Share::generateUrl(FreshRSS_Context::$user_conf->shares, $share, $item->link(), $item->title() . ' . ' . $feed->name())?>">
-										<?php echo $has_specific_title ? $share['name'] : _t('index.share.' . $share['name']); ?>
-									</a>
-								</li>
-							<?php } ?>
-						</ul>
+							<li class="dropdown-close"><a href="#close">❌</a></li><?php
+								$link = $item->link();
+								$title = $item->title() . ' · ' . $feed->name();
+								foreach (FreshRSS_Context::$user_conf->sharing as $share_options) {
+									$share = FreshRSS_Share::get($share_options['type']);
+									$share_options['link'] = $link;
+									$share_options['title'] = $title;
+									$share->update($share_options);
+							?><li class="item share">
+								<a target="_blank" href="<?php echo $share->url(); ?>"><?php echo $share->name(); ?></a>
+							</li><?php
+								}
+						?></ul>
 					</div>
 					<?php } ?>
 				</li><?php

+ 1 - 1
p/scripts/main.js

@@ -1086,7 +1086,7 @@ function init_print_action() {
 }
 
 function init_share_observers() {
-	shares = $('.form-group:not(".form-actions")').length;
+	shares = $('.group-share').length;
 
 	$('.share.add').on('click', function(e) {
 		var opt = $(this).siblings('select').find(':selected');