f1ab8192 by Jeff Balicki

resources fav and style

Signed-off-by: Jeff <jeff@gotenzing.com>
1 parent f379d0bf
Showing 125 changed files with 4794 additions and 0 deletions
1 <?php
2 namespace Favorites\API\Shortcodes;
3
4 class ButtonShortcode
5 {
6 /**
7 * Shortcode Options
8 * @var array
9 */
10 private $options;
11
12 public function __construct()
13 {
14 add_shortcode('favorite_button', [$this, 'renderView']);
15 }
16
17 /**
18 * Shortcode Options
19 */
20 private function setOptions($options)
21 {
22 $this->options = shortcode_atts([
23 'post_id' => null,
24 'site_id' => null,
25 'group_id' => null
26 ], $options);
27 }
28
29 /**
30 * Render the Button
31 * @param $options, array of shortcode options
32 */
33 public function renderView($options)
34 {
35 $this->setOptions($options);
36 return get_favorites_button($this->options['post_id'], $this->options['site_id'], $this->options['group_id']);
37 }
38 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\API\Shortcodes;
3
4 class ClearFavoritesShortcode
5 {
6 /**
7 * Shortcode Options
8 * @var array
9 */
10 private $options;
11
12 public function __construct()
13 {
14 add_shortcode('clear_favorites_button', [$this, 'renderView']);
15 }
16
17 /**
18 * Shortcode Options
19 */
20 private function setOptions($options)
21 {
22 $this->options = shortcode_atts([
23 'site_id' => null,
24 'text' => null
25 ], $options);
26 }
27
28 /**
29 * Render the Button
30 * @param $options, array of shortcode options
31 */
32 public function renderView($options)
33 {
34 $this->setOptions($options);
35 return get_clear_favorites_button($this->options['site_id'], $this->options['text']);
36 }
37 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\API\Shortcodes;
3
4 class FavoriteCountShortcode
5 {
6 /**
7 * Shortcode Options
8 * @var array
9 */
10 private $options;
11
12 public function __construct()
13 {
14 add_shortcode('favorite_count', [$this, 'renderView']);
15 }
16
17 /**
18 * Shortcode Options
19 */
20 private function setOptions($options)
21 {
22 $this->options = shortcode_atts([
23 'post_id' => '',
24 'site_id' => ''
25 ], $options);
26 }
27
28 /**
29 * Render the count
30 * @param $options, array of shortcode options
31 */
32 public function renderView($options)
33 {
34 $this->setOptions($options);
35 return get_favorites_count($this->options['post_id'], $this->options['site_id']);
36 }
37 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\API\Shortcodes;
3
4 class PostFavoritesShortcode
5 {
6 /**
7 * Shortcode Options
8 * @var array
9 */
10 private $options;
11
12 public function __construct()
13 {
14 add_shortcode('post_favorites', [$this, 'renderView']);
15 }
16
17 /**
18 * Shortcode Options
19 */
20 private function setOptions($options)
21 {
22 $this->options = shortcode_atts([
23 'post_id' => '',
24 'site_id' => '',
25 'separator' => 'list',
26 'include_anonymous' => 'true',
27 'anonymous_label' => __('Anonymous Users', 'favorites'),
28 'anonymous_label_single' => __('Anonymous User', 'favorites')
29 ], $options);
30 }
31
32 /**
33 * Render the HTML list
34 * @param $options, array of shortcode options
35 */
36 public function renderView($options)
37 {
38 $this->setOptions($options);
39
40 $this->options['include_anonymous'] = ( $this->options['include_anonymous'] == 'true' ) ? true : false;
41
42 return the_users_who_favorited_post(
43 $post_id = $this->options['post_id'],
44 $site_id = $this->options['site_id'],
45 $separator = $this->options['separator'],
46 $include_anonymous = $this->options['include_anonymous'],
47 $anonymous_label = $this->options['anonymous_label'],
48 $anonymous_label_single = $this->options['anonymous_label_single']
49 );
50 }
51 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\API\Shortcodes;
3
4 class UserFavoriteCount
5 {
6 /**
7 * Shortcode Options
8 * @var array
9 */
10 private $options;
11
12 /**
13 * List Filters
14 * @var array
15 */
16 private $filters;
17
18 public function __construct()
19 {
20 add_shortcode('user_favorite_count', [$this, 'renderView']);
21 }
22
23 /**
24 * Shortcode Options
25 */
26 private function setOptions($options)
27 {
28 $this->options = shortcode_atts([
29 'user_id' => '',
30 'site_id' => '',
31 'post_types' => ''
32 ], $options);
33 }
34
35 /**
36 * Parse Post Types
37 */
38 private function parsePostTypes()
39 {
40 if ( $this->options['post_types'] == "" ) return;
41 $post_types = explode(',', $this->options['post_types']);
42 $this->filters = ['post_type' => $post_types];
43 }
44
45 /**
46 * Render the HTML list
47 * @param $options, array of shortcode options
48 */
49 public function renderView($options)
50 {
51 $this->setOptions($options);
52 $this->parsePostTypes();
53
54 if ( $this->options['user_id'] == '' ) $this->options['user_id'] = null;
55 if ( $this->options['site_id'] == '' ) $this->options['site_id'] = get_current_blog_id();
56
57 return get_user_favorites_count($this->options['user_id'], $this->options['site_id'], $this->filters, true);
58 }
59 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\API\Shortcodes;
3
4 use Favorites\Entities\User\UserFavorites;
5
6 class UserFavoritesShortcode
7 {
8 /**
9 * Shortcode Options
10 * @var array
11 */
12 private $options;
13
14 /**
15 * List Filters
16 * @var array
17 */
18 private $filters;
19
20 public function __construct()
21 {
22 add_shortcode('user_favorites', [$this, 'renderView']);
23 }
24
25 /**
26 * Shortcode Options
27 */
28 private function setOptions($options)
29 {
30 $this->options = shortcode_atts([
31 'user_id' => '',
32 'site_id' => '',
33 'include_links' => 'true',
34 'post_types' => '',
35 'include_buttons' => 'false',
36 'include_thumbnails' => 'false',
37 'thumbnail_size' => 'thumbnail',
38 'include_excerpts' => 'false',
39 'no_favorites' => ''
40 ], $options);
41 }
42
43 /**
44 * Parse Post Types
45 */
46 private function parsePostTypes()
47 {
48 if ( $this->options['post_types'] == "" ) return;
49 $post_types = explode(',', $this->options['post_types']);
50 $this->filters = ['post_type' => $post_types];
51 }
52
53 /**
54 * Render the HTML list
55 * @param $options, array of shortcode options
56 */
57 public function renderView($options)
58 {
59 $this->setOptions($options);
60 $this->parsePostTypes();
61
62 if ( $this->options['user_id'] == "" ) $this->options['user_id'] = null;
63 if ( $this->options['site_id'] == "" ) $this->options['site_id'] = null;
64 $this->options['include_links'] = ( $this->options['include_links'] == 'true' ) ? true : false;
65 $this->options['include_buttons'] = ( $this->options['include_buttons'] == 'true' ) ? true : false;
66 $this->options['include_thumbnails'] = ( $this->options['include_thumbnails'] == 'true' ) ? true : false;
67 $this->options['include_excerpts'] = ( $this->options['include_excerpts'] == 'true' ) ? true : false;
68
69 $favorites = new UserFavorites(
70 $this->options['user_id'],
71 $this->options['site_id'],
72 $this->options['include_links'],
73 $this->filters
74 );
75 return $favorites->getFavoritesList(
76 $this->options['include_buttons'],
77 $this->options['include_thumbnails'],
78 $this->options['thumbnail_size'],
79 $this->options['include_excerpts'],
80 $this->options['no_favorites']
81 );
82 }
83 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * Primary plugin API functions
4 */
5
6 use Favorites\Entities\Favorite\FavoriteButton;
7 use Favorites\Entities\Post\FavoriteCount;
8 use Favorites\Entities\User\UserFavorites;
9 use Favorites\Entities\Post\PostFavorites;
10 use Favorites\Entities\Favorite\ClearFavoritesButton;
11
12
13 /**
14 * Get the favorite button
15 * @param $post_id int, defaults to current post
16 * @param $site_id int, defaults to current blog/site
17 * @return html
18 */
19 function get_favorites_button($post_id = null, $site_id = null, $group_id = null)
20 {
21 global $blog_id;
22 if ( !$post_id ) $post_id = get_the_id();
23 if ( !$group_id ) $group_id = 1;
24 $site_id = ( is_multisite() && is_null($site_id) ) ? $blog_id : $site_id;
25 if ( !is_multisite() ) $site_id = 1;
26 $button = new FavoriteButton($post_id, $site_id);
27 return $button->display();
28 }
29
30
31 /**
32 * Echos the favorite button
33 * @param $post_id int, defaults to current post
34 * @param $site_id int, defaults to current blog/site
35 * @return html
36 */
37 function the_favorites_button($post_id = null, $site_id = null, $group_id = null)
38 {
39 echo get_favorites_button($post_id, $site_id, $group_id);
40 }
41
42
43 /**
44 * Get the Favorite Total Count for a Post
45 * @param $post_id int, defaults to current post
46 * @param $site_id int, defaults to current blog/site
47 * @param $html bool, whether to return html (returns simple integer if false)
48 * @return html
49 */
50 function get_favorites_count($post_id = null, $site_id = null, $html = true)
51 {
52 global $blog_id;
53 $site_id = ( is_multisite() && is_null($site_id) ) ? $blog_id : $site_id;
54 if ( !$post_id ) $post_id = get_the_id();
55 $count = new FavoriteCount();
56 $count = $count->getCount($post_id, $site_id);
57 $out = "";
58 if ( $html ) $out .= '<span data-favorites-post-count-id="' . $post_id . '" data-siteid="' . $site_id . '">';
59 $out .= $count;
60 if ( $html ) $out .= '</span>';
61 return $out;
62 }
63
64
65 /**
66 * Echo the Favorite Count
67 * @param $post_id int, defaults to current post
68 * @param $site_id int, defaults to current blog/site
69 * @return html
70 */
71 function the_favorites_count($post_id = null, $site_id = null, $html = true)
72 {
73 echo get_favorites_count($post_id, $site_id, $html);
74 }
75
76
77 /**
78 * Get an array of User Favorites
79 * @param $user_id int, defaults to current user
80 * @param $site_id int, defaults to current blog/site
81 * @param $filters array of post types/taxonomies
82 * @return array
83 */
84 function get_user_favorites($user_id = null, $site_id = null, $filters = null)
85 {
86 global $blog_id;
87 $site_id = ( is_multisite() && is_null($site_id) ) ? $blog_id : $site_id;
88 if ( !is_multisite() ) $site_id = 1;
89 $favorites = new UserFavorites($user_id, $site_id, $links = false, $filters);
90 return $favorites->getFavoritesArray();
91 }
92
93
94 /**
95 * HTML List of User Favorites
96 * @param $user_id int, defaults to current user
97 * @param $site_id int, defaults to current blog/site
98 * @param $filters array of post types/taxonomies
99 * @param $include_button boolean, whether to include the favorite button for each item
100 * @param $include_thumbnails boolean, whether to include the thumbnail for each item
101 * @param $thumbnail_size string, the thumbnail size to display
102 * @param $include_excpert boolean, whether to include the excerpt for each item
103 * @return html
104 */
105 function get_user_favorites_list($user_id = null, $site_id = null, $include_links = false, $filters = null, $include_button = false, $include_thumbnails = false, $thumbnail_size = 'thumbnail', $include_excerpt = false)
106 {
107 global $blog_id;
108 $site_id = ( is_multisite() && is_null($site_id) ) ? $blog_id : $site_id;
109 if ( !is_multisite() ) $site_id = 1;
110 $favorites = new UserFavorites($user_id, $site_id, $include_links, $filters);
111 return $favorites->getFavoritesList($include_button, $include_thumbnails, $thumbnail_size, $include_excerpt);
112 }
113
114
115 /**
116 * Echo HTML List of User Favorites
117 * @param $user_id int, defaults to current user
118 * @param $site_id int, defaults to current blog/site
119 * @param $filters array of post types/taxonomies
120 * @param $include_button boolean, whether to include the favorite button for each item
121 * @param $include_thumbnails boolean, whether to include the thumbnail for each item
122 * @param $thumbnail_size string, the thumbnail size to display
123 * @param $include_excpert boolean, whether to include the excerpt for each item
124 * @return html
125 */
126 function the_user_favorites_list($user_id = null, $site_id = null, $include_links = false, $filters = null, $include_button = false, $include_thumbnails = false, $thumbnail_size = 'thumbnail', $include_excerpt = false)
127 {
128 echo get_user_favorites_list($user_id, $site_id, $include_links, $filters, $include_button, $include_thumbnails, $thumbnail_size, $include_excerpt);
129 }
130
131
132 /**
133 * Get the number of posts a specific user has favorited
134 * @param $user_id int, defaults to current user
135 * @param $site_id int, defaults to current blog/site
136 * @param $filters array of post types/taxonomies
137 * @param $html boolean, whether to output html (important for AJAX updates). If false, an integer is returned
138 * @return int
139 */
140 function get_user_favorites_count($user_id = null, $site_id = null, $filters = null, $html = false)
141 {
142 $favorites = get_user_favorites($user_id, $site_id, $filters);
143 $posttypes = ( isset($filters['post_type']) ) ? implode(',', $filters['post_type']) : 'all';
144 $count = ( isset($favorites[0]['site_id']) ) ? count($favorites[0]['posts']) : count($favorites);
145 $out = "";
146 if ( !$site_id ) $site_id = 1;
147 if ( $html ) $out .= '<span class="simplefavorites-user-count" data-posttypes="' . $posttypes . '" data-siteid="' . $site_id . '">';
148 $out .= $count;
149 if ( $html ) $out .= '</span>';
150 return $out;
151 }
152
153
154 /**
155 * Print the number of posts a specific user has favorited
156 * @param $user_id int, defaults to current user
157 * @param $site_id int, defaults to current blog/site
158 * @param $filters array of post types/taxonomies
159 * @return html
160 */
161 function the_user_favorites_count($user_id = null, $site_id = null, $filters = null)
162 {
163 echo get_user_favorites_count($user_id, $site_id, $filters);
164 }
165
166
167 /**
168 * Get an array of users who have favorited a post
169 * @param $post_id int, defaults to current post
170 * @param $site_id int, defaults to current blog/site
171 * @param $user_role string, defaults to all
172 * @return array of user objects
173 */
174 function get_users_who_favorited_post($post_id = null, $site_id = null, $user_role = null)
175 {
176 $users = new PostFavorites($post_id, $site_id, $user_role);
177 return $users->getUsers();
178 }
179
180
181 /**
182 * Get a list of users who favorited a post
183 * @param $post_id int, defaults to current post
184 * @param $site_id int, defaults to current blog/site
185 * @param $separator string, custom separator between items (defaults to HTML list)
186 * @param $include_anonmyous boolean, whether to include anonmyous users
187 * @param $anonymous_label string, label for anonymous user count
188 * @param $anonymous_label_single string, singular label for anonymous user count
189 * @param $user_role string, defaults to all
190 */
191 function the_users_who_favorited_post($post_id = null, $site_id = null, $separator = 'list', $include_anonymous = true, $anonymous_label = 'Anonymous Users', $anonymous_label_single = 'Anonymous User', $user_role = null)
192 {
193 $users = new PostFavorites($post_id, $site_id, $user_role);
194 echo $users->userList($separator, $include_anonymous, $anonymous_label, $anonymous_label_single);
195 }
196
197 /**
198 * Get the number of anonymous users who favorited a post
199 * @param $post_id int Defaults to current post
200 * @return int Just anonymous users
201 */
202 function get_anonymous_users_who_favourited_post( $post_id = null ) {
203 $user = new PostFavorites( $post_id );
204 return $users->anonymousCount();
205 }
206
207 /**
208 * Echo the number of anonymous users who favorited a post
209 * @param $post_id int Defaults to current post
210 * @return string Just anonymous users
211 */
212 function the_anonymous_users_who_favourited_post( $post_id = null ) {
213 echo get_anonymous_users_who_favourited_post( $post_id );
214 }
215
216 /**
217 * Get the clear favorites button
218 * @param $site_id int, defaults to current blog/site
219 * @param $text string, button text - defaults to site setting
220 * @return html
221 */
222 function get_clear_favorites_button($site_id = null, $text = null)
223 {
224 $button = new ClearFavoritesButton($site_id, $text);
225 return $button->display();
226 }
227
228
229 /**
230 * Print the clear favorites button
231 * @param $site_id int, defaults to current blog/site
232 * @param $text string, button text - defaults to site setting
233 * @return html
234 */
235 function the_clear_favorites_button($site_id = null, $text = null)
236 {
237 echo get_clear_favorites_button($site_id, $text);
238 }
239
240 /**
241 * Get the total number of favorites, for all posts and users
242 * @param $site_id int, defaults to current blog/site
243 * @return html
244 */
245 function get_total_favorites_count($site_id = null)
246 {
247 $count = new FavoriteCount();
248 return $count->getAllCount($site_id);
249 }
250
251 /**
252 * Print the total number of favorites, for all posts and users
253 * @param $site_id int, defaults to current blog/site
254 * @return html
255 */
256 function the_total_favorites_count($site_id = null)
257 {
258 echo get_total_favorites_count($site_id);
259 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Activation;
3
4 /**
5 * Plugin Activation
6 */
7 class Activate
8 {
9 public function __construct()
10 {
11 $this->setOptions();
12 }
13
14 /**
15 * Default Plugin Options
16 */
17 private function setOptions()
18 {
19 if ( !get_option('simplefavorites_dependencies')
20 && get_option('simplefavorites_dependencies') !== "" ){
21 update_option('simplefavorites_dependencies', [
22 'css' => 'true',
23 'js' => 'true'
24 ]);
25 }
26 if ( !get_option('simplefavorites_users')
27 && get_option('simplefavorites_users') !== "" ){
28 update_option('simplefavorites_users', [
29 'anonymous' => [
30 'display' => 'true',
31 'save' => 'true'
32 ],
33 'saveas' => 'cookie'
34 ]);
35 }
36 if ( !get_option('simplefavorites_display')
37 && get_option('simplefavorites_display') !== "" ){
38 update_option('simplefavorites_display', [
39 'buttontext' => __('Favorite <i class="sf-icon-star-empty"></i>', 'favorites'),
40 'buttontextfavorited' => __('Favorited <i class="sf-icon-star-full"></i>', 'favorites'),
41 'posttypes' => [
42 'post' => [
43 'display' => true,
44 'after_content' => true,
45 'postmeta' => true
46 ]
47 ]
48 ]);
49 }
50 if ( !get_option('simplefavorites_cache_enabled')
51 && get_option('simplefavorites_cache_enabled') !== "" ){
52 update_option('simplefavorites_cache_enabled', 'true');
53 }
54 }
55 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Activation;
3
4 use Favorites\Helpers;
5 use Favorites\Config\SettingsRepository;
6
7 /**
8 * Plugin Dependencies
9 */
10 class Dependencies
11 {
12 /**
13 * Plugin Directory
14 */
15 private $plugin_dir;
16
17 /**
18 * Plugin Version
19 */
20 private $plugin_version;
21
22 /**
23 * Settings Repository
24 */
25 private $settings_repo;
26
27 public function __construct()
28 {
29 $this->settings_repo = new SettingsRepository;
30 $this->setPluginVersion();
31 $this->plugin_dir = Helpers::plugin_url();
32 add_action( 'admin_enqueue_scripts', [$this, 'adminStyles']);
33 add_action( 'admin_enqueue_scripts', [$this, 'adminScripts']);
34 add_action( 'wp_enqueue_scripts', [$this, 'frontendStyles']);
35 add_action( 'wp_enqueue_scripts', [$this, 'frontendScripts']);
36 }
37
38 /**
39 * Set the Plugin Version
40 */
41 private function setPluginVersion()
42 {
43 global $favorites_version;
44 $this->plugin_version = $favorites_version;
45 }
46
47 /**
48 * Admin Styles
49 */
50 public function adminStyles()
51 {
52 wp_enqueue_style('wp-color-picker');
53 wp_enqueue_style(
54 'simple-favorites-admin',
55 $this->plugin_dir . '/assets/css/favorites-admin.css',
56 [],
57 $this->plugin_version
58 );
59 }
60
61 /**
62 * Admin Scripts
63 */
64 public function adminScripts()
65 {
66 $screen = get_current_screen();
67 $settings_page = ( strpos($screen->id, 'simple-favorites') ) ? true : false;
68 if ( !$settings_page ) return;
69 wp_enqueue_script(
70 'simple-favorites-admin',
71 $this->plugin_dir . '/assets/js/favorites-admin.min.js',
72 ['jquery', 'wp-color-picker'],
73 $this->plugin_version
74 );
75 }
76
77 /**
78 * Front End Styles
79 */
80 public function frontendStyles()
81 {
82 if ( !$this->settings_repo->outputDependency('css') ) return;
83 wp_enqueue_style(
84 'simple-favorites',
85 $this->plugin_dir . '/assets/css/favorites.css',
86 [],
87 $this->plugin_version
88 );
89 }
90
91 /**
92 * Front End Scripts
93 */
94 public function frontendScripts()
95 {
96 if ( !$this->settings_repo->outputDependency('js') ) return;
97 $file = ( $this->settings_repo->devMode() ) ? 'favorites.js' : 'favorites.min.js';
98 wp_enqueue_script(
99 'favorites',
100 $this->plugin_dir . '/assets/js/' . $file,
101 ['jquery'],
102 $this->plugin_version
103 );
104 $localized_data = [
105 'ajaxurl' => admin_url( 'admin-ajax.php' ),
106 'nonce' => wp_create_nonce('simple_favorites_nonce'),
107 'favorite' => apply_filters('favorites/button/html', $this->settings_repo->buttonText(), null, false, null),
108 'favorited' => apply_filters('favorites/button/html', $this->settings_repo->buttonTextFavorited(), null, true, null),
109 'includecount' => $this->settings_repo->includeCountInButton(),
110 'indicate_loading' => $this->settings_repo->includeLoadingIndicator(),
111 'loading_text' => $this->settings_repo->loadingText(),
112 'loading_image' => $this->settings_repo->loadingImage(),
113 'loading_image_active' => $this->settings_repo->loadingImage('active'),
114 'loading_image_preload' => $this->settings_repo->includeLoadingIndicatorPreload(),
115 'cache_enabled' => $this->settings_repo->cacheEnabled(),
116 'button_options' => $this->settings_repo->formattedButtonOptions(),
117 'authentication_modal_content' => $this->settings_repo->authenticationModalContent(),
118 'authentication_redirect' => $this->settings_repo->redirectAnonymous(),
119 'dev_mode' => $this->settings_repo->devMode(),
120 'logged_in' => is_user_logged_in(),
121 'user_id' => get_current_user_id()
122 ];
123 $redirect_url = $this->settings_repo->redirectAnonymousId();
124 $localized_data['authentication_redirect_url'] = ( $redirect_url ) ? get_the_permalink($redirect_url) : apply_filters( 'favorites/authentication_redirect_url', wp_login_url() );
125 wp_localize_script(
126 'favorites',
127 'favorites_data',
128 $localized_data
129 );
130 }
131 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites;
3
4 use Favorites\Config\SettingsRepository;
5
6 /**
7 * Plugin Bootstrap
8 */
9 class Bootstrap
10 {
11 /**
12 * Settings Repository
13 * @var object
14 */
15 private $settings_repo;
16
17 public function __construct()
18 {
19 $this->settings_repo = new SettingsRepository;
20 add_action( 'init', [$this, 'init']);
21 add_action( 'admin_init', [$this, 'adminInit']);
22 add_filter( 'plugin_action_links_' . 'favorites/favorites.php', [$this, 'settingsLink']);
23 add_action( 'plugins_loaded', [$this, 'addLocalization']);
24 }
25
26 /**
27 * Initialize
28 */
29 public function init()
30 {
31 new Config\Settings;
32 new Activation\Activate;
33 new Activation\Dependencies;
34 new Entities\Post\PostHooks;
35 new Events\RegisterPublicEvents;
36 new Entities\Post\PostMeta;
37 new API\Shortcodes\ButtonShortcode;
38 new API\Shortcodes\FavoriteCountShortcode;
39 new API\Shortcodes\UserFavoritesShortcode;
40 new API\Shortcodes\UserFavoriteCount;
41 new API\Shortcodes\PostFavoritesShortcode;
42 new API\Shortcodes\ClearFavoritesShortcode;
43 $this->startSession();
44 }
45
46 /**
47 * Admin Init
48 */
49 public function adminInit()
50 {
51 new Entities\Post\AdminColumns;
52 }
53
54 /**
55 * Add a link to the settings on the plugin page
56 */
57 public function settingsLink($links)
58 {
59 $settings_link = '<a href="options-general.php?page=simple-favorites">' . __('Settings', 'favorites') . '</a>';
60 $help_link = '<a href="http://favoriteposts.com">' . __('FAQ', 'favorites') . '</a>';
61 array_unshift($links, $help_link);
62 array_unshift($links, $settings_link);
63 return $links;
64 }
65
66 /**
67 * Localization Domain
68 */
69 public function addLocalization()
70 {
71 load_plugin_textdomain(
72 'favorites',
73 false,
74 dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages' );
75 }
76
77 /**
78 * Initialize a Session
79 */
80 public function startSession()
81 {
82 if ( $this->settings_repo->saveType() !== 'session' ) return;
83 if ( !session_id() ) session_start();
84 }
85 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Config;
3
4 use Favorites\Config\SettingsRepository;
5 use Favorites\Entities\PostType\PostTypeRepository;
6 use Favorites\Helpers;
7
8 /**
9 * Plugin Settings
10 */
11 class Settings
12 {
13 /**
14 * Plugin Name
15 */
16 private $plugin_name;
17
18 /**
19 * Settings Repository
20 */
21 private $settings_repo;
22
23 /**
24 * Post Type Repository
25 */
26 private $post_type_repo;
27
28 public function __construct()
29 {
30 $this->settings_repo = new SettingsRepository;
31 $this->post_type_repo = new PostTypeRepository;
32 $this->setName();
33 add_action( 'admin_init', [$this, 'registerSettings']);
34 add_action( 'admin_menu', [$this, 'registerSettingsPage']);
35 }
36
37 /**
38 * Set the plugin name
39 */
40 private function setName()
41 {
42 global $favorites_name;
43 $this->plugin_name = $favorites_name;
44 }
45
46 /**
47 * Register the settings page
48 */
49 public function registerSettingsPage()
50 {
51 add_options_page(
52 $this->plugin_name . ' ' . __('Settings', 'favorites'),
53 $this->plugin_name,
54 'manage_options',
55 'simple-favorites',
56 [$this, 'settingsPage']
57 );
58 }
59
60 /**
61 * Display the Settings Page
62 */
63 public function settingsPage()
64 {
65 $tab = ( isset($_GET['tab']) ) ? sanitize_text_field($_GET['tab']) : 'general';
66 include( Helpers::view('settings/settings') );
67 }
68
69 /**
70 * Register the settings
71 */
72 public function registerSettings()
73 {
74 register_setting( 'simple-favorites-general', 'simplefavorites_dependencies' );
75 register_setting( 'simple-favorites-general', 'simplefavorites_cache_enabled' );
76 register_setting( 'simple-favorites-general', 'simplefavorites_dev_mode');
77 register_setting( 'simple-favorites-users', 'simplefavorites_users' );
78 register_setting( 'simple-favorites-display', 'simplefavorites_display' );
79 }
80 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Favorite;
3
4 use Favorites\Entities\User\UserRepository;
5 use Favorites\Config\SettingsRepository;
6
7 class ClearFavoritesButton
8 {
9 /**
10 * Site ID
11 */
12 private $site_id;
13
14 /**
15 * User Respository
16 */
17 private $user;
18
19 /**
20 * The Button Text
21 */
22 private $text;
23
24 /**
25 * Settings Repository
26 */
27 private $settings_repo;
28
29 public function __construct($site_id, $text)
30 {
31 $this->user = new UserRepository;
32 $this->settings_repo = new SettingsRepository;
33 $this->site_id = $site_id;
34 $this->text = $text;
35 }
36
37 /**
38 * Display the button
39 */
40 public function display()
41 {
42 if ( !$this->user->getsButton() ) return false;
43 if ( !$this->text ) $this->text = html_entity_decode($this->settings_repo->clearFavoritesText());
44 if ( !$this->site_id ) $this->site_id = 1;
45 $out = '<button class="simplefavorites-clear" data-siteid="' . $this->site_id . '">' . $this->text . '</button>';
46 return $out;
47 }
48 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Favorite;
3
4 use Favorites\Config\SettingsRepository;
5 use Favorites\Entities\Favorite\SyncSingleFavorite;
6 use Favorites\Entities\Post\SyncFavoriteCount;
7
8 class Favorite
9 {
10 /**
11 * Settings Repository
12 */
13 private $settings_repo;
14
15 /**
16 * Save Type
17 */
18 private $save_type;
19
20 public function __construct()
21 {
22 $this->settings_repo = new SettingsRepository;
23 }
24
25 /**
26 * Save the Favorite
27 */
28 public function update($post_id, $status, $site_id, $group_id = 1)
29 {
30 $this->save_type = $this->settings_repo->saveType();
31 $usersync = new SyncSingleFavorite($post_id, $site_id, $group_id);
32 $saveType = $this->save_type;
33 $usersync->$saveType();
34
35 $postsync = new SyncFavoriteCount($post_id, $status, $site_id);
36 $postsync->sync();
37 }
38
39 /**
40 * Get the Save Type
41 */
42 public function saveType()
43 {
44 return $this->save_type;
45 }
46 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Favorite;
3
4 use Favorites\Entities\User\UserRepository;
5 use Favorites\Entities\Post\FavoriteCount;
6 use Favorites\Config\SettingsRepository;
7
8 class FavoriteButton
9 {
10 /**
11 * The Post ID
12 */
13 private $post_id;
14
15 /**
16 * Site ID
17 */
18 private $site_id;
19
20 /**
21 * Group ID
22 */
23 private $group_id;
24
25 /**
26 * User Respository
27 */
28 private $user;
29
30 /**
31 * Favorite Count Object
32 */
33 private $count;
34
35 /**
36 * Button Options
37 * @var array
38 */
39 private $button_options;
40
41 /**
42 * Favorited?
43 * @var bool
44 */
45 private $favorited;
46
47 /**
48 * Settings Repository
49 */
50 private $settings_repo;
51
52 public function __construct($post_id, $site_id, $group_id = 1)
53 {
54 $this->user = new UserRepository;
55 $this->settings_repo = new SettingsRepository;
56 $this->count = new FavoriteCount;
57 $this->post_id = $post_id;
58 $this->site_id = $site_id;
59 $this->group_id = $group_id;
60 }
61
62 /**
63 * Diplay the Button
64 * @param boolean loading - whether to include loading class
65 * @return html
66 */
67 public function display($loading = true)
68 {
69 // $cookie = json_decode(stripslashes($_COOKIE['simplefavorites']), true);
70 // var_dump($cookie[0]);
71 if ( !$this->settings_repo->cacheEnabled() ) $loading = false;
72 if ( !$this->user->getsButton() ) return false;
73
74 $this->button_options = $this->settings_repo->formattedButtonOptions();
75 $this->favorited = ( $this->user->isFavorite($this->post_id, $this->site_id, null, $this->group_id) ) ? true : false;
76 $count = $this->count->getCount($this->post_id, $this->site_id);
77 $button_html_type = apply_filters('favorites/button/element_type', $this->settings_repo->getButtonHtmlType(), $this->post_id, $this->site_id);
78 $html = $this->html();
79
80 $out = '<' . $button_html_type . ' class="' . $this->cssClasses($loading) . '"';
81
82 $out .= ' data-postid="' . $this->post_id . '" data-siteid="' . $this->site_id . '" data-groupid="' . $this->group_id . '" data-favoritecount="' . $count . '" style="' . $this->styleAttributes() . '">';
83
84 if ( $this->settings_repo->includeLoadingIndicator() && $this->settings_repo->includeLoadingIndicatorPreload() && $loading){
85 $out .= $this->settings_repo->loadingText();
86 $spinner = ( $this->favorited ) ? $this->settings_repo->loadingImage('active') : $this->settings_repo->loadingImage();
87 if ( $spinner ) $out .= $spinner;
88 } else {
89 $out .= $html;
90 if ( $this->button_options['include_count'] ) $out .= $this->addCount();
91 }
92 $out .= '</' . $button_html_type . '>';
93 return $out;
94 }
95
96 /**
97 * Add CSS Classes
98 */
99 private function cssClasses($loading)
100 {
101 $classes = 'simplefavorite-button';
102 if ( $this->favorited ) $classes .= ' active';
103 if ( $this->button_options['include_count'] ) $classes .= ' has-count';
104 if ( $this->settings_repo->includeLoadingIndicator() && $this->settings_repo->includeLoadingIndicatorPreload() && $loading ) $classes .= ' loading';
105 if ( is_array($this->button_options['button_type']) ) $classes .= ' preset';
106 return apply_filters('favorites/button/css_classes', $classes, $this->post_id, $this->site_id);
107 }
108
109 /**
110 * Add Style Attributes
111 */
112 private function styleAttributes($icon = false)
113 {
114 if ( !$this->button_options['custom_colors'] ) return null;
115 $html = '';
116 $default_colors = $this->button_options['default'];
117 $active_colors = $this->button_options['active'];
118 if ( $icon ){
119 if ( $this->favorited ){
120 if ( $active_colors['icon_active'] ) $html .= 'color:' . $active_colors['icon_active'] . ';';
121 } else {
122 if ( $default_colors['icon_default'] ) $html .= 'color:' . $default_colors['icon_default'] . ';';
123 }
124 return $html;
125 }
126
127 if ( !$this->button_options['box_shadow'] ) $html .= 'box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;';
128
129 if ( $this->favorited ) {
130 if ( $active_colors['background_active'] ) $html .= 'background-color:' . $active_colors['background_active'] . ';';
131 if ( $active_colors['border_active'] ) $html .= 'border-color:' . $active_colors['border_active'] . ';';
132 if ( $active_colors['text_active'] ) $html .= 'color:' . $active_colors['text_active'] . ';';
133 return $html;
134 }
135 if ( $default_colors['background_default'] ) $html .= 'background-color:' . $default_colors['background_default'] . ';';
136 if ( $default_colors['border_default'] ) $html .= 'border-color:' . $default_colors['border_default'] . ';';
137 if ( $default_colors['text_default'] ) $html .= 'color:' . $default_colors['text_default'] . ';';
138 return $html;
139 }
140
141 /**
142 * Build the HTML for the button
143 */
144 private function html()
145 {
146 $html = '';
147 if ( is_array($this->button_options['button_type']) ) {
148 $html .= '<i class="' . $this->button_options['button_type']['icon_class'] . '" style="' . $this->styleAttributes(true) . '"></i>';
149 $html .= ( $this->favorited ) ? $this->button_options['button_type']['state_active'] : $this->button_options['button_type']['state_default'];
150 } else {
151 $html .= ( $this->favorited ) ? html_entity_decode($this->settings_repo->buttonTextFavorited()) : html_entity_decode($this->settings_repo->buttonText());
152 }
153 return apply_filters('favorites/button/html', $html, $this->post_id, $this->favorited, $this->site_id);
154 }
155
156 /**
157 * Add the favorite count
158 */
159 private function addCount()
160 {
161 $default_colors = $this->button_options['default'];
162 $active_colors = $this->button_options['active'];
163
164 $html = '<span class="simplefavorite-button-count" style="';
165 if ( $this->favorited ){
166 if ( $active_colors['count_active'] ) $html .= 'color:' . $active_colors['count_active'] . ';';
167 } else {
168 if ( $default_colors['count_default'] ) $html .= 'color:' . $default_colors['count_default'] . ';';
169 }
170 $html .= '">' . $this->count->getCount($this->post_id, $this->site_id) . '</span>';
171 return apply_filters('favorites/button/count', $html);
172 }
173 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Favorite;
3
4 /**
5 * Filters an array of favorites using provided array of filters
6 */
7 class FavoriteFilter
8 {
9 /**
10 * Favorites
11 * @var array of post IDs
12 */
13 private $favorites;
14
15 /**
16 * Filters
17 * @var array
18 *
19 * Example:
20 *
21 * array(
22 * 'post_type' => array('post', 'posttypetwo'),
23 * 'terms' => array(
24 * 'category' => array(
25 * 'termone', 'termtwo', 'termthree'
26 * ),
27 * 'other-taxonomy' => array(
28 * 'termone', 'termtwo', 'termthree'
29 * )
30 * )
31 * );
32 *
33 */
34 private $filters;
35
36 public function __construct($favorites, $filters)
37 {
38 $this->favorites = $favorites;
39 $this->filters = $filters;
40 }
41
42 public function filter()
43 {
44 if ( isset($this->filters['post_type']) && is_array($this->filters['post_type']) ) $this->filterByPostType();
45 if ( isset($this->filters['terms']) && is_array($this->filters['terms']) ) $this->filterByTerm();
46 if ( isset($this->filters['status']) && is_array($this->filters['status']) ) $this->filterByStatus();
47 return $this->favorites;
48 }
49
50 /**
51 * Filter favorites by post type
52 * @since 1.1.1
53 * @param array $favorites
54 */
55 private function filterByPostType()
56 {
57 foreach($this->favorites as $key => $favorite){
58 $post_type = get_post_type($favorite);
59 if ( !in_array($post_type, $this->filters['post_type']) ) unset($this->favorites[$key]);
60 }
61 }
62
63 /**
64 * Filter favorites by status
65 * @since 2.1.4
66 */
67 private function filterByStatus()
68 {
69 foreach($this->favorites as $key => $favorite){
70 $status = get_post_status($favorite);
71 if ( !in_array($status, $this->filters['status']) ) unset($this->favorites[$key]);
72 }
73 }
74
75 /**
76 * Filter favorites by terms
77 * @since 1.1.1
78 * @param array $favorites
79 */
80 private function filterByTerm()
81 {
82 $taxonomies = $this->filters['terms'];
83 $favorites = $this->favorites;
84
85 foreach ( $favorites as $key => $favorite ) :
86
87 $all_terms = [];
88 $all_filters = [];
89
90 foreach ( $taxonomies as $taxonomy => $terms ){
91 if ( !isset($terms) || !is_array($terms) ) continue;
92 $post_terms = wp_get_post_terms($favorite, $taxonomy, array("fields" => "slugs"));
93 if ( !empty($post_terms) ) $all_terms = array_merge($all_terms, $post_terms);
94 $all_filters = array_merge($all_filters, $terms);
95 }
96
97 $dif = array_diff($all_filters, $all_terms);
98 if ( !empty($dif) ) unset($favorites[$key]);
99
100 endforeach;
101
102 $this->favorites = $favorites;
103 }
104 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Favorite;
3
4 use Favorites\Entities\Post\FavoriteCount;
5 use Favorites\Entities\Favorite\FavoriteButton;
6 use Favorites\Entities\FavoriteList\FavoriteList;
7
8 /**
9 * Format the user's favorite array to include additional post data
10 */
11 class FavoritesArrayFormatter
12 {
13 /**
14 * Formatted favorites array
15 */
16 private $formatted_favorites;
17
18 /**
19 * Total Favorites Counter
20 */
21 private $counter;
22
23 /**
24 * Post ID to add to return array
25 * For adding/removing session/cookie favorites for current request
26 * @var int
27 */
28 private $post_id;
29
30 /**
31 * Site ID for post to add to array
32 * For adding/removing session/cookie favorites for current request
33 * @var int
34 */
35 private $site_id;
36
37 /**
38 * Site ID for post to add to array
39 * For adding/removing session/cookie favorites for current request
40 * @var string
41 */
42 private $status;
43
44 public function __construct()
45 {
46 $this->counter = new FavoriteCount;
47 }
48
49 public function format($favorites, $post_id = null, $site_id = null, $status = null)
50 {
51 $this->formatted_favorites = $favorites;
52 $this->post_id = $post_id;
53 $this->site_id = $site_id;
54 $this->status = $status;
55 $this->resetIndexes();
56 $this->addPostData();
57 return $this->formatted_favorites;
58 }
59
60 /**
61 * Reset the favorite indexes
62 */
63 private function resetIndexes()
64 {
65 foreach ( $this->formatted_favorites as $site => $site_favorites ){
66 // Make older posts compatible with new name
67 if ( !isset($site_favorites['posts']) ) {
68 $site_favorites['posts'] = $site_favorites['site_favorites'];
69 unset($this->formatted_favorites[$site]['site_favorites']);
70 }
71 foreach ( $site_favorites['posts'] as $key => $favorite ){
72 unset($this->formatted_favorites[$site]['posts'][$key]);
73 $this->formatted_favorites[$site]['posts'][$favorite]['post_id'] = $favorite;
74 }
75 }
76 }
77
78 /**
79 * Add the post type to each favorite
80 */
81 private function addPostData()
82 {
83 $this->checkCurrentPost();
84 foreach ( $this->formatted_favorites as $site => $site_favorites ){
85 foreach ( $site_favorites['posts'] as $key => $favorite ){
86 $site_id = $this->formatted_favorites[$site]['site_id'];
87 $this->formatted_favorites[$site]['posts'][$key]['post_type'] = get_post_type($key);
88 $this->formatted_favorites[$site]['posts'][$key]['title'] = get_the_title($key);
89 $this->formatted_favorites[$site]['posts'][$key]['permalink'] = get_the_permalink($key);
90 $this->formatted_favorites[$site]['posts'][$key]['total'] = $this->counter->getCount($key, $site_id);
91 $this->formatted_favorites[$site]['posts'][$key]['thumbnails'] = $this->getThumbnails($key);
92 $this->formatted_favorites[$site]['posts'][$key]['excerpt'] = apply_filters('the_excerpt', get_post_field('post_excerpt', $key));
93 $button = new FavoriteButton($key, $site_id);
94 $this->formatted_favorites[$site]['posts'][$key]['button'] = $button->display(false);
95 }
96 $this->formatted_favorites[$site] = array_reverse($this->formatted_favorites[$site]);
97 }
98 }
99
100 /**
101 * Make sure the current post is updated in the array
102 * (for cookie/session favorites, so AJAX response returns array with correct posts without page refresh)
103 */
104 private function checkCurrentPost()
105 {
106 if ( !isset($this->post_id) || !isset($this->site_id) ) return;
107 if ( is_user_logged_in() ) return;
108 foreach ( $this->formatted_favorites as $site => $site_favorites ){
109 if ( $site_favorites['site_id'] == $this->site_id ) {
110 if ( isset($site_favorites['posts'][$this->post_id]) && $this->status == 'inactive' ){
111 unset($this->formatted_favorites[$site]['posts'][$this->post_id]);
112 } else {
113 $this->formatted_favorites[$site]['posts'][$this->post_id] = array('post_id' => $this->post_id);
114 }
115 }
116 }
117 }
118
119 /**
120 * Add thumbnail urls to the array
121 */
122 private function getThumbnails($post_id)
123 {
124 if ( !has_post_thumbnail($post_id) ) return false;
125 $sizes = get_intermediate_image_sizes();
126 $thumbnails = [];
127 foreach ( $sizes as $size ){
128 $url = get_the_post_thumbnail_url($post_id, $size);
129 $img = '<img src="' . $url . '" alt="' . get_the_title($post_id) . '" class="favorites-list-thumbnail" />';
130 $thumbnails[$size] = apply_filters('favorites/list/thumbnail', $img, $post_id, $size);
131 }
132 return $thumbnails;
133 }
134 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Favorite;
3
4 use Favorites\Config\SettingsRepository;
5
6 /**
7 * Sync all favorites for a specific site
8 */
9 class SyncAllFavorites
10 {
11 /**
12 * Favorites to Save
13 * @var array
14 */
15 private $favorites;
16
17 /**
18 * Settings Repository
19 */
20 private $settings_repo;
21
22 public function __construct()
23 {
24 $this->settings_repo = new SettingsRepository;
25 }
26
27 /**
28 * Sync the favorites
29 */
30 public function sync($favorites)
31 {
32 $this->favorites = $favorites;
33 $saveType = $this->settings_repo->saveType();
34 $this->$saveType();
35 $this->updateUserMeta();
36 }
37
38 /**
39 * Sync Session Favorites
40 */
41 private function session()
42 {
43 return $_SESSION['simplefavorites'] = $this->favorites;
44 }
45
46 /**
47 * Sync a Cookie Favorite
48 */
49 public function cookie()
50 {
51 setcookie( 'simplefavorites', json_encode( $this->favorites ), time() + apply_filters( 'simplefavorites_cookie_expiration_interval', 31556926 ), '/' );
52 return;
53 }
54
55 /**
56 * Update User Meta (logged in only)
57 */
58 private function updateUserMeta()
59 {
60 if ( !is_user_logged_in() ) return false;
61 return update_user_meta( intval(get_current_user_id()), 'simplefavorites', $this->favorites );
62 }
63 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Favorite;
3
4 use Favorites\Entities\User\UserRepository;
5 use Favorites\Helpers;
6
7 /**
8 * Sync a single favorite to a given save type
9 */
10 class SyncSingleFavorite
11 {
12 /**
13 * The Post ID
14 */
15 private $post_id;
16
17 /**
18 * The Site ID
19 */
20 private $site_id;
21
22 /**
23 * The Group ID
24 */
25 private $group_id;
26
27 /**
28 * User Repository
29 */
30 private $user;
31
32 public function __construct($post_id, $site_id, $group_id = 1)
33 {
34 $this->user = new UserRepository;
35 $this->post_id = $post_id;
36 $this->site_id = $site_id;
37 $this->group_id = $group_id;
38 }
39
40 /**
41 * Sync a Session Favorite
42 */
43 public function session()
44 {
45 if ( $this->user->isFavorite($this->post_id, $this->site_id) ) return $_SESSION['simplefavorites'] = $this->removeFavorite();
46 return $_SESSION['simplefavorites'] = $this->addFavorite();
47 }
48
49 /**
50 * Sync a Cookie Favorite
51 */
52 public function cookie()
53 {
54 if ( $this->user->isFavorite($this->post_id, $this->site_id) ){
55 $favorites = $this->removeFavorite();
56 setcookie( 'simplefavorites', json_encode( $favorites ), time() + apply_filters( 'simplefavorites_cookie_expiration_interval', 31556926 ), '/' );
57 return;
58 }
59 $favorites = $this->addFavorite();
60 setcookie( 'simplefavorites', json_encode( $favorites ), time() + apply_filters( 'simplefavorites_cookie_expiration_interval', 31556926 ), '/' );
61 return;
62 }
63
64 /**
65 * Update User Meta (logged in only)
66 */
67 public function updateUserMeta($favorites)
68 {
69 if ( !is_user_logged_in() ) return;
70 update_user_meta( intval(get_current_user_id()), 'simplefavorites', $favorites );
71 }
72
73 /**
74 * Remove a Favorite
75 */
76 private function removeFavorite()
77 {
78 $favorites = $this->user->getAllFavorites($this->site_id);
79
80 foreach($favorites as $key => $site_favorites){
81 if ( $site_favorites['site_id'] !== $this->site_id ) continue;
82 foreach($site_favorites['posts'] as $k => $fav){
83 if ( $fav == $this->post_id ) unset($favorites[$key]['posts'][$k]);
84 }
85 if ( !Helpers::groupsExist($site_favorites) ) return;
86 foreach( $site_favorites['groups'] as $group_key => $group){
87 if ( $group['group_id'] !== $this->group_id ) continue;
88 foreach ( $group['posts'] as $k => $g_post_id ){
89 if ( $g_post_id == $this->post_id ) unset($favorites[$key]['groups'][$group_key]['posts'][$k]);
90 }
91 }
92 }
93 $this->updateUserMeta($favorites);
94 return $favorites;
95 }
96
97 /**
98 * Add a Favorite
99 */
100 private function addFavorite()
101 {
102 $favorites = $this->user->getAllFavorites($this->site_id);
103 if ( !Helpers::siteExists($this->site_id, $favorites) ){
104 $favorites[] = [
105 'site_id' => $this->site_id,
106 'posts' => []
107 ];
108 }
109 // Loop through each site's favorites, continue if not the correct site id
110 foreach($favorites as $key => $site_favorites){
111 if ( $site_favorites['site_id'] !== $this->site_id ) continue;
112 $favorites[$key]['posts'][] = $this->post_id;
113
114 // Add the default group if it doesn't exist yet
115 if ( !Helpers::groupsExist($site_favorites) ){
116 $favorites[$key]['groups'] = [
117 [
118 'group_id' => 1,
119 'site_id' => $this->site_id,
120 'group_name' => __('Default List', 'favorites'),
121 'posts' => array()
122 ]
123 ];
124 }
125 foreach( $favorites[$key]['groups'] as $group_key => $group){
126 if ( $group['group_id'] == $this->group_id )
127 $favorites[$key]['groups'][$group_key]['posts'][] = $this->post_id;
128 }
129 }
130 $this->updateUserMeta($favorites);
131 return $favorites;
132 }
133 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\FavoriteList;
3
4 /**
5 * Get a full list of user favorites
6 * @param array of options from shortcode/api function
7 */
8 class FavoriteList extends FavoriteListBase
9 {
10 public function __construct($options)
11 {
12 parent::__construct($options);
13 }
14
15 /**
16 * Get the list
17 */
18 public function getList()
19 {
20 $list = ( !$this->list_options->customize_markup || !$this->list_options->custom_markup_html )
21 ? new FavoriteListTypeDefault($this->list_options)
22 : new FavoriteListTypeCustom($this->list_options);
23 return $list->getListMarkup();
24 }
25
26 /**
27 * Get a single listing
28 */
29 public function getListing($post_id)
30 {
31 $list = ( !$this->list_options->customize_markup || !$this->list_options->custom_markup_html )
32 ? new FavoriteListTypeDefault($this->list_options)
33 : new FavoriteListTypeCustom($this->list_options);
34 return $list->listing($post_id);
35 }
36 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\FavoriteList;
3
4 use Favorites\Config\SettingsRepository;
5 use Favorites\Entities\FavoriteList\FavoriteListDefault;
6 use Favorites\Entities\FavoriteList\FavoriteListCustom;
7
8 abstract class FavoriteListBase
9 {
10 /**
11 * List Options
12 * @var object
13 */
14 protected $list_options;
15
16 /**
17 * Settings Repository
18 */
19 protected $settings_repo;
20
21 public function __construct($list_options)
22 {
23 $this->list_options = $list_options;
24 $this->settings_repo = new SettingsRepository;
25 $this->setOptions();
26 }
27
28 /**
29 * Set the list default options
30 */
31 protected function setOptions()
32 {
33 $options = $this->list_options;
34 $this->list_options = new \stdClass;
35 $this->list_options->user_id = ( isset($options['user_id']) ) ? $options['user_id'] : null;
36 if ( ($this->list_options->user_id && isset($options['include_button'])) && ( get_current_user_id() !== $this->list_options->user_id ) ) unset($options['include_button']);
37 $this->list_options->site_id = ( isset($options['site_id']) ) ? $options['site_id'] : null;
38 $this->list_options->filters = ( isset($options['filters']) ) ? $options['filters'] : null;
39 $this->list_options->include_button = ( isset($options['include_button']) ) ? $options['include_button'] : false;
40 $this->list_options->include_thumbnails = ( isset($options['include_thumbnails']) ) ? $options['include_thumbnails'] : false;
41 $this->list_options->thumbnail_size = ( isset($options['thumbnail_size']) ) ? $options['thumbnail_size'] : 'thumbnail';
42 $this->list_options->include_excerpt = ( isset($options['include_excerpt']) ) ? $options['include_excerpt'] : false;
43 $this->list_options->include_links = ( isset($options['include_links']) ) ? $options['include_links'] : false;
44 $this->list_options->customized = $this->settings_repo->listCustomization('customize');
45 $this->list_options->wrapper_type = 'ul';
46 $this->list_options->wrapper_css = '';
47 $this->list_options->listing_type = 'li';
48 $this->list_options->listing_css = '';
49 $this->list_options->no_favorites = ( isset($options['no_favorites']) ) ? $options['no_favorites'] : '';
50 $this->setCustomOptions();
51 if ( !property_exists($this->list_options, 'customize_markup') ) $this->list_options->customize_markup = false;
52 if ( !property_exists($this->list_options, 'custom_markup_html') ) $this->list_options->custom_markup_html = false;
53 }
54
55 /**
56 * Set the list customized options
57 */
58 protected function setCustomOptions()
59 {
60 $options = $this->settings_repo->listCustomization('all');
61 if ( !$options ) return;
62 foreach ( $options as $option => $val ){
63 if ( $option == 'customize' ) continue;
64 if ( $val == '' ) continue;
65 $this->list_options->$option = ( $val == 'true' ) ? true : sanitize_text_field($val);
66 if ( $option == 'custom_markup_html' ) $this->list_options->custom_markup_html = $val;
67 }
68 }
69 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\FavoriteList;
3
4 use Favorites\Entities\User\UserFavorites;
5 use Favorites\Config\SettingsRepository;
6 use Favorites\Entities\FavoriteList\FavoriteListingPresenter;
7 use Favorites\Entities\PostType\PostTypeRepository;
8
9 /**
10 * Base class for favorite lists
11 */
12 abstract class FavoriteListTypeBase
13 {
14 /**
15 * List options
16 * @var object
17 */
18 protected $list_options;
19
20 /**
21 * User favorites object
22 */
23 protected $user_favorites;
24
25 /**
26 * Settings Repo
27 */
28 protected $settings_repo;
29
30 /**
31 * Post Type Repo
32 */
33 protected $post_type_repo;
34
35 /**
36 * User's Favorites
37 */
38 protected $favorites;
39
40 /**
41 * Listing Presenter
42 */
43 protected $listing_presenter;
44
45 public function __construct($list_options)
46 {
47 $this->settings_repo = new SettingsRepository;
48 $this->post_type_repo = new PostTypeRepository;
49 $this->user_favorites = new UserFavorites;
50 $this->listing_presenter = new FavoriteListingPresenter;
51 $this->list_options = $list_options;
52 $this->setApiOptions();
53 $this->setFavorites();
54 $this->setNoFavoritesText();
55 $this->setPostTypes();
56 }
57
58 /**
59 * Set the API options (defined in shortcode and api functions)
60 */
61 protected function setApiOptions()
62 {
63 $this->list_options->site_id = ( is_null($this->list_options->site_id) || $this->list_options->site_id == '' )
64 ? get_current_blog_id() : $this->list_options->site_id;
65 $this->list_options->user_id = ( is_null($this->list_options->user_id) || $this->list_options->user_id == '' )
66 ? null : $this->list_options->user_id;
67 $this->list_options->filters = ( is_null($this->list_options->filters) || $this->list_options->filters == '' )
68 ? null : $this->list_options->filters;
69 }
70
71 /**
72 * Set the favorites
73 */
74 protected function setFavorites()
75 {
76 $favorites = $this->user_favorites->getFavoritesArray($this->list_options->user_id, $this->list_options->site_id, $this->list_options->filters);
77 $this->favorites = ( isset($favorites[0]['site_id']) ) ? $favorites[0]['posts'] : $favorites;
78 }
79
80 /**
81 * Set the no favorites text
82 */
83 protected function setNoFavoritesText()
84 {
85 if ( $this->list_options->no_favorites == '' )
86 $this->list_options->no_favorites = $this->settings_repo->noFavoritesText();
87 }
88
89 /**
90 * Set the post types
91 */
92 protected function setPostTypes()
93 {
94 $this->list_options->post_types = implode(',', $this->post_type_repo->getAllPostTypes('names', true));
95 if ( isset($this->list_options->filters['post_type']) )
96 $this->list_options->post_types = implode(',', $this->list_options->filters['post_type']);
97 }
98
99 /**
100 * Generate the list opening
101 */
102 protected function listOpening()
103 {
104 $css = apply_filters('favorites/list/wrapper/css', $this->list_options->wrapper_css, $this->list_options);
105 $out = '<' . $this->list_options->wrapper_type;
106 $out .= ' class="favorites-list ' . $css . '" data-userid="' . $this->list_options->user_id . '" data-siteid="' . $this->list_options->site_id . '" ';
107 $out .= ( $this->list_options->include_button ) ? 'data-includebuttons="true"' : 'data-includebuttons="false"';
108 $out .= ( $this->list_options->include_links ) ? ' data-includelinks="true"' : ' data-includelinks="false"';
109 $out .= ( $this->list_options->include_thumbnails ) ? ' data-includethumbnails="true"' : ' data-includethumbnails="false"';
110 $out .= ( $this->list_options->include_excerpt ) ? ' data-includeexcerpts="true"' : ' data-includeexcerpts="false"';
111 $out .= ' data-thumbnailsize="' . $this->list_options->thumbnail_size . '"';
112 $out .= ' data-nofavoritestext="' . $this->list_options->no_favorites . '"';
113 $out .= ' data-posttypes="' . $this->list_options->post_types . '"';
114 $out .= '>';
115 return $out;
116 }
117
118 /**
119 * Generate the list closing
120 */
121 protected function listClosing()
122 {
123 return '</' . $this->list_options->wrapper_type . '>';
124 }
125
126 /**
127 * Generates the no favorites item
128 */
129 protected function noFavorites()
130 {
131 if ( !empty($this->favorites) ) return;
132 $out = $this->listOpening();
133 $out .= '<' . $this->list_options->wrapper_type;
134 $out .= ' data-postid="0" data-nofavorites class="no-favorites">' . $this->list_options->no_favorites;
135 $out .= '</' . $this->list_options->wrapper_type . '>';
136 $out .= $this->listClosing();
137 return $out;
138 }
139
140 /**
141 * Get the markup for a full list
142 */
143 public function getListMarkup()
144 {
145 if ( is_multisite() ) switch_to_blog($this->list_options->site_id);
146 if ( empty($this->favorites) ) return $this->noFavorites();
147
148 $out = $this->listOpening();
149 foreach ( $this->favorites as $key => $favorite ){
150 $out .= $this->listing($favorite);
151 }
152 $out .= $this->listClosing();
153 if ( is_multisite() ) restore_current_blog();
154 return $out;
155 }
156 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\FavoriteList;
3
4 use Favorites\Entities\User\UserFavorites;
5 use Favorites\Config\SettingsRepository;
6
7 /**
8 * Generate the list for custom markup list
9 */
10 class FavoriteListTypeCustom extends FavoriteListTypeBase
11 {
12
13 public function __construct($list_options)
14 {
15 parent::__construct($list_options);
16 }
17
18 public function listing($favorite)
19 {
20 return $this->listing_presenter->present($this->list_options, $this->list_options->custom_markup_html, $favorite);
21 }
22 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\FavoriteList;
3
4 use Favorites\Entities\Favorite\FavoriteButton;
5
6 /**
7 * Create a favorites list using the default markup
8 */
9 class FavoriteListTypeDefault extends FavoriteListTypeBase
10 {
11 public function __construct($list_options)
12 {
13 parent::__construct($list_options);
14 }
15
16 private function setTemplate()
17 {
18 $template = '';
19 if ( $this->list_options->include_thumbnails ) $template .= '[post_thumbnail_' . $this->list_options->thumbnail_size . ']';
20 $template .= "\n\n";
21 if ( $this->list_options->include_links ) $template .= '<a href="[post_permalink]">';
22 $template .= '[post_title]';
23 if ( $this->list_options->include_links ) $template .= '</a>';
24 $template .= "\n\n";
25 if ( $this->list_options->include_excerpt ) $template .= "[post_excerpt]\n\n";
26 if ( $this->list_options->include_button )$template .= "[favorites_button]";
27 return $template;
28 }
29
30 /**
31 * Generate a single listing
32 * @param int favorite post id
33 */
34 public function listing($favorite)
35 {
36 return $this->listing_presenter->present($this->list_options, $this->setTemplate(), $favorite);
37 }
38 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\FavoriteList;
3
4 /*
5 * Filters the favorites listing markup
6 */
7 class FavoriteListingPresenter
8 {
9 /**
10 * The list options
11 * @var object
12 */
13 private $list_options;
14
15 /**
16 * The Favorite Post ID
17 * @var int
18 */
19 private $favorite;
20
21 /**
22 * The custom markup
23 * @var str
24 */
25 private $markup;
26
27 /**
28 * The return html
29 * @var str
30 */
31 private $html;
32
33 /**
34 * Primary API Method
35 * @param str markup
36 * @param int favorite
37 */
38 public function present($list_options, $markup, $favorite)
39 {
40 $this->list_options = $list_options;
41 $this->markup = $markup;
42 $this->favorite = $favorite;
43
44 $this->listingOpening();
45 $this->filterMarkup();
46 $this->listingClosing();
47
48 return apply_filters('favorites/list/listing/html', $this->html, $this->markup, $this->favorite, $this->list_options);
49 }
50
51 /**
52 * Create the listing opening
53 */
54 private function listingOpening()
55 {
56 $css = apply_filters('favorites/list/listing/css', $this->list_options->listing_css, $this->list_options);
57 $this->html = '<' . $this->list_options->listing_type;
58 $this->html .= ' data-postid="' . $this->favorite . '" class="' . $css . '">';
59 }
60
61 /**
62 * Create the listing closing
63 */
64 private function listingClosing()
65 {
66 $this->html .= '</' . $this->list_options->listing_type . '>';
67 }
68
69 /**
70 * Filter the markup
71 */
72 private function filterMarkup()
73 {
74 $this->html .= apply_filters('the_content', $this->markup);
75 $this->replacePostFields();
76 $this->replaceFavoritesFields();
77 $this->replaceThumbnails();
78 $this->replaceCustomFields();
79 }
80
81 /**
82 * Replace Post Fields
83 */
84 private function replacePostFields()
85 {
86 $this->html = str_replace('[post_title]', get_the_title($this->favorite), $this->html);
87 $this->html = str_replace('[post_permalink]', get_permalink($this->favorite), $this->html);
88 $this->html = str_replace('[permalink]', '<a href="' . get_permalink($this->favorite) . '">', $this->html);
89 $this->html = str_replace('[/permalink]', '</a>', $this->html);
90 $this->html = str_replace('[post_excerpt]', $this->getPostExcerpt(), $this->html);
91 $this->html = str_replace('[post_content]', get_the_content($this->favorite), $this->html);
92 }
93
94 /**
95 * Replace Favorites Fields
96 */
97 private function replaceFavoritesFields()
98 {
99 $this->html = str_replace(
100 '[favorites_count]',
101 '<span class="simplefavorites-user-count" data-posttypes="' . $this->list_options->post_types . '" data-siteid="' . $this->list_options->site_id . '">' . get_favorites_count($this->favorite, $this->list_options->site_id) . '</span>',
102 $this->html
103 );
104 $this->html = str_replace('[favorites_button]', get_favorites_button($this->favorite, $this->list_options->site_id), $this->html);
105 }
106
107 /**
108 * Replace Thumbnails
109 */
110 private function replaceThumbnails()
111 {
112 $sizes = get_intermediate_image_sizes();
113 foreach ( $sizes as $size ){
114 if ( strpos($this->html, '[post_thumbnail_' . $size) !== false ){
115 $thumb = apply_filters('favorites/list/thumbnail', $this->getThumbnail($size), $this->favorite, $this->list_options->thumbnail_size);
116 $this->html = str_replace('[post_thumbnail_' . $size . ']', $thumb, $this->html);
117 }
118 }
119 }
120
121 /**
122 * Get a thumbnail
123 */
124 private function getThumbnail($size)
125 {
126 return ( has_post_thumbnail($this->favorite) ) ? get_the_post_thumbnail($this->favorite, $size) : ' ';
127 }
128
129 /**
130 * Replace custom fields
131 */
132 private function replaceCustomFields()
133 {
134 preg_match_all("/\[[^\]]*\]/", $this->html, $out);
135 if ( empty($out) ) return;
136 foreach($out[0] as $field){
137 $field_bracketed = $field;
138 $key = str_replace('[', '', $field);
139 $key = str_replace('custom_field:', '', $key);
140 $key = str_replace(']', '', $key);
141 $meta = get_post_meta($this->favorite, $key, true);
142 if ( !$meta ) $meta = '';
143 if ( is_array($meta) ) $meta = '';
144 $this->html = str_replace($field_bracketed, $meta, $this->html);
145 }
146 }
147
148 /**
149 * Get the post excerpt
150 */
151 private function getPostExcerpt()
152 {
153 $post_id = $this->favorite;
154 $custom_excerpt = get_post_field('post_excerpt', $this->favorite);
155 if ( $custom_excerpt ) return $custom_excerpt;
156
157 $the_post = get_post($post_id);
158 $the_excerpt = $the_post->post_content;
159 $excerpt_length = 35;
160 $the_excerpt = strip_tags(strip_shortcodes($the_excerpt));
161 $words = explode(' ', $the_excerpt, $excerpt_length + 1);
162
163 if ( count($words) > $excerpt_length ) :
164 array_pop($words);
165 array_push($words, '…');
166 $the_excerpt = implode(' ', $words);
167 endif;
168 return $the_excerpt;
169 }
170
171 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Post;
3
4 use Favorites\Config\SettingsRepository;
5 use Favorites\Entities\PostType\PostTypeRepository;
6
7 /**
8 * Add Post Favorite Counts to Admin Columns
9 */
10 class AdminColumns
11 {
12 /**
13 * Settings Repository
14 */
15 private $settings_repo;
16
17 /**
18 * Post Type Repository
19 */
20 private $post_type_repo;
21
22 /**
23 * Post Type
24 */
25 private $post_types;
26
27 public function __construct()
28 {
29 $this->settings_repo = new SettingsRepository;
30 $this->post_type_repo = new PostTypeRepository;
31 $this->setPostTypes();
32 $this->addHooks();
33 }
34
35 /**
36 * Set the Post Types
37 */
38 private function setPostTypes()
39 {
40 $this->post_types = [];
41 foreach ( $this->post_type_repo->getAllPostTypes() as $key => $posttype ) :
42 $display = $this->settings_repo->displayInPostType($posttype);
43 if ( isset($display['admincolumns']) ) array_push($this->post_types, $key);
44 endforeach;
45 }
46
47 /**
48 * Add Hooks
49 */
50 private function addHooks()
51 {
52 foreach($this->post_types as $type){
53 add_filter('manage_' . $type . '_posts_columns', [$this, 'addColumn']);
54 add_action('manage_' . $type . '_posts_custom_column', [$this, 'addColumnData'], 10, 2);
55 }
56 }
57
58 /**
59 * Add the column
60 */
61 public function addColumn($columns)
62 {
63 $new_column = ['favorites' => __('Favorites', 'favorites')];
64 return array_merge($columns, $new_column);
65 }
66
67 /**
68 * Add the column data
69 */
70 public function addColumnData($column, $post_id)
71 {
72 if ( $column !== 'favorites' ) return;
73 echo get_favorites_count($post_id);
74 }
75 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Post;
3
4 /**
5 * Returns the total number of favorites for a post
6 */
7 class FavoriteCount
8 {
9 /**
10 * Get the favorite count for a post
11 */
12 public function getCount($post_id, $site_id = null)
13 {
14 if ( (is_multisite()) && (isset($site_id)) && ($site_id !== "") ) switch_to_blog(intval($site_id));
15 $count = get_post_meta($post_id, 'simplefavorites_count', true);
16 if ( $count == '' ) $count = 0;
17 if ( (is_multisite()) && (isset($site_id) && ($site_id !== "")) ) restore_current_blog();
18 return intval($count);
19 }
20
21 /**
22 * Get the favorite count for all posts in a site
23 */
24 public function getAllCount($site_id = null)
25 {
26 if ( (is_multisite()) && (isset($site_id)) && ($site_id !== "") ) switch_to_blog(intval($site_id));
27 global $wpdb;
28 $query = "SELECT SUM(meta_value) AS favorites_count FROM {$wpdb->prefix}postmeta WHERE meta_key = 'simplefavorites_count'";
29 $count = $wpdb->get_var( $query );
30 if ( (is_multisite()) && (isset($site_id) && ($site_id !== "")) ) restore_current_blog();
31 return intval($count);
32 }
33 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Post;
3
4 use Favorites\Entities\User\UserRepository;
5 use Favorites\Entities\Post\FavoriteCount;
6
7 /**
8 * Get the users who have favorited a specific post
9 */
10 class PostFavorites
11 {
12 /**
13 * Post ID
14 */
15 private $post_id;
16
17 /**
18 * Site ID
19 */
20 private $site_id;
21
22 /**
23 * User Role
24 */
25 private $user_role;
26
27 /**
28 * User Repository
29 * @var Favorites\Entities\User\UserRepository;
30 */
31 private $user_repo;
32
33 /**
34 * Favorite Count
35 * @var Favorites\Entities\Post\FavoriteCount
36 */
37 private $favorite_count;
38
39 public function __construct($post_id, $site_id, $user_role)
40 {
41 $this->post_id = ( $post_id ) ? $post_id : get_the_id();
42 $this->site_id = ( $site_id ) ? $site_id : get_current_blog_id();
43 $this->user_role = ( $user_role ) ? $user_role : '';
44 $this->user_repo = new UserRepository;
45 $this->favorite_count = new FavoriteCount;
46 }
47
48 /**
49 * Get an array of users who favorited the post
50 * @return array of user objects
51 */
52 public function getUsers()
53 {
54 $users = $this->getAllUsers();
55 foreach($users as $key => $user){
56 if ( !$this->user_repo->isFavorite($this->post_id, $this->site_id, $user->ID) ){
57 unset($users[$key]);
58 }
59 }
60 return $users;
61 }
62
63 /**
64 * Get all Users
65 */
66 private function getAllUsers()
67 {
68 $user_query = new \WP_User_Query([
69 'blog_id' => ( $this->site_id ) ? $this->site_id : get_current_blog_id(),
70 'role' => $this->user_role
71 ]);
72 $users = $user_query->get_results();
73 return $users;
74 }
75
76 /**
77 * Get the number of Anonymous Users who have favorited the post
78 */
79 public function anonymousCount()
80 {
81 $total_count = $this->favorite_count->getCount($this->post_id, $this->site_id);
82 $registered_count = count($this->getUsers());
83 return $total_count - $registered_count;
84 }
85
86 /**
87 * Get an HTML formatted list of users who have favorited the post
88 * @param string $separator (list, or string to separate each item)
89 * @param boolean $include_anonymous
90 * @param string $anonymous_label
91 * @param string $anonymous_label_single
92 */
93 public function userList($separator, $include_anonymous, $anonymous_label, $anonymous_label_single)
94 {
95 $users = $this->getUsers();
96 $total = ( $include_anonymous ) ? count($users) + 1 : count($users);
97 $anonymous_count = $this->anonymousCount();
98
99 $out = ( $separator == 'list' ) ? '<ul>' : '';
100 foreach($users as $key => $user){
101 if ( $separator == 'list' ) $out .= '<li>';
102 $out .= $user->display_name;
103 if ( $separator == 'list' ) {
104 $out .= '</li>';
105 } else {
106 if ( $key + 1 < $total ) $out .= $separator;
107 }
108 }
109
110 if ( $include_anonymous ){
111 $label = ( $anonymous_count == 1 ) ? $anonymous_label_single : $anonymous_label;
112
113 if ( $separator == 'list' ){
114 $out .= '<li>' . $anonymous_count . ' ' . $label . '</li>';
115 } else {
116 $out .= $anonymous_count . ' ' . $label;
117 }
118 }
119
120 if ( $separator == 'list' ) $out .= '</ul>';
121
122 return apply_filters('simplefavorites_user_list', $out, $users, $anonymous_count);
123 }
124 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Post;
3
4 use Favorites\Config\SettingsRepository;
5 use Favorites\Entities\Favorite\FavoriteButton;
6
7 /**
8 * Post Actions and Filters
9 */
10 class PostHooks
11 {
12 /**
13 * Settings Repository
14 */
15 private $settings_repo;
16
17 /**
18 * The Content
19 */
20 private $content;
21
22 /**
23 * The Post Object
24 */
25 private $post;
26
27 public function __construct()
28 {
29 $this->settings_repo = new SettingsRepository;
30 add_filter('the_content', [$this, 'filterContent']);
31 }
32
33 /**
34 * Filter the Content
35 */
36 public function filterContent($content)
37 {
38 global $post;
39 if ( !$post ) return $content;
40 $this->post = $post;
41 $this->content = $content;
42
43 $display = $this->settings_repo->displayInPostType($post->post_type);
44 if ( !$display ) return $content;
45
46 return $this->addFavoriteButton($display);
47 }
48
49 /**
50 * Add the Favorite Button
51 * @todo add favorite button html
52 */
53 private function addFavoriteButton($display_in)
54 {
55 $output = '';
56
57 if ( isset($display_in['before_content']) && $display_in['before_content'] == 'true' ){
58 $output .= get_favorites_button();
59 }
60
61 $output .= $this->content;
62
63 if ( isset($display_in['after_content']) && $display_in['after_content'] == 'true' ){
64 $output .= get_favorites_button();
65 }
66 return $output;
67 }
68 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Post;
3
4 use Favorites\Config\SettingsRepository;
5 use Favorites\Entities\Post\FavoriteCount;
6
7 class PostMeta
8 {
9 /**
10 * Settings Repository
11 */
12 private $settings_repo;
13
14 public function __construct()
15 {
16 $this->settings_repo = new SettingsRepository;
17 add_action( 'add_meta_boxes', [$this, 'favoriteCountBox']);
18 }
19
20 /**
21 * Add the Favorite Count Meta Box for enabled Types
22 */
23 public function favoriteCountBox()
24 {
25 foreach ( $this->settings_repo->metaEnabled() as $type ){
26 add_meta_box(
27 'favorites',
28 __( 'Favorites', 'favorites' ),
29 [$this, 'favoriteCount'],
30 $type,
31 'side',
32 'low'
33 );
34 }
35 }
36
37 /**
38 * The favorite count
39 */
40 public function favoriteCount()
41 {
42 global $post;
43 $count = new FavoriteCount;
44 echo '<strong>' . __('Total Favorites', 'favorites') . ':</strong> ';
45 echo $count->getCount($post->ID);
46 echo '<input type="hidden" name="simplefavorites_count" value="' . $count->getCount($post->ID) . '">';
47 }
48 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\Post;
3
4 use Favorites\Entities\Post\FavoriteCount;
5 use Favorites\Entities\User\UserRepository;
6
7 /**
8 * Updates the favorite count for a given post
9 */
10 class SyncFavoriteCount
11 {
12 /**
13 * Post ID
14 * @var int
15 */
16 private $post_id;
17
18 /**
19 * Site ID
20 * @var int
21 */
22 private $site_id;
23
24 /**
25 * Status
26 * @var string
27 */
28 private $status;
29
30 /**
31 * Favorite Count
32 * @var object
33 */
34 private $favorite_count;
35
36 /**
37 * User Repository
38 */
39 private $user;
40
41 public function __construct($post_id, $status, $site_id)
42 {
43 $this->post_id = $post_id;
44 $this->status = $status;
45 $this->site_id = $site_id;
46 $this->favorite_count = new FavoriteCount;
47 $this->user = new UserRepository;
48 }
49
50 /**
51 * Sync the Post Total Favorites
52 */
53 public function sync()
54 {
55 if ( !$this->user->countsInTotal() ) return false;
56 $count = $this->favorite_count->getCount($this->post_id, $this->site_id);
57 $count = ( $this->status == 'active' ) ? $count + 1 : max(0, $count - 1);
58 return update_post_meta($this->post_id, 'simplefavorites_count', $count);
59 }
60 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\PostType;
3
4 class PostTypeRepository
5 {
6 /**
7 * Get all registered post types
8 * @since 1.0
9 * @return array
10 */
11 public function getAllPostTypes($return = 'names', $flat_array = false)
12 {
13 $args = [
14 'public' => true,
15 'show_ui' => true
16 ];
17 $post_types = get_post_types($args, $return);
18 if ( !$flat_array ) return $post_types;
19 $post_types_flat = [];
20 foreach ($post_types as $key => $value) {
21 $post_types_flat[] = $value;
22 }
23 return $post_types_flat;
24 }
25 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\User;
3
4 use Favorites\Entities\User\UserRepository;
5 use Favorites\Entities\Favorite\FavoriteFilter;
6 use Favorites\Entities\FavoriteList\FavoriteList;
7
8 class UserFavorites
9 {
10 /**
11 * User ID
12 * @var int
13 */
14 private $user_id;
15
16 /**
17 * Site ID
18 * @var int
19 */
20 private $site_id;
21
22 /**
23 * Display Links
24 * @var boolean
25 */
26 private $links;
27
28 /**
29 * Filters
30 * @var array
31 */
32 private $filters;
33
34 /**
35 * User Repository
36 */
37 private $user_repo;
38
39 public function __construct($user_id = null, $site_id = null, $links = false, $filters = null)
40 {
41 $this->user_id = $user_id;
42 $this->site_id = $site_id;
43 $this->links = $links;
44 $this->filters = $filters;
45 $this->user_repo = new UserRepository;
46 }
47
48 /**
49 * Get an array of favorites for specified user
50 */
51 public function getFavoritesArray($user_id = null, $site_id = null, $filters = null)
52 {
53 $user_id = ( isset($user_id) ) ? $user_id : $this->user_id;
54 $site_id = ( isset($site_id) ) ? $site_id : $this->site_id;
55 $favorites = $this->user_repo->getFavorites($user_id, $site_id);
56 if ( isset($filters) ) $this->filters = $filters;
57 if ( isset($this->filters) && is_array($this->filters) ) $favorites = $this->filterFavorites($favorites);
58 return $this->removeInvalidFavorites($favorites);
59 }
60
61 /**
62 * Remove non-existent or non-published favorites
63 * @param array $favorites
64 */
65 private function removeInvalidFavorites($favorites)
66 {
67 foreach($favorites as $key => $favorite){
68 if ( !$this->postExists($favorite) ) unset($favorites[$key]);
69 }
70 return $favorites;
71 }
72
73 /**
74 * Filter the favorites
75 * @since 1.1.1
76 * @param array $favorites
77 */
78 private function filterFavorites($favorites)
79 {
80 $favorites = new FavoriteFilter($favorites, $this->filters);
81 return $favorites->filter();
82 }
83
84 /**
85 * Return an HTML list of favorites for specified user
86 * @param $include_button boolean - whether to include the favorite button
87 * @param $include_thumbnails boolean - whether to include post thumbnails
88 * @param $thumbnail_size string - thumbnail size to display
89 * @param $include_excerpt boolean - whether to include the post excerpt
90 */
91 public function getFavoritesList($include_button = false, $include_thumbnails = false, $thumbnail_size = 'thumbnail', $include_excerpt = false, $no_favorites = '')
92 {
93 $list_args = [
94 'include_button' => $include_button,
95 'include_thumbnails' => $include_thumbnails,
96 'thumbnail_size' => $thumbnail_size,
97 'include_excerpt' => $include_excerpt,
98 'include_links' => $this->links,
99 'site_id' => $this->site_id,
100 'user_id' => $this->user_id,
101 'no_favorites' => $no_favorites,
102 'filters' => $this->filters,
103 ];
104 $list = new FavoriteList($list_args);
105 return $list->getList();
106 }
107
108 /**
109 * Check if post exists and is published
110 */
111 private function postExists($id)
112 {
113 $allowed_statuses = ( isset($this->filters['status']) && is_array($this->filters['status']) ) ? $this->filters['status'] : array('publish');
114 $status = get_post_status($id);
115 if ( !$status ) return false;
116 if ( !in_array($status, $allowed_statuses) ) return false;
117 return true;
118 }
119 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Entities\User;
3
4 use Favorites\Config\SettingsRepository;
5 use Favorites\Helpers;
6 use Favorites\Entities\Favorite\FavoritesArrayFormatter;
7
8 class UserRepository
9 {
10 /**
11 * Settings Repository
12 */
13 private $settings_repo;
14
15 public function __construct()
16 {
17 $this->settings_repo = new SettingsRepository;
18 }
19
20 /**
21 * Display button for current user
22 * @return boolean
23 */
24 public function getsButton()
25 {
26 if ( is_user_logged_in() ) return true;
27 if ( $this->settings_repo->anonymous('display') ) return true;
28 if ( $this->settings_repo->requireLogin() ) return true;
29 if ( $this->settings_repo->redirectAnonymous() ) return true;
30 return false;
31 }
32
33 /**
34 * Get All of current user's favorites (includes all sites)
35 * @return array (multidimensional)
36 */
37 public function getAllFavorites()
38 {
39 if ( is_user_logged_in() ) {
40 $all_favorites = $this->getLoggedInFavorites();
41 } else {
42 $saveType = $this->settings_repo->saveType();
43 $favorites = ( $saveType == 'cookie' ) ? $this->getCookieFavorites() : $this->getSessionFavorites();
44 $all_favorites = $this->favoritesWithSiteID($favorites);
45 }
46
47 /**
48 * Filter All of current user's favorites.
49 *
50 * @since 1.3.0
51 * @param array The original current user's favorites.
52 */
53 $all_favorites = apply_filters('favorites/user/favorites/all', $all_favorites);
54
55 return $all_favorites;
56 }
57
58 /**
59 * Get User's Favorites by Site ID (includes a single site)
60 * @return array (flat)
61 */
62 public function getFavorites($user_id = null, $site_id = null, $group_id = null)
63 {
64 if ( is_user_logged_in() && !$user_id ) $user_id = get_current_user_id();
65 if ( is_user_logged_in() || $user_id ) {
66 $favorites = $this->getLoggedInFavorites($user_id, $site_id, $group_id);
67 } else {
68 $saveType = $this->settings_repo->saveType();
69 $favorites = ( $saveType == 'cookie' )
70 ? $this->getCookieFavorites($site_id, $group_id)
71 : $this->getSessionFavorites($site_id, $group_id);
72 }
73
74 /**
75 * Filter a User's Favorites.
76 *
77 * @since 1.3.0
78 * @param array The original User's Favorites.
79 */
80 $favorites = apply_filters('favorites/user/favorites', $favorites);
81
82 return $favorites;
83 }
84
85 /**
86 * Check for Site ID in user's favorites
87 * Multisite Compatibility for >1.1
88 * 1.2 compatibility with new naming structure
89 * @since 1.1
90 */
91 private function favoritesWithSiteID($favorites)
92 {
93 if ( Helpers::keyExists('site_favorites', $favorites) ){
94 foreach($favorites as $key => $site_favorites){
95 if ( !isset($favorites[$key]['site_favorites']) ) continue;
96 $favorites[$key]['posts'] = $favorites[$key]['site_favorites'];
97 unset($favorites[$key]['site_favorites']);
98 if ( isset($favorites[$key]['total']) ) unset($favorites[$key]['total']);
99 }
100 }
101 if ( Helpers::keyExists('site_id', $favorites) ) return $favorites;
102 $new_favorites = [
103 [
104 'site_id' => 1,
105 'posts' => $favorites
106 ]
107 ];
108 return $new_favorites;
109 }
110
111 /**
112 * Check for Groups array in user's favorites
113 * Add all favorites to the default group if it doesn't exist
114 * Compatibility for < 2.2
115 * @since 2.2
116 */
117 private function favoritesWithGroups($favorites)
118 {
119 if ( Helpers::groupsExist($favorites[0]) ) return $favorites;
120 $data = [
121 'group_id' => 1,
122 'site_id' => $favorites[0]['site_id'],
123 'group_name' => __('Default List', 'favorites'),
124 'posts' => $favorites[0]['posts']
125 ];
126 $favorites[0]['groups'] = [
127 $data
128 ];
129 return $favorites;
130 }
131
132 /**
133 * Get Logged In User Favorites
134 */
135 private function getLoggedInFavorites($user_id = null, $site_id = null, $group_id = null)
136 {
137 $user_id = ( is_null($user_id) ) ? get_current_user_id() : $user_id;
138 $favorites = get_user_meta($user_id, 'simplefavorites');
139 if ( empty($favorites) ) return array(array('site_id'=> 1, 'posts' => [], 'groups' => [] ));
140
141 $favorites = $this->favoritesWithSiteID($favorites[0]);
142 $favorites = $this->favoritesWithGroups($favorites);
143
144 if ( !is_null($site_id) && is_null($group_id) ) $favorites = Helpers::pluckSiteFavorites($site_id, $favorites);
145 if ( !is_null($group_id) ) $favorites = Helpers::pluckGroupFavorites($group_id, $site_id, $favorites);
146
147 return $favorites;
148 }
149
150 /**
151 * Get Session Favorites
152 */
153 private function getSessionFavorites($site_id = null, $group_id = null)
154 {
155 if ( !isset($_SESSION['simplefavorites']) ) $_SESSION['simplefavorites'] = [];
156 $favorites = $_SESSION['simplefavorites'];
157 $favorites = $this->favoritesWithSiteID($favorites);
158 $favorites = $this->favoritesWithGroups($favorites);
159 if ( !is_null($site_id) && is_null($group_id) ) $favorites = Helpers::pluckSiteFavorites($site_id, $favorites);
160 if ( !is_null($group_id) ) $favorites = Helpers::pluckGroupFavorites($group_id, $site_id, $favorites);
161 return $favorites;
162 }
163
164 /**
165 * Get Cookie Favorites
166 */
167 private function getCookieFavorites($site_id = null, $group_id = null)
168 {
169 if ( !isset($_COOKIE['simplefavorites']) ) $_COOKIE['simplefavorites'] = json_encode([]);
170 $favorites = json_decode(stripslashes($_COOKIE['simplefavorites']), true);
171 $favorites = $this->favoritesWithSiteID($favorites);
172 $favorites = $this->favoritesWithGroups($favorites);
173 if ( isset($_POST['user_consent_accepted']) && $_POST['user_consent_accepted'] == 'true' ) $favorites[0]['consent_provided'] = time();
174 if ( !is_null($site_id) && is_null($group_id) ) $favorites = Helpers::pluckSiteFavorites($site_id, $favorites);
175 if ( !is_null($group_id) ) $favorites = Helpers::pluckGroupFavorites($group_id, $site_id, $favorites);
176 return $favorites;
177 }
178
179 /**
180 * Has the user favorited a specified post?
181 * @param int $post_id
182 * @param int $site_id
183 * @param int $user_id
184 * @param int $group_id
185 */
186 public function isFavorite($post_id, $site_id = 1, $user_id = null, $group_id = null)
187 {
188 $favorites = $this->getFavorites($user_id, $site_id, $group_id);
189 if ( in_array($post_id, $favorites) ) return true;
190 return false;
191 }
192
193 /**
194 * Does the user count in total favorites?
195 * @return boolean
196 */
197 public function countsInTotal()
198 {
199 if ( is_user_logged_in() ) return true;
200 return $this->settings_repo->anonymous('save');
201 }
202
203 /**
204 * Format an array of favorites
205 * @param $post_id - int, post to add to array (for session/cookie favorites)
206 * @param $site_id - int, site id for post_id
207 */
208 public function formattedFavorites($post_id = null, $site_id = null, $status = null)
209 {
210 $favorites = $this->getAllFavorites();
211 $formatter = new FavoritesArrayFormatter;
212 return $formatter->format($favorites, $post_id, $site_id, $status);
213 }
214
215 /**
216 * Has the user consented to cookies (if applicable)
217 */
218 public function consentedToCookies()
219 {
220 if ( $this->settings_repo->saveType() !== 'cookie' ) return true;
221 if ( isset($_POST['user_consent_accepted']) && $_POST['user_consent_accepted'] == 'true' ) return true;
222 if ( !$this->settings_repo->consent('require') ) return true;
223 if ( isset($_COOKIE['simplefavorites']) ){
224 $cookie = json_decode(stripslashes($_COOKIE['simplefavorites']), true);
225 if ( isset($cookie[0]['consent_provided']) ) return true;
226 if ( isset($cookie[0]['consent_denied']) ) return false;
227 }
228 return false;
229 }
230
231 /**
232 * Has the user denied consent to cookies explicitly
233 */
234 public function deniedCookies()
235 {
236 if ( $this->settings_repo->saveType() !== 'cookie' ) return false;
237 if ( !$this->settings_repo->consent('require') ) return false;
238 if ( isset($_COOKIE['simplefavorites']) ){
239 $cookie = json_decode(stripslashes($_COOKIE['simplefavorites']), true);
240 if ( isset($cookie[0]['consent_denied']) ) return true;
241 }
242 return false;
243 }
244 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Events;
3
4 use Favorites\Listeners\FavoriteButton;
5 use Favorites\Listeners\FavoritesArray;
6 use Favorites\Listeners\ClearFavorites;
7 use Favorites\Listeners\FavoriteCount;
8 use Favorites\Listeners\FavoriteList;
9 use Favorites\Listeners\CookieConsent;
10
11 class RegisterPublicEvents
12 {
13 public function __construct()
14 {
15 // Front End Favorite Button
16 add_action( 'wp_ajax_nopriv_favorites_favorite', [$this, 'favoriteButton']);
17 add_action( 'wp_ajax_favorites_favorite', [$this, 'favoriteButton']);
18
19 // User's Favorited Posts (array of IDs)
20 add_action( 'wp_ajax_nopriv_favorites_array', [$this, 'favoritesArray']);
21 add_action( 'wp_ajax_favorites_array', [$this, 'favoritesArray']);
22
23 // Clear Favorites
24 add_action( 'wp_ajax_nopriv_favorites_clear', [$this, 'clearFavorites']);
25 add_action( 'wp_ajax_favorites_clear', [$this, 'clearFavorites']);
26
27 // Total Favorite Count
28 add_action( 'wp_ajax_nopriv_favorites_totalcount', [$this, 'favoriteCount']);
29 add_action( 'wp_ajax_favorites_totalcount', [$this, 'favoriteCount']);
30
31 // Single Favorite List
32 add_action( 'wp_ajax_nopriv_favorites_list', [$this, 'favoriteList']);
33 add_action( 'wp_ajax_favorites_list', [$this, 'favoriteList']);
34
35 // Accept/Deny Cookies
36 add_action( 'wp_ajax_nopriv_favorites_cookie_consent', [$this, 'cookiesConsented']);
37 add_action( 'wp_ajax_favorites_cookie_consent', [$this, 'cookiesConsented']);
38
39 }
40
41 /**
42 * Favorite Button
43 */
44 public function favoriteButton()
45 {
46 new FavoriteButton;
47 }
48
49 /**
50 * Generate a Nonce
51 */
52 public function nonce()
53 {
54 new NonceHandler;
55 }
56
57 /**
58 * Get an array of current user's favorites
59 */
60 public function favoritesArray()
61 {
62 new FavoritesArray;
63 }
64
65 /**
66 * Clear all Favorites
67 */
68 public function clearFavorites()
69 {
70 new ClearFavorites;
71 }
72
73 /**
74 * Favorite Count for a single post
75 */
76 public function favoriteCount()
77 {
78 new FavoriteCount;
79 }
80
81 /**
82 * Single Favorite List for a Specific User
83 */
84 public function favoriteList()
85 {
86 new FavoriteList;
87 }
88
89 /**
90 * Cookies were either accepted or denied
91 */
92 public function cookiesConsented()
93 {
94 new CookieConsent;
95 }
96 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 /**
3 * Static Wrapper for Bootstrap Class
4 * Prevents T_STRING error when checking for 5.3.2
5 */
6 class Favorites
7 {
8 public static function init()
9 {
10 // dev/live
11 global $favorites_env;
12 $favorites_env = 'live';
13
14 global $favorites_version;
15 $favorites_version = '2.3.2';
16
17 global $favorites_name;
18 $favorites_name = __('Favorites', 'favorites');
19
20 $app = new Favorites\Bootstrap;
21 }
22 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites;
3
4 /**
5 * Static Helper Methods
6 */
7 class Helpers
8 {
9 /**
10 * Plugin Root Directory
11 */
12 public static function plugin_url()
13 {
14 return plugins_url() . '/' . dirname( plugin_basename( FAVORITES_PLUGIN_FILE ) );
15 }
16
17 /**
18 * Views
19 */
20 public static function view($file)
21 {
22 return dirname(__FILE__) . '/Views/' . $file . '.php';
23 }
24
25 /**
26 * Plugin Version
27 */
28 public static function version()
29 {
30 global $favorites_version;
31 return $favorites_version;
32 }
33
34 /**
35 * Get File Contents
36 */
37 public static function getFileContents($file)
38 {
39 return file_get_contents( dirname( dirname(__FILE__) ) . '/' . $file);
40 }
41
42 /**
43 * Multidemensional array key search
44 * @since 1.1
45 * @return boolean
46 */
47 public static function keyExists($needle, $haystack)
48 {
49 if ( array_key_exists($needle, $haystack) || in_array($needle, $haystack) ){
50 return true;
51 } else {
52 $return = false;
53 foreach ( array_values($haystack) as $value ){
54 if ( is_array($value) && !$return ) $return = self::keyExists($needle, $value);
55 }
56 return $return;
57 }
58 }
59
60 /**
61 * Site ID Exists
62 * checks if site id is in favorites array yet
63 * @since 1.1
64 * @return boolean
65 */
66 public static function siteExists($site_id, $meta)
67 {
68 foreach ( $meta as $key => $site ){
69 if ( $site['site_id'] == $site_id ) return true;
70 }
71 return false;
72 }
73
74 /**
75 * Groups Exists
76 * checks if groups array is in favorites array yet
77 * @since 2.2
78 * @return boolean
79 */
80 public static function groupsExist($site_favorites)
81 {
82 if ( isset($site_favorites['groups']) && !empty($site_favorites['groups']) ) return true;
83 return false;
84 }
85
86 /**
87 * Pluck the site favorites from saved meta array
88 * @since 1.1
89 * @param int $site_id
90 * @param array $favorites (user meta)
91 * @return array
92 */
93 public static function pluckSiteFavorites($site_id, $all_favorites)
94 {
95 foreach($all_favorites as $site_favorites){
96 if ( $site_favorites['site_id'] == $site_id && isset($site_favorites['posts']) ) return $site_favorites['posts'];
97 }
98 return array();
99 }
100
101 /**
102 * Pluck the site favorites from saved meta array
103 * @since 1.1
104 * @param int $site_id
105 * @param array $favorites (user meta)
106 * @return array
107 */
108 public static function pluckGroupFavorites($group_id, $site_id, $all_favorites)
109 {
110 foreach($all_favorites as $key => $site_favorites){
111 if ( $site_favorites['site_id'] !== $site_id ) continue;
112 foreach ( $all_favorites[$key]['groups'] as $group ){
113 if ( $group['group_id'] == $group_id ){
114 return $group['posts'];
115 }
116 }
117 }
118 return array();
119 }
120 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Listeners;
3
4 use Favorites\Config\SettingsRepository;
5 use Favorites\Entities\User\UserRepository;
6
7 /**
8 * Base AJAX class
9 */
10 abstract class AJAXListenerBase
11 {
12 /**
13 * Form Data
14 */
15 protected $data;
16
17 /**
18 * Settings Repo
19 */
20 protected $settings_repo;
21
22 /**
23 * User Repo
24 */
25 protected $user_repo;
26
27 public function __construct($check_nonce = true)
28 {
29 $this->settings_repo = new SettingsRepository;
30 $this->user_repo = new UserRepository;
31 $this->checkLogIn();
32 $this->checkConsent();
33 }
34
35 /**
36 * Send an Error Response
37 * @param $error string
38 */
39 protected function sendError($error = null)
40 {
41 $error = ( $error ) ? $error : __('There was an error processing the request.', 'favorites');
42 return wp_send_json([
43 'status' => 'error',
44 'message' => $error
45 ]);
46 }
47
48 /**
49 * Check if logged in
50 */
51 protected function checkLogIn()
52 {
53 if ( is_user_logged_in() ) return true;
54 if ( $this->settings_repo->anonymous('display') ) return true;
55 if ( $this->settings_repo->requireLogin() ) return $this->response(['status' => 'unauthenticated']);
56 if ( $this->settings_repo->redirectAnonymous() ) return $this->response(['status' => 'unauthenticated']);
57 }
58
59 /**
60 * Check if consent is required and received
61 */
62 protected function checkConsent()
63 {
64 if ( $this->user_repo->consentedToCookies() ) return;
65 return $this->response([
66 'status' => 'consent_required',
67 'message' => $this->settings_repo->consent('modal'),
68 'accept_text' => $this->settings_repo->consent('consent_button_text'),
69 'deny_text' => $this->settings_repo->consent('deny_button_text'),
70 'post_data' => $_POST
71 ]);
72 }
73
74 /**
75 * Send a response
76 */
77 protected function response($response)
78 {
79 return wp_send_json($response);
80 }
81 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Listeners;
3
4 use Favorites\Entities\Favorite\Favorite;
5 use Favorites\Entities\Favorite\SyncAllFavorites;
6 use Favorites\Entities\Post\SyncFavoriteCount;
7
8 class ClearFavorites extends AJAXListenerBase
9 {
10 /**
11 * Favorites Sync
12 */
13 private $favorites_sync;
14
15 public function __construct()
16 {
17 parent::__construct();
18 $this->favorites_sync = new SyncAllFavorites;
19 $this->setFormData();
20 $this->clearFavorites();
21 $this->sendResponse();
22 }
23
24 /**
25 * Set Form Data
26 */
27 private function setFormData()
28 {
29 $this->data['siteid'] = intval(sanitize_text_field($_POST['siteid']));
30 $this->data['old_favorites'] = $this->user_repo->formattedFavorites();
31 }
32
33 /**
34 * Remove all user's favorites from the specified site
35 */
36 private function clearFavorites()
37 {
38 $user = ( is_user_logged_in() ) ? get_current_user_id() : null;
39 do_action('favorites_before_clear', $this->data['siteid'], $user);
40 $favorites = $this->user_repo->getAllFavorites();
41 foreach($favorites as $key => $site_favorites){
42 if ( $site_favorites['site_id'] == $this->data['siteid'] ) {
43 $this->updateFavoriteCounts($site_favorites);
44 unset($favorites[$key]);
45 }
46 }
47 $this->favorites_sync->sync($favorites);
48
49 do_action('favorites_after_clear', $this->data['siteid'], $user);
50 }
51
52 /**
53 * Update all the cleared post favorite counts
54 */
55 private function updateFavoriteCounts($site_favorites)
56 {
57 foreach($site_favorites['posts'] as $favorite){
58 $count_sync = new SyncFavoriteCount($favorite, 'inactive', $this->data['siteid']);
59 $count_sync->sync();
60 }
61 }
62
63 /**
64 * Set and send the response
65 */
66 private function sendResponse()
67 {
68 $favorites = $this->user_repo->formattedFavorites();
69 $this->response([
70 'status' => 'success',
71 'old_favorites' => $this->data['old_favorites'],
72 'favorites' => $favorites
73 ]);
74 }
75 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Listeners;
3
4 use Favorites\Entities\User\UserRepository;
5
6 class CookieConsent
7 {
8 /**
9 * Consented?
10 * @var bool
11 */
12 private $consent;
13
14 /**
15 * User Repo
16 */
17 private $user_repo;
18
19 public function __construct()
20 {
21 $this->user_repo = new UserRepository;
22 $this->setConsent();
23 $this->respond();
24 }
25
26 private function setConsent()
27 {
28 $this->consent = ( isset($_POST['consent']) && $_POST['consent'] == 'true' ) ? true : false;
29 if ( $this->consent ){
30 $this->setApprove();
31 return;
32 }
33 $this->setDeny();
34 }
35
36 private function setApprove()
37 {
38 $cookie = [];
39 if ( isset($_COOKIE['simplefavorites']) ) {
40 $cookie = json_decode(stripslashes($_COOKIE['simplefavorites']), true);
41 } else {
42 $cookie = $this->user_repo->getAllFavorites();
43 }
44 $cookie[0]['consent_provided'] = time();
45 setcookie( 'simplefavorites', json_encode( $cookie ), time() + apply_filters( 'simplefavorites_cookie_expiration_interval', 31556926 ), '/' );
46 }
47
48 private function setDeny()
49 {
50 $cookie = [];
51 $cookie[0]['consent_denied'] = time();
52 setcookie( 'simplefavorites', json_encode( $cookie ), time() + apply_filters( 'simplefavorites_cookie_expiration_interval', 31556926 ), '/' );
53 }
54
55 private function respond()
56 {
57 wp_send_json([
58 'status' => 'success',
59 'consent' => $this->consent
60 ]);
61 }
62 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Listeners;
3
4 use Favorites\Entities\Favorite\Favorite;
5
6 class FavoriteButton extends AJAXListenerBase
7 {
8 public function __construct()
9 {
10 parent::__construct();
11 $this->setFormData();
12 $this->updateFavorite();
13 }
14
15 /**
16 * Set Form Data
17 */
18 private function setFormData()
19 {
20 $this->data['postid'] = intval(sanitize_text_field($_POST['postid']));
21 $this->data['siteid'] = intval(sanitize_text_field($_POST['siteid']));
22 $this->data['status'] = ( $_POST['status'] == 'active') ? 'active' : 'inactive';
23 $this->data['groupid'] = ( isset($_POST['groupid']) && $_POST['groupid'] !== '' ) ? intval($_POST['groupid']) : 1;
24 }
25
26 /**
27 * Update the Favorite
28 */
29 private function updateFavorite()
30 {
31 try {
32 $this->beforeUpdateAction();
33 if ( !$this->validates() ) throw new \Exception(__('Invalid post.', 'favorites'));
34 $favorite = new Favorite;
35 $favorite->update($this->data['postid'], $this->data['status'], $this->data['siteid'], $this->data['groupid']);
36 $this->afterUpdateAction();
37 $this->response([
38 'status' => 'success',
39 'favorite_data' => [
40 'id' => $this->data['postid'],
41 'siteid' => $this->data['siteid'],
42 'status' => $this->data['status'],
43 'groupid' => $this->data['groupid'],
44 'save_type' => $favorite->saveType()
45 ],
46 'favorites' => $this->user_repo->formattedFavorites($this->data['postid'], $this->data['siteid'], $this->data['status'])
47 ]);
48 } catch ( \Exception $e ){
49 return $this->sendError($e->getMessage());
50 }
51 }
52
53 /**
54 * Before Update Action
55 * Provides hook for performing actions before a favorite
56 */
57 private function beforeUpdateAction()
58 {
59 $user = ( is_user_logged_in() ) ? get_current_user_id() : null;
60 do_action('favorites_before_favorite', $this->data['postid'], $this->data['status'], $this->data['siteid'], $user);
61 }
62
63 /**
64 * After Update Action
65 * Provides hook for performing actions after a favorite
66 */
67 private function afterUpdateAction()
68 {
69 $user = ( is_user_logged_in() ) ? get_current_user_id() : null;
70 do_action('favorites_after_favorite', $this->data['postid'], $this->data['status'], $this->data['siteid'], $user);
71 }
72
73 /**
74 * Validate the Favorite
75 */
76 private function validates()
77 {
78 $post_type = get_post_type($this->data['postid']);
79 $enabled = $this->settings_repo->displayInPostType($post_type);
80 $post_type_object = get_post_type_object(get_post_type($this->data['postid']));
81 if ( !$post_type_object ) return false;
82 if ( !$post_type_object->public || !$enabled ) return false;
83 return true;
84 }
85 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Listeners;
3
4 use Favorites\Entities\Post\FavoriteCount as FavoriteCounter;
5
6 /**
7 * Return the total number of favorites for a specified post
8 */
9 class FavoriteCount extends AJAXListenerBase
10 {
11 /**
12 * Favorite Counter
13 */
14 private $favorite_counter;
15
16 public function __construct()
17 {
18 parent::__construct();
19 $this->favorite_counter = new FavoriteCounter;
20 $this->setData();
21 $this->sendCount();
22 }
23
24 private function setData()
25 {
26 $this->data['postid'] = ( isset($_POST['postid']) ) ? intval($_POST['postid']) : null;
27 $this->data['siteid'] = ( isset($_POST['siteid']) ) ? intval($_POST['siteid']) : null;
28 }
29
30 private function sendCount()
31 {
32 $this->response([
33 'status' => 'success',
34 'count' => $this->favorite_counter->getCount($this->data['postid'], $this->data['siteid'])
35 ]);
36 }
37 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Listeners;
3
4 use Favorites\Entities\User\UserFavorites;
5
6 class FavoriteList extends AJAXListenerBase
7 {
8 /**
9 * Form Data
10 * @var array
11 */
12 protected $data;
13
14 /**
15 * List HTML
16 */
17 private $list;
18
19 public function __construct()
20 {
21 parent::__construct();
22 $this->setData();
23 $this->getList();
24 wp_send_json(['status' => 'success', 'list' => $this->list, 'data' => $this->data]);
25 }
26
27 /**
28 * Set the User ID & Site ID
29 */
30 private function setData()
31 {
32 $this->data['user_id'] = ( isset($_POST['userid']) ) ? intval($_POST['userid']) : null;
33 $this->data['site_id'] = ( isset($_POST['siteid']) ) ? intval($_POST['siteid']) : null;
34 $this->data['include_links'] = ( isset($_POST['include_links']) && $_POST['include_links'] == 'true' ) ? true : false;
35 $this->data['include_buttons'] = ( isset($_POST['include_buttons']) && $_POST['include_buttons'] == 'true' ) ? true : false;
36 $this->data['include_thumbnails'] = ( isset($_POST['include_thumbnails']) && $_POST['include_thumbnails'] == 'true' ) ? true : false;
37 $this->data['thumbnail_size'] = ( isset($_POST['thumbnail_size']) && $_POST['thumbnail_size'] != '' ) ? sanitize_text_field($_POST['thumbnail_size']) : 'thumbnail';
38 $this->data['include_excerpt'] = ( isset($_POST['include_excerpt']) && $_POST['include_excerpt'] == 'true' ) ? true : false;
39 $this->data['no_favorites'] = ( isset($_POST['no_favorites']) ) ? sanitize_text_field($_POST['no_favorites']) : '';
40 $this->data['post_types'] = ( isset($_POST['post_types']) ) ? explode(',', $_POST['post_types']) : array();
41 }
42
43 /**
44 * Get the favorites list
45 */
46 private function getList()
47 {
48 global $blog_id;
49 $site_id = ( is_multisite() && is_null($site_id) ) ? $blog_id : $site_id;
50 if ( !is_multisite() ) $site_id = 1;
51
52 $filters = ( !empty($this->data['post_types']) ) ? ['post_type' => $this->data['post_types']] : null;
53
54 $favorites = new UserFavorites(
55 $this->data['user_id'],
56 $this->data['site_id'],
57 $this->data['include_links'],
58 $filters
59 );
60 $this->list = $favorites->getFavoritesList(
61 $include_button = $this->data['include_buttons'],
62 $this->data['include_thumbnails'],
63 $this->data['thumbnail_size'],
64 $this->data['include_excerpt'],
65 $this->data['no_favorites']
66 );
67 }
68 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Favorites\Listeners;
3
4 /**
5 * Return an array of user's favorited posts
6 */
7 class FavoritesArray extends AJAXListenerBase
8 {
9 /**
10 * User Favorites
11 * @var array
12 */
13 private $favorites;
14
15 public function __construct()
16 {
17 parent::__construct(false);
18 $this->setFavorites();
19 $this->response(['status'=>'success', 'favorites' => $this->favorites]);
20 }
21
22 /**
23 * Get the Favorites
24 */
25 private function setFavorites()
26 {
27 $favorites = $this->user_repo->formattedFavorites();
28 $this->favorites = $favorites;
29 }
30 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php settings_fields( 'simple-favorites-general' ); ?>
2
3 <h3><?php _e('Page Cache', 'favorites'); ?></h3>
4 <div class="simple-favorites-post-types">
5 <div class="post-type-row">
6 <div class="post-type-checkbox">
7 <input type="checkbox" name="simplefavorites_cache_enabled" value="true" <?php if ( $this->settings_repo->cacheEnabled() ) echo 'checked'; ?> />
8 </div>
9 <div class="post-type-name">
10 <?php _e('Cache Enabled on Site (Favorites content is injected on page load with AJAX request)', 'favorites'); ?>
11 </div>
12 </div><!-- .post-type-row -->
13 </div><!-- .simple-favorites-post-types -->
14
15 <h3><?php _e('Development Mode', 'favorites'); ?></h3>
16 <div class="simple-favorites-post-types">
17 <div class="post-type-row">
18 <div class="post-type-checkbox">
19 <input type="checkbox" name="simplefavorites_dev_mode" value="true" <?php if ( $this->settings_repo->devMode() ) echo 'checked'; ?> />
20 </div>
21 <div class="post-type-name">
22 <?php _e('Enable Development Mode (logs JS responses in the console for debugging)'); ?>
23 </div>
24 </div><!-- .post-type-row -->
25 </div><!-- .simple-favorites-post-types -->
26
27 <h3><?php _e('Dependencies', 'favorites'); ?></h3>
28 <div class="simple-favorites-display-settings">
29 <div class="row">
30 <div class="description">
31 <h5><?php _e('Enqueue Plugin CSS', 'favorites'); ?></h5>
32 </div>
33 <div class="field">
34 <label class="block"><input type="checkbox" name="simplefavorites_dependencies[css]" value="true" data-favorites-dependency-checkbox <?php if ( $this->settings_repo->outputDependency('css') ) echo 'checked'; ?> /><?php _e('Output Plugin CSS', 'favorites'); ?>
35 </label>
36 <div class="simplefavorites-dependency-content" data-favorites-dependency-content>
37 <p><em><?php _e('If you are compiling your own minified CSS, include the CSS below:', 'favorites'); ?></em></p>
38 <textarea><?php echo Favorites\Helpers::getFileContents('assets/css/styles-uncompressed.css'); ?></textarea>
39 </div>
40 </div>
41 </div><!-- .row -->
42 <div class="row">
43 <div class="description">
44 <h5><?php _e('Enqueue Plugin Javascript', 'favorites'); ?></h5>
45 <p><?php _e('Important: The plugin JavaScript is required for core functions. If this is disabled, the plugin JS <strong>must</strong> be included with the theme along with the global JS variables.', 'favorites'); ?></p>
46 </div>
47 <div class="field">
48 <label class="block">
49 <input type="checkbox" name="simplefavorites_dependencies[js]" value="true" data-favorites-dependency-checkbox <?php if ( $this->settings_repo->outputDependency('js') ) echo 'checked'; ?> /><?php _e('Output Plugin JavaScript', 'favorites'); ?>
50 </label>
51 <div class="simplefavorites-dependency-content" data-favorites-dependency-content>
52 <p><em><?php _e('If you are compiling your own minified Javascript, include the below (required for plugin functionality):', 'favorites'); ?></em></p>
53 <textarea><?php echo Favorites\Helpers::getFileContents('assets/js/favorites.js'); ?></textarea>
54 </div>
55 </div>
56 </div><!-- .row -->
57 </div><!-- .favorites-display-settings -->
58
59 <div class="favorites-alert">
60 <p><strong><?php _e('Favorites Version', 'favorites'); ?>:</strong> <?php echo Favorites\Helpers::version(); ?></p>
61 </div>
...\ No newline at end of file ...\ No newline at end of file
1 <?php settings_fields( 'simple-favorites-users' ); ?>
2
3 <h3><?php _e('User Settings', 'favorites'); ?></h3>
4 <div class="simple-favorites-display-settings">
5 <div class="row">
6 <div class="description">
7 <h5><?php _e('Anonymous Users', 'favorites'); ?></h5>
8 <p><?php _e('Enable favoriting functionality for unauthenticated users.', 'favorites'); ?></p>
9 </div>
10 <div class="field">
11 <label class="block"><input type="checkbox" name="simplefavorites_users[anonymous][display]" value="true" <?php if ( $this->settings_repo->anonymous('display') ) echo ' checked'; ?> data-favorites-anonymous-checkbox /><?php _e('Enable Anonymous Users', 'favorites'); ?>
12 </label>
13 <label class="block" data-favorites-anonymous-count><input type="checkbox" name="simplefavorites_users[anonymous][save]" value="true" <?php if ( $this->settings_repo->anonymous('save') ) echo ' checked'; ?> /><?php _e('Include in Post Favorite Count', 'favorites'); ?>
14 </label>
15 </div>
16 </div><!-- .row -->
17 <div class="row">
18 <div class="description">
19 <h5><?php _e('User Cookie Consent', 'favorites'); ?></h5>
20 <p><?php _e('Require user consent for saving cookies before allowing favorites to be saved.', 'favorites'); ?></p><p><strong><?php _e('Important:', 'favorites'); ?></strong> <?php _e('If using this option for GDPR compliance, please consult an attorney for appropriate legal terms to display in the modal consent.', 'favorites'); ?></p>
21 </div>
22 <div class="field">
23 <label class="block"><input type="checkbox" name="simplefavorites_users[consent][require]" value="true" <?php if ( $this->settings_repo->consent('require') ) echo ' checked'; ?> data-favorites-require-consent-checkbox /><?php _e('Require User Consent', 'favorites'); ?>
24 </label>
25 <div class="require-consent-modal-content" data-favorites-require-consent-modal-content>
26 <h3><?php _e('Content to Display in Modal Agreement', 'favorites'); ?></h3>
27 <?php
28 wp_editor($this->settings_repo->consent('modal'), 'simplefavorites_users_authentication_modal',
29 array(
30 'textarea_name' => 'simplefavorites_users[consent][modal]',
31 'tabindex' => 1,
32 'wpautop' => true
33 )
34 );
35 ?>
36 <p>
37 <label class="block"><?php _e('Consent Button Text', 'favorites'); ?></label>
38 <input type="text" name="simplefavorites_users[consent][consent_button_text]" value="<?php echo $this->settings_repo->consent('consent_button_text'); ?>" />
39 </p>
40 <p>
41 <label class="block"><?php _e('Deny Button Text', 'favorites'); ?></label>
42 <input type="text" name="simplefavorites_users[consent][deny_button_text]" value="<?php echo $this->settings_repo->consent('deny_button_text'); ?>" />
43 </p>
44 </div>
45 </div>
46 </div><!-- .row -->
47 <div class="row" data-favorites-require-login>
48 <div class="description">
49 <h5><?php _e('Anonymous Favoriting Behavior', 'favorites'); ?></h5>
50 <p><?php _e('By default, favorite buttons are hidden from unauthenticated users if anonymous users are disabled.', 'favorites'); ?></p>
51 </div>
52 <div class="field">
53 <label class="block"><input type="checkbox" name="simplefavorites_users[require_login]" value="true" <?php if ( $this->settings_repo->requireLogin() ) echo ' checked'; ?> data-favorites-require-login-checkbox data-favorites-anonymous-settings="modal" /><?php _e('Show Buttons and Display Modal for Anonymous Users', 'favorites'); ?>
54 </label>
55 <label class="block"><input type="checkbox" name="simplefavorites_users[redirect_anonymous]" value="true" <?php if ( $this->settings_repo->redirectAnonymous() ) echo ' checked'; ?> data-favorites-redirect-anonymous-checkbox data-favorites-anonymous-settings="redirect" /><?php _e('Redirect Anonymous Users to a Page', 'favorites'); ?>
56 </label>
57 <div class="authentication-modal-content" data-favorites-authentication-modal-content>
58 <h3><?php _e('Edit the Modal Content Below', 'favorites'); ?></h3>
59 <p><strong><?php _e('Important: ', 'favorites'); ?></strong> <?php _e('If plugin css or javascript has been disabled, the modal window will not display correctly.', 'favorites'); ?></p>
60 <p><?php _e('To add "close" button or link, give it a data attribute of "data-favorites-modal-close".', 'favorites'); ?></p>
61 <?php
62 wp_editor($this->settings_repo->authenticationModalContent(true), 'simplefavorites_users_authentication_modal',
63 array(
64 'textarea_name' => 'simplefavorites_users[authentication_modal]',
65 'tabindex' => 1,
66 'wpautop' => true
67 )
68 );
69 ?>
70 </div>
71 <div class="anonymous-redirect-content" data-favorites-anonymous-redirect-content>
72 <label><?php _e('Enter the Page/Post ID to redirect to (defaults to the site url)', 'sscblog'); ?></label>
73 <input type="text" name="simplefavorites_users[anonymous_redirect_id]" value="<?php echo $this->settings_repo->redirectAnonymousId(); ?>" />
74 </div>
75 </div>
76 </div><!-- .row -->
77 <div class="row">
78 <div class="description">
79 <h5><?php _e('Save Unauthenticated Favorites as', 'favorites'); ?></h5>
80 <p><?php _e('Unauthenticated users\' favorites may be saved in either cookies or session. Authenticated users\' favorites are saved as user meta.', 'favorites'); ?></p>
81 </div>
82 <div class="field">
83 <label class="block"><input type="radio" name="simplefavorites_users[anonymous][saveas]" value="cookie" <?php if ( $this->settings_repo->saveType() == 'cookie' ) echo 'checked'; ?>/><?php _e('Cookie', 'favorites'); ?>
84 </label>
85 <label>
86 <input type="radio" name="simplefavorites_users[anonymous][saveas]" value="session" <?php if ( $this->settings_repo->saveType() == 'session' ) echo 'checked'; ?>/><?php _e('Session', 'favorites'); ?>
87 </label>
88 </div>
89 </div><!-- .row -->
90 </div><!-- .favorites-display-settings -->
...\ No newline at end of file ...\ No newline at end of file
1 <div class="wrap">
2 <h1><?php echo $this->plugin_name . ' '; _e('Settings', 'favorites'); ?></h1>
3
4 <h2 class="nav-tab-wrapper">
5 <a class="nav-tab <?php if ( $tab == 'general' ) echo 'nav-tab-active'; ?>" href="options-general.php?page=simple-favorites">
6 <?php _e('General', 'favorites'); ?>
7 </a>
8 <a class="nav-tab <?php if ( $tab == 'users' ) echo 'nav-tab-active'; ?>" href="options-general.php?page=simple-favorites&tab=users">
9 <?php _e('Users', 'favorites'); ?>
10 </a>
11 <a class="nav-tab <?php if ( $tab == 'display' ) echo 'nav-tab-active'; ?>" href="options-general.php?page=simple-favorites&tab=display">
12 <?php _e('Display & Post Types', 'favorites'); ?>
13 </a>
14 </h2>
15
16 <form method="post" enctype="multipart/form-data" action="options.php">
17 <?php include(Favorites\Helpers::view('settings/settings-' . $tab)); ?>
18 <?php submit_button(); ?>
19 </form>
20 </div><!-- .wrap -->
...\ No newline at end of file ...\ No newline at end of file
1 .simplefavorite-button.active{opacity:.7}.simplefavorite-button.has-count{position:relative}.simplefavorite-button.preset{display:inline-block;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;background:transparent;background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:0px 0px 2px 0px rgba(0,0,0,0.1),1px 1px 1px 0px rgba(0,0,0,0.1);box-shadow:0px 0px 2px 0px rgba(0,0,0,0.1),1px 1px 1px 0px rgba(0,0,0,0.1);padding:.5em 1em .5em 2em;position:relative;-webkit-border-radius:2px;border-radius:2px;cursor:pointer;-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease}.simplefavorite-button.preset:active,.simplefavorite-button.preset:focus{outline:none}.simplefavorite-button.preset i{position:absolute;font-size:1.3em;left:.3em}.simplefavorite-button.preset:hover{background-color:#333;border-color:#333;color:#fff;-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease}.simplefavorite-button.preset.active{background-color:#333;color:#fff;border-color:#333;opacity:1}.simplefavorites-loading{margin-left:8px}.sf-icon-spinner-wrapper{display:inline-block;position:relative;min-width:1em;min-height:1em}.sf-icon-spinner{-webkit-animation:sf_rotate linear 2s infinite;animation:sf_rotate linear 2s infinite;position:absolute;top:.15em;left:0}@-webkit-keyframes sf_rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);-webkit-transform-origin:center center;transform-origin:center center}50%{-webkit-transform:rotate(180deg);transform:rotate(180deg);-webkit-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg);-webkit-transform-origin:center center;transform-origin:center center}}@keyframes sf_rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);-webkit-transform-origin:center center;transform-origin:center center}50%{-webkit-transform:rotate(180deg);transform:rotate(180deg);-webkit-transform-origin:center center;transform-origin:center center}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg);-webkit-transform-origin:center center;transform-origin:center center}}.favorites-list{list-style:none}.favorites-list li{zoom:1;border-top:1px solid rgba(0,0,0,0.2);padding:.75em 0;margin:0}.favorites-list li:before,.favorites-list li:after{content:" ";display:table}.favorites-list li:after{clear:both}.favorites-list li img{float:left;margin-right:1em}.simplefavorites-modal-backdrop{position:fixed;width:0;height:0;background-color:rgba(0,0,0,0.85);top:0;left:50%;z-index:998;opacity:0;-webkit-transition:opacity 200ms ease;-o-transition:opacity 200ms ease;transition:opacity 200ms ease}.simplefavorites-modal-backdrop.active{width:100%;height:100%;left:0;opacity:1;-webkit-transition:opacity 200ms ease;-o-transition:opacity 200ms ease;transition:opacity 200ms ease}.simplefavorites-modal-content{z-index:999;position:fixed;top:-200%;left:50%;width:50%;background-color:#fff;-webkit-border-radius:2px;border-radius:2px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease;-webkit-box-shadow:2px 2px 20px 0px rgba(51,51,51,0.5);box-shadow:2px 2px 20px 0px rgba(51,51,51,0.5)}.simplefavorites-modal-content.small{width:400px}.simplefavorites-modal-content.active{top:50px;-webkit-transition:all 200ms ease;-o-transition:all 200ms ease;transition:all 200ms ease}.simplefavorites-modal-content.loading .modal-content-body{display:none}.simplefavorites-modal-content.loading .modal-content-loading{display:block}.simplefavorites-modal-content-body{padding:1em;max-height:300px;overflow:auto;zoom:1}.simplefavorites-modal-content-body:before,.simplefavorites-modal-content-body:after{content:" ";display:table}.simplefavorites-modal-content-body:after{clear:both}.simplefavorites-modal-content-body.no-padding{padding:0}.simplefavorites-modal-content-body.has-footer{padding-bottom:0}.simplefavorites-modal-content-interior{padding:1em;padding-bottom:0}.simplefavorites-modal-content-footer{zoom:1;padding:.7em;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background-color:rgba(51,51,51,0.1)}.simplefavorites-modal-content-footer:before,.simplefavorites-modal-content-footer:after{content:" ";display:table}.simplefavorites-modal-content-footer:after{clear:both}.simplefavorites-button-consent-deny{float:left;opacity:.7}.simplefavorites-button-consent-accept{float:right}@media (max-width: 767px){.simplefavorites-modal-content{width:90%}.simplefavorites-modal-content.active{top:20px}.simplefavorites-modal-content-body{height:300px;overflow-y:scroll;-webkit-overflow-scrolling:touch;overflow-x:hidden}}@media print{.simplefavorites-modal-backdrop,.simplefavorites-modal-content{display:none}}@font-face{font-family:'favorites';src:url("fonts/favorites.eot")}@font-face{font-family:'favorites';src:url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBwcAAAC8AAAAYGNtYXClTaJoAAABHAAAAIxnYXNwAAAAEAAAAagAAAAIZ2x5Ztq6v+MAAAGwAAAEVGhlYWQN7PEkAAAGBAAAADZoaGVhB8IDzgAABjwAAAAkaG10eCoAAgwAAAZgAAAANGxvY2EE9AZcAAAGlAAAABxtYXhwABEAdQAABrAAAAAgbmFtZWwpt2EAAAbQAAABnnBvc3QAAwAAAAAIcAAAACAAAwPNAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADqEAPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAcAAAABgAEAADAAgAAQAg5gHofeia6Nzo5ul76dnqEP/9//8AAAAAACDmAOh96Jro3Ojm6Xvp2eoQ//3//wAB/+MaBBeJF20XLBcjFo8WMhX8AAMAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAIAIP/2A+ADigARABsAAAEfATMPAR8BLwEPAT8BLwEzNxMDIQUDJQUDLQECADMN1oknDTOJJyaKNw0nidYQQHP+kwEmcAEqASZwASr+kwK9oy1jGi2jYxoaY6MtHWYtAWr+o9r+o9fXAV3XAwAAAAABACD/9gPgA4oACQAAAQ0BEyUFEyUhEwJzAW3+1nD+2v7WcP7aAW1zAi0D1/6j19MBXNcBXQAAAAEAVgAdA6oDKwAbAAAlJy4DNTQ+AjMyFhc+ATMyHgIVFA4CBwIAPlKHXzQkP1UyN2YjImY4MVY/JDRfhlMdOEt/dHE9MVY/JDIoKDIkP1YxPXF2f0sAAAADAFYAAQOqA1UAFQAhADsAAAE+ATU0JiMiBg8BJy4BIyIGFRQWHwEBMjY1NCYjIgYVFBYFHgEVFAYHAQ4BIyImJwEuATURNDYzITIWFwLgDxE+LBYnDyAeDyYXKz8PD7b+wBslJRsbJSUCwwwMDAz+1AweEhIeDP6ADAwxIwEsEh4MAR8PJhcrPw8PICAPDz8rFyYPtgIYJRsbJSUbGyXEDB4SEh4M/tQMDAwMAYAMHhIBLCIyDAwAAgAqACsD1gOBABwAIAAAAQczFRQGBwMOASMhIiY1ETQ2NwEXHgEdAQchMhYBETMRA9YCAgMDggkqG/6AIjQODAEYLgkJKgEOIjT8VKwCAQRSCRAH/tQXHTMjAaoSHgwBGi4JFg0OxDL+CAIA/gAAAAEA1gArAyoDKwAKAAABMhYVESUFETQ2MwLWIjL+1v7WMSMDKzQi/VaAgAKqIjQAAAIAIP/wBAADsAA6AHIAAAEuAScuAScuAScuAQcOAQcOAQcOAQcOARceARceARceARceATc+ATc+ATc+ATc+ATc6ATMyNjU8ATUxBw4BBw4BBw4BJy4BJy4BJy4BJy4BNz4BNz4BNz4BNz4BFx4BFx4BFx4BFx4BBzEcARUUFhcOAQcEAAEVFRQ5JCNULi1hMTFfLC1PISE0ERIQAQEUExM2ISJOKytaLi5ZKSlLHh8xEAkOAwECARslZhEzHx9JKChVKipTJyZFHR0sDw8OAQESEBEuHR5DJSVPJydNJCNAGhspDg0NASEYBQ8LAcAyYy0uUiIjNRISEQEBFRMUNyMiUS0sXi8vXCsrTSAgMhAREAEBFBISNCEgTCkZNBslGwEDAaooRx4eLhAPDwEBEhERMR4eRyYnUSkpUCUlQhwbKw4PDQEBERAQLRwcQSQjSyYBAwEZJAMaMxgAAAEAAP/ZBAADpwAKAAABJQsBDQEDJQUDJQQA/p6env6eAQA8ATwBPDwBAAIzMwFB/r8z+v6gpqYBYPoAAAEAAAAgBAADQAAFAAAJAScHCQEDYP4g4KABgAKAA0D+IOCg/oACgAABAAAAAQAAvj/AY18PPPUACwQAAAAAANVm1k8AAAAA1WbWTwAA/9kEAAOwAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAANBAAAAAAAAAAAAAAAAgAAAAQAACAEAAAgBAAAVgQAAFYEAAAqBAAA1gQAACAEAAAABAAAAAAAAAAACgAUAB4AVgByAJ4A+gEyAUoB+AIWAioAAQAAAA0AcwADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAkAAAABAAAAAAACAAcAcgABAAAAAAADAAkAPAABAAAAAAAEAAkAhwABAAAAAAAFAAsAGwABAAAAAAAGAAkAVwABAAAAAAAKABoAogADAAEECQABABIACQADAAEECQACAA4AeQADAAEECQADABIARQADAAEECQAEABIAkAADAAEECQAFABYAJgADAAEECQAGABIAYAADAAEECQAKADQAvGZhdm9yaXRlcwBmAGEAdgBvAHIAaQB0AGUAc1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZhdm9yaXRlcwBmAGEAdgBvAHIAaQB0AGUAc2Zhdm9yaXRlcwBmAGEAdgBvAHIAaQB0AGUAc1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZhdm9yaXRlcwBmAGEAdgBvAHIAaQB0AGUAc0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format("truetype");font-weight:normal;font-style:normal}[class^="sf-icon-"],[class*=" sf-icon-"]{font-family:'favorites' !important;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sf-icon-spinner:before{content:"\e97b"}.sf-icon-favorite:before{content:"\e9d9"}.sf-icon-checkmark:before{content:"\ea10"}.sf-icon-bookmark:before{content:"\e8e6"}.sf-icon-love:before{content:"\e87d"}.sf-icon-wishlist:before{content:"\e89a"}.sf-icon-like:before{content:"\e8dc"}.sf-icon-star-empty:before{content:"\e600"}.sf-icon-star-full:before{content:"\e601"}
1 <?xml version="1.0" standalone="no"?>
2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3 <svg xmlns="http://www.w3.org/2000/svg">
4 <metadata>Generated by IcoMoon</metadata>
5 <defs>
6 <font id="favorites" horiz-adv-x="1024">
7 <font-face units-per-em="1024" ascent="960" descent="-64" />
8 <missing-glyph horiz-adv-x="1024" />
9 <glyph unicode="&#x20;" horiz-adv-x="512" d="" />
10 <glyph unicode="&#xe600;" glyph-name="star-empty" d="M512 700.8l51.2-163.2 12.8-44.8h214.4l-137.6-99.2-38.4-25.6 12.8-44.8 51.2-163.2-137.6 99.2-38.4 25.6-38.4-25.6-137.6-99.2 54.4 163.2 12.8 44.8-38.4 28.8-137.6 102.4h214.4l16 44.8 64 156.8zM512 905.6l-115.2-348.8h-364.8l294.4-217.6-112-348.8 297.6 214.4 294.4-214.4-112 348.8 297.6 214.4-364.8 3.2-115.2 348.8z" />
11 <glyph unicode="&#xe601;" glyph-name="star-full" d="M627.2 556.8l364.8-3.2-297.6-214.4 112-348.8-294.4 214.4-297.6-211.2 112 348.8-294.4 214.4h364.8l115.2 348.8z" />
12 <glyph unicode="&#xe87d;" glyph-name="love" d="M512 28.667l-62 56c-220 200-364 330-364 492 0 132 102 234 234 234 74 0 146-36 192-90 46 54 118 90 192 90 132 0 234-102 234-234 0-162-144-294-364-494z" />
13 <glyph unicode="&#xe89a;" glyph-name="wishlist" d="M736 286.667c20 20 32 46 32 76 0 58-48 106-106 106-30 0-56-10-76-30l-32-32-30 32c-20 20-46 30-76 30-58 0-106-48-106-106 0-30 10-56 30-76l182-182zM234 640.667c36 0 64 28 64 64s-28 64-64 64-64-28-64-64 28-64 64-64zM914 444.667c16-16 24-36 24-60s-8-44-24-60l-300-300c-16-16-36-24-60-24s-44 8-60 24l-384 384c-16 16-24 36-24 60v300c0 46 38 84 84 84h300c24 0 44-8 60-24z" />
14 <glyph unicode="&#xe8dc;" glyph-name="like" d="M982 512.667l-2-4h2v-82c0-12-2-22-6-32l-130-300c-12-30-42-52-78-52h-384c-46 0-86 40-86 86v426c0 24 10 44 26 60l280 282 46-46c12-12 18-26 18-44v-14l-42-196h270c46 0 86-38 86-84zM42 42.667v512h172v-512h-172z" />
15 <glyph unicode="&#xe8e6;" glyph-name="bookmark" d="M726 810.667c46 0 84-40 84-86v-682l-298 128-298-128v682c0 46 38 86 84 86h428z" />
16 <glyph unicode="&#xe97b;" glyph-name="spinner" d="M1024 448c-1.278 66.862-15.784 133.516-42.576 194.462-26.704 61-65.462 116.258-113.042 161.92-47.552 45.696-103.944 81.82-164.984 105.652-61.004 23.924-126.596 35.352-191.398 33.966-64.81-1.282-129.332-15.374-188.334-41.356-59.048-25.896-112.542-63.47-156.734-109.576-44.224-46.082-79.16-100.708-102.186-159.798-23.114-59.062-34.128-122.52-32.746-185.27 1.286-62.76 14.964-125.148 40.134-182.206 25.088-57.1 61.476-108.828 106.11-151.548 44.61-42.754 97.472-76.504 154.614-98.72 57.118-22.304 118.446-32.902 179.142-31.526 60.708 1.29 120.962 14.554 176.076 38.914 55.15 24.282 105.116 59.48 146.366 102.644 41.282 43.14 73.844 94.236 95.254 149.43 13.034 33.458 21.88 68.4 26.542 103.798 1.246-0.072 2.498-0.12 3.762-0.12 35.346 0 64 28.652 64 64 0 1.796-0.094 3.572-0.238 5.332h0.238zM922.306 278.052c-23.472-53.202-57.484-101.4-99.178-141.18-41.67-39.81-91-71.186-144.244-91.79-53.228-20.678-110.29-30.452-166.884-29.082-56.604 1.298-112.596 13.736-163.82 36.474-51.25 22.666-97.684 55.49-135.994 95.712-38.338 40.198-68.528 87.764-88.322 139.058-19.87 51.284-29.228 106.214-27.864 160.756 1.302 54.552 13.328 108.412 35.254 157.69 21.858 49.3 53.498 93.97 92.246 130.81 38.73 36.868 84.53 65.87 133.874 84.856 49.338 19.060 102.136 28.006 154.626 26.644 52.5-1.306 104.228-12.918 151.562-34.034 47.352-21.050 90.256-51.502 125.624-88.782 35.396-37.258 63.21-81.294 81.39-128.688 18.248-47.392 26.782-98.058 25.424-148.496h0.238c-0.144-1.76-0.238-3.536-0.238-5.332 0-33.012 24.992-60.174 57.086-63.624-6.224-34.822-16.53-68.818-30.78-100.992z" />
17 <glyph unicode="&#xe9d9;" glyph-name="favorite" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538z" />
18 <glyph unicode="&#xea10;" glyph-name="checkmark" d="M864 832l-480-480-224 224-160-160 384-384 640 640z" />
19 </font></defs></svg>
...\ No newline at end of file ...\ No newline at end of file
1 .simplefavorite-button.active {
2 opacity: .7;
3 }
4
5 .simplefavorite-button.has-count {
6 position: relative;
7 }
8
9 .simplefavorite-button.preset {
10 display: inline-block;
11 -webkit-appearance: none;
12 -moz-appearance: none;
13 appearance: none;
14 border: 0;
15 background: transparent;
16 background-color: #ffffff;
17 border: 1px solid #cccccc;
18 -webkit-box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.1), 1px 1px 1px 0px rgba(0, 0, 0, 0.1);
19 box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.1), 1px 1px 1px 0px rgba(0, 0, 0, 0.1);
20 padding: .5em 1em .5em 2em;
21 position: relative;
22 -webkit-border-radius: 2px;
23 border-radius: 2px;
24 cursor: pointer;
25 -webkit-transition: all 200ms ease;
26 -o-transition: all 200ms ease;
27 transition: all 200ms ease;
28 }
29
30 .simplefavorite-button.preset:active, .simplefavorite-button.preset:focus {
31 outline: none;
32 }
33
34 .simplefavorite-button.preset i {
35 position: absolute;
36 font-size: 1.3em;
37 left: .3em;
38 }
39
40 .simplefavorite-button.preset:hover {
41 background-color: #333;
42 border-color: #333;
43 color: #ffffff;
44 -webkit-transition: all 200ms ease;
45 -o-transition: all 200ms ease;
46 transition: all 200ms ease;
47 }
48
49 .simplefavorite-button.preset.active {
50 background-color: #333;
51 color: #ffffff;
52 border-color: #333;
53 opacity: 1;
54 }
55
56 .simplefavorites-loading {
57 margin-left: 8px;
58 }
59
60 .sf-icon-spinner-wrapper {
61 display: inline-block;
62 position: relative;
63 min-width: 1em;
64 min-height: 1em;
65 }
66
67 .sf-icon-spinner {
68 -webkit-animation: sf_rotate linear 2s infinite;
69 animation: sf_rotate linear 2s infinite;
70 position: absolute;
71 top: .15em;
72 left: 0;
73 }
74
75 @-webkit-keyframes sf_rotate {
76 0% {
77 -webkit-transform: rotate(0deg);
78 transform: rotate(0deg);
79 -webkit-transform-origin: center center;
80 transform-origin: center center;
81 }
82 50% {
83 -webkit-transform: rotate(180deg);
84 transform: rotate(180deg);
85 -webkit-transform-origin: center center;
86 transform-origin: center center;
87 }
88 100% {
89 -webkit-transform: rotate(360deg);
90 transform: rotate(360deg);
91 -webkit-transform-origin: center center;
92 transform-origin: center center;
93 }
94 }
95
96 @keyframes sf_rotate {
97 0% {
98 -webkit-transform: rotate(0deg);
99 transform: rotate(0deg);
100 -webkit-transform-origin: center center;
101 transform-origin: center center;
102 }
103 50% {
104 -webkit-transform: rotate(180deg);
105 transform: rotate(180deg);
106 -webkit-transform-origin: center center;
107 transform-origin: center center;
108 }
109 100% {
110 -webkit-transform: rotate(360deg);
111 transform: rotate(360deg);
112 -webkit-transform-origin: center center;
113 transform-origin: center center;
114 }
115 }
116
117 .favorites-list {
118 list-style: none;
119 }
120
121 .favorites-list li {
122 zoom: 1;
123 border-top: 1px solid rgba(0, 0, 0, 0.2);
124 padding: .75em 0;
125 margin: 0;
126 }
127
128 .favorites-list li:before, .favorites-list li:after {
129 content: " ";
130 /* 1 */
131 display: table;
132 /* 2 */
133 }
134
135 .favorites-list li:after {
136 clear: both;
137 }
138
139 .favorites-list li img {
140 float: left;
141 margin-right: 1em;
142 }
143
144 .simplefavorites-modal-backdrop {
145 position: fixed;
146 width: 0;
147 height: 0;
148 background-color: rgba(0, 0, 0, 0.85);
149 top: 0;
150 left: 50%;
151 z-index: 998;
152 opacity: 0;
153 -webkit-transition: opacity 200ms ease;
154 -o-transition: opacity 200ms ease;
155 transition: opacity 200ms ease;
156 }
157
158 .simplefavorites-modal-backdrop.active {
159 width: 100%;
160 height: 100%;
161 left: 0;
162 opacity: 1;
163 -webkit-transition: opacity 200ms ease;
164 -o-transition: opacity 200ms ease;
165 transition: opacity 200ms ease;
166 }
167
168 .simplefavorites-modal-content {
169 z-index: 999;
170 position: fixed;
171 top: -200%;
172 left: 50%;
173 width: 50%;
174 background-color: #ffffff;
175 -webkit-border-radius: 2px;
176 border-radius: 2px;
177 -webkit-transform: translateX(-50%);
178 -ms-transform: translateX(-50%);
179 transform: translateX(-50%);
180 -webkit-transition: all 200ms ease;
181 -o-transition: all 200ms ease;
182 transition: all 200ms ease;
183 -webkit-box-shadow: 2px 2px 20px 0px rgba(51, 51, 51, 0.5);
184 box-shadow: 2px 2px 20px 0px rgba(51, 51, 51, 0.5);
185 }
186
187 .simplefavorites-modal-content.small {
188 width: 400px;
189 }
190
191 .simplefavorites-modal-content.active {
192 top: 50px;
193 -webkit-transition: all 200ms ease;
194 -o-transition: all 200ms ease;
195 transition: all 200ms ease;
196 }
197
198 .simplefavorites-modal-content.loading .modal-content-body {
199 display: none;
200 }
201
202 .simplefavorites-modal-content.loading .modal-content-loading {
203 display: block;
204 }
205
206 .simplefavorites-modal-content-body {
207 padding: 1em;
208 max-height: 300px;
209 overflow: auto;
210 zoom: 1;
211 }
212
213 .simplefavorites-modal-content-body:before, .simplefavorites-modal-content-body:after {
214 content: " ";
215 /* 1 */
216 display: table;
217 /* 2 */
218 }
219
220 .simplefavorites-modal-content-body:after {
221 clear: both;
222 }
223
224 .simplefavorites-modal-content-body.no-padding {
225 padding: 0;
226 }
227
228 .simplefavorites-modal-content-body.has-footer {
229 padding-bottom: 0;
230 }
231
232 .simplefavorites-modal-content-interior {
233 padding: 1em;
234 padding-bottom: 0;
235 }
236
237 .simplefavorites-modal-content-footer {
238 zoom: 1;
239 padding: .7em;
240 -webkit-border-radius: 0 0 2px 2px;
241 border-radius: 0 0 2px 2px;
242 background-color: rgba(51, 51, 51, 0.1);
243 }
244
245 .simplefavorites-modal-content-footer:before, .simplefavorites-modal-content-footer:after {
246 content: " ";
247 /* 1 */
248 display: table;
249 /* 2 */
250 }
251
252 .simplefavorites-modal-content-footer:after {
253 clear: both;
254 }
255
256 .simplefavorites-button-consent-deny {
257 float: left;
258 opacity: .7;
259 }
260
261 .simplefavorites-button-consent-accept {
262 float: right;
263 }
264
265 @media (max-width: 767px) {
266 .simplefavorites-modal-content {
267 width: 90%;
268 }
269 .simplefavorites-modal-content.active {
270 top: 20px;
271 }
272 .simplefavorites-modal-content-body {
273 height: 300px;
274 overflow-y: scroll;
275 -webkit-overflow-scrolling: touch;
276 overflow-x: hidden;
277 }
278 }
279
280 @media print {
281 .simplefavorites-modal-backdrop,
282 .simplefavorites-modal-content {
283 display: none;
284 }
285 }
286
287 @font-face {
288 font-family: 'favorites';
289 src: url("fonts/favorites.eot");
290 }
291
292 @font-face {
293 font-family: 'favorites';
294 src: url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBwcAAAC8AAAAYGNtYXClTaJoAAABHAAAAIxnYXNwAAAAEAAAAagAAAAIZ2x5Ztq6v+MAAAGwAAAEVGhlYWQN7PEkAAAGBAAAADZoaGVhB8IDzgAABjwAAAAkaG10eCoAAgwAAAZgAAAANGxvY2EE9AZcAAAGlAAAABxtYXhwABEAdQAABrAAAAAgbmFtZWwpt2EAAAbQAAABnnBvc3QAAwAAAAAIcAAAACAAAwPNAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADqEAPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAcAAAABgAEAADAAgAAQAg5gHofeia6Nzo5ul76dnqEP/9//8AAAAAACDmAOh96Jro3Ojm6Xvp2eoQ//3//wAB/+MaBBeJF20XLBcjFo8WMhX8AAMAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAIAIP/2A+ADigARABsAAAEfATMPAR8BLwEPAT8BLwEzNxMDIQUDJQUDLQECADMN1oknDTOJJyaKNw0nidYQQHP+kwEmcAEqASZwASr+kwK9oy1jGi2jYxoaY6MtHWYtAWr+o9r+o9fXAV3XAwAAAAABACD/9gPgA4oACQAAAQ0BEyUFEyUhEwJzAW3+1nD+2v7WcP7aAW1zAi0D1/6j19MBXNcBXQAAAAEAVgAdA6oDKwAbAAAlJy4DNTQ+AjMyFhc+ATMyHgIVFA4CBwIAPlKHXzQkP1UyN2YjImY4MVY/JDRfhlMdOEt/dHE9MVY/JDIoKDIkP1YxPXF2f0sAAAADAFYAAQOqA1UAFQAhADsAAAE+ATU0JiMiBg8BJy4BIyIGFRQWHwEBMjY1NCYjIgYVFBYFHgEVFAYHAQ4BIyImJwEuATURNDYzITIWFwLgDxE+LBYnDyAeDyYXKz8PD7b+wBslJRsbJSUCwwwMDAz+1AweEhIeDP6ADAwxIwEsEh4MAR8PJhcrPw8PICAPDz8rFyYPtgIYJRsbJSUbGyXEDB4SEh4M/tQMDAwMAYAMHhIBLCIyDAwAAgAqACsD1gOBABwAIAAAAQczFRQGBwMOASMhIiY1ETQ2NwEXHgEdAQchMhYBETMRA9YCAgMDggkqG/6AIjQODAEYLgkJKgEOIjT8VKwCAQRSCRAH/tQXHTMjAaoSHgwBGi4JFg0OxDL+CAIA/gAAAAEA1gArAyoDKwAKAAABMhYVESUFETQ2MwLWIjL+1v7WMSMDKzQi/VaAgAKqIjQAAAIAIP/wBAADsAA6AHIAAAEuAScuAScuAScuAQcOAQcOAQcOAQcOARceARceARceARceATc+ATc+ATc+ATc+ATc6ATMyNjU8ATUxBw4BBw4BBw4BJy4BJy4BJy4BJy4BNz4BNz4BNz4BNz4BFx4BFx4BFx4BFx4BBzEcARUUFhcOAQcEAAEVFRQ5JCNULi1hMTFfLC1PISE0ERIQAQEUExM2ISJOKytaLi5ZKSlLHh8xEAkOAwECARslZhEzHx9JKChVKipTJyZFHR0sDw8OAQESEBEuHR5DJSVPJydNJCNAGhspDg0NASEYBQ8LAcAyYy0uUiIjNRISEQEBFRMUNyMiUS0sXi8vXCsrTSAgMhAREAEBFBISNCEgTCkZNBslGwEDAaooRx4eLhAPDwEBEhERMR4eRyYnUSkpUCUlQhwbKw4PDQEBERAQLRwcQSQjSyYBAwEZJAMaMxgAAAEAAP/ZBAADpwAKAAABJQsBDQEDJQUDJQQA/p6env6eAQA8ATwBPDwBAAIzMwFB/r8z+v6gpqYBYPoAAAEAAAAgBAADQAAFAAAJAScHCQEDYP4g4KABgAKAA0D+IOCg/oACgAABAAAAAQAAvj/AY18PPPUACwQAAAAAANVm1k8AAAAA1WbWTwAA/9kEAAOwAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAANBAAAAAAAAAAAAAAAAgAAAAQAACAEAAAgBAAAVgQAAFYEAAAqBAAA1gQAACAEAAAABAAAAAAAAAAACgAUAB4AVgByAJ4A+gEyAUoB+AIWAioAAQAAAA0AcwADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAkAAAABAAAAAAACAAcAcgABAAAAAAADAAkAPAABAAAAAAAEAAkAhwABAAAAAAAFAAsAGwABAAAAAAAGAAkAVwABAAAAAAAKABoAogADAAEECQABABIACQADAAEECQACAA4AeQADAAEECQADABIARQADAAEECQAEABIAkAADAAEECQAFABYAJgADAAEECQAGABIAYAADAAEECQAKADQAvGZhdm9yaXRlcwBmAGEAdgBvAHIAaQB0AGUAc1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZhdm9yaXRlcwBmAGEAdgBvAHIAaQB0AGUAc2Zhdm9yaXRlcwBmAGEAdgBvAHIAaQB0AGUAc1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZhdm9yaXRlcwBmAGEAdgBvAHIAaQB0AGUAc0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format("truetype");
295 font-weight: normal;
296 font-style: normal;
297 }
298
299 [class^="sf-icon-"], [class*=" sf-icon-"] {
300 /* use !important to prevent issues with browser extensions that change fonts */
301 font-family: 'favorites' !important;
302 speak: none;
303 font-style: normal;
304 font-weight: normal;
305 font-variant: normal;
306 text-transform: none;
307 line-height: 1;
308 /* Better Font Rendering =========== */
309 -webkit-font-smoothing: antialiased;
310 -moz-osx-font-smoothing: grayscale;
311 }
312
313 .sf-icon-spinner:before {
314 content: "\e97b";
315 }
316
317 .sf-icon-favorite:before {
318 content: "\e9d9";
319 }
320
321 .sf-icon-checkmark:before {
322 content: "\ea10";
323 }
324
325 .sf-icon-bookmark:before {
326 content: "\e8e6";
327 }
328
329 .sf-icon-love:before {
330 content: "\e87d";
331 }
332
333 .sf-icon-wishlist:before {
334 content: "\e89a";
335 }
336
337 .sf-icon-like:before {
338 content: "\e8dc";
339 }
340
341 .sf-icon-star-empty:before {
342 content: "\e600";
343 }
344
345 .sf-icon-star-full:before {
346 content: "\e601";
347 }
1 {
2 "name": "kylephillips/favorites",
3 "description": "Favorites for WordPress",
4 "keywords": ["wordpress", "plugin", "favorite", "bookmark"],
5 "homepage": "https://favoriteposts.com",
6 "license": "GPL",
7 "authors": [
8 {
9 "name": "Kyle Phillips",
10 "email": "kylephillipsdesign@gmail.com",
11 "homepage": "https://github.com/kylephillips"
12 }
13 ],
14 "type": "wordpress-plugin",
15 "require": {
16 "php": ">=5.3.2",
17 "composer/installers": "v1.0.6"
18 },
19 "autoload": {
20 "psr-4" : {
21 "Favorites\\" : "app/"
22 }
23 }
24 }
1 <?php
2 /*
3 Plugin Name: Favorites
4 Plugin URI: http://favoriteposts.com
5 Description: Simple and flexible favorite buttons for any post type.
6 Version: 2.3.2
7 Author: Kyle Phillips
8 Author URI: https://github.com/kylephillips
9 Text Domain: favorites
10 Domain Path: /languages/
11 License: GPLv2 or later.
12 Copyright: Kyle Phillips
13 */
14
15 /* Copyright 2019 Kyle Phillips
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License, version 2, as
19 published by the Free Software Foundation.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31 /**
32 * Check Wordpress and PHP versions before instantiating plugin
33 */
34 register_activation_hook( __FILE__, 'favorites_check_versions' );
35
36 define( 'FAVORITES_PLUGIN_FILE', __FILE__ );
37
38 function favorites_check_versions( $wp = '3.9', $php = '5.3.2' ) {
39 global $wp_version;
40 if ( version_compare( PHP_VERSION, $php, '<' ) ) $flag = 'PHP';
41 elseif ( version_compare( $wp_version, $wp, '<' ) ) $flag = 'WordPress';
42 else return;
43 $version = 'PHP' == $flag ? $php : $wp;
44
45 if (function_exists('deactivate_plugins')){
46 deactivate_plugins( basename( __FILE__ ) );
47 }
48
49 wp_die('<p>The <strong>Favorites</strong> plugin requires'.$flag.' version '.$version.' or greater.</p>','Plugin Activation Error', array( 'response'=>200, 'back_link'=>TRUE ) );
50 }
51
52 if( !class_exists('Bootstrap') ) :
53 favorites_check_versions();
54 require_once(__DIR__ . '/vendor/autoload.php');
55 require_once(__DIR__ . '/app/Favorites.php');
56 require_once(__DIR__ . '/app/API/functions.php');
57 Favorites::init();
58 endif;
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 //Nothing to see here
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 // autoload.php @generated by Composer
4
5 require_once __DIR__ . '/composer' . '/autoload_real.php';
6
7 return ComposerAutoloaderInit1fc0bf97587a64ee48e6c213b25ab21b::getLoader();
1 <?php
2
3 // autoload_classmap.php @generated by Composer
4
5 $vendorDir = dirname(dirname(__FILE__));
6 $baseDir = dirname($vendorDir);
7
8 return array(
9 );
1 <?php
2
3 // autoload_namespaces.php @generated by Composer
4
5 $vendorDir = dirname(dirname(__FILE__));
6 $baseDir = dirname($vendorDir);
7
8 return array(
9 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src'),
10 );
1 <?php
2
3 // autoload_psr4.php @generated by Composer
4
5 $vendorDir = dirname(dirname(__FILE__));
6 $baseDir = dirname($vendorDir);
7
8 return array(
9 'Favorites\\' => array($baseDir . '/app'),
10 );
1 <?php
2
3 // autoload_real.php @generated by Composer
4
5 class ComposerAutoloaderInit1fc0bf97587a64ee48e6c213b25ab21b
6 {
7 private static $loader;
8
9 public static function loadClassLoader($class)
10 {
11 if ('Composer\Autoload\ClassLoader' === $class) {
12 require __DIR__ . '/ClassLoader.php';
13 }
14 }
15
16 public static function getLoader()
17 {
18 if (null !== self::$loader) {
19 return self::$loader;
20 }
21
22 spl_autoload_register(array('ComposerAutoloaderInit1fc0bf97587a64ee48e6c213b25ab21b', 'loadClassLoader'), true, true);
23 self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24 spl_autoload_unregister(array('ComposerAutoloaderInit1fc0bf97587a64ee48e6c213b25ab21b', 'loadClassLoader'));
25
26 $map = require __DIR__ . '/autoload_namespaces.php';
27 foreach ($map as $namespace => $path) {
28 $loader->set($namespace, $path);
29 }
30
31 $map = require __DIR__ . '/autoload_psr4.php';
32 foreach ($map as $namespace => $path) {
33 $loader->setPsr4($namespace, $path);
34 }
35
36 $classMap = require __DIR__ . '/autoload_classmap.php';
37 if ($classMap) {
38 $loader->addClassMap($classMap);
39 }
40
41 $loader->register(true);
42
43 return $loader;
44 }
45 }
46
47 function composerRequire1fc0bf97587a64ee48e6c213b25ab21b($file)
48 {
49 require $file;
50 }
1 [
2 {
3 "name": "composer/installers",
4 "version": "v1.0.6",
5 "version_normalized": "1.0.6.0",
6 "source": {
7 "type": "git",
8 "url": "https://github.com/composer/installers.git",
9 "reference": "b3bd071ea114a57212c75aa6a2eef5cfe0cc798f"
10 },
11 "dist": {
12 "type": "zip",
13 "url": "https://api.github.com/repos/composer/installers/zipball/b3bd071ea114a57212c75aa6a2eef5cfe0cc798f",
14 "reference": "b3bd071ea114a57212c75aa6a2eef5cfe0cc798f",
15 "shasum": ""
16 },
17 "replace": {
18 "shama/baton": "*"
19 },
20 "require-dev": {
21 "composer/composer": "1.0.*@dev",
22 "phpunit/phpunit": "3.7.*"
23 },
24 "time": "2013-08-20 04:37:09",
25 "type": "composer-installer",
26 "extra": {
27 "class": "Composer\\Installers\\Installer",
28 "branch-alias": {
29 "dev-master": "1.0-dev"
30 }
31 },
32 "installation-source": "dist",
33 "autoload": {
34 "psr-0": {
35 "Composer\\Installers\\": "src/"
36 }
37 },
38 "notification-url": "https://packagist.org/downloads/",
39 "license": [
40 "MIT"
41 ],
42 "authors": [
43 {
44 "name": "Kyle Robinson Young",
45 "email": "kyle@dontkry.com",
46 "homepage": "https://github.com/shama",
47 "role": "Developer"
48 }
49 ],
50 "description": "A multi-framework Composer library installer",
51 "homepage": "http://composer.github.com/installers/",
52 "keywords": [
53 "TYPO3 CMS",
54 "TYPO3 Flow",
55 "TYPO3 Neos",
56 "agl",
57 "cakephp",
58 "codeigniter",
59 "drupal",
60 "fuelphp",
61 "installer",
62 "joomla",
63 "kohana",
64 "laravel",
65 "li3",
66 "lithium",
67 "mako",
68 "modulework",
69 "phpbb",
70 "ppi",
71 "silverstripe",
72 "symfony",
73 "wordpress",
74 "zend"
75 ]
76 }
77 ]
1 ; top-most EditorConfig file
2 root = true
3
4 ; Unix-style newlines
5 [*]
6 end_of_line = LF
7
8 [*.php]
9 indent_style = space
10 indent_size = 4
1 language: php
2
3 php:
4 - 5.3
5 - 5.4
6
7 before_script:
8 - curl -s http://getcomposer.org/installer | php -- --quiet
9 - php composer.phar install --dev
10
11 script: phpunit
1 Copyright (c) 2012 Kyle Robinson Young
2
3 Permission is hereby granted, free of charge, to any person obtaining a copy
4 of this software and associated documentation files (the "Software"), to deal
5 in the Software without restriction, including without limitation the rights
6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 copies of the Software, and to permit persons to whom the Software is furnished
8 to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in all
11 copies or substantial portions of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 THE SOFTWARE.
...\ No newline at end of file ...\ No newline at end of file
1 # A Multi-Framework [Composer](http://getcomposer.org) Library Installer
2
3 [![Build Status](https://secure.travis-ci.org/composer/installers.png)](http://travis-ci.org/composer/installers)
4
5 This is for PHP package authors to require in their `composer.json`. It will
6 install their package to the correct location based on the specified package
7 type.
8
9 The goal of `installers` is to be a simple package type to install path map.
10 Users can also customize the install path per package and package authors can
11 modify the package name upon installing.
12
13 `installers` isn't intended on replacing all custom installers. If your
14 package requires special installation handling then by all means, create a
15 custom installer to handle it.
16
17 **Natively Supported Frameworks**:
18
19 The following frameworks natively work with Composer and will be
20 installed to the default `vendor` directory. `composer/installers`
21 is not needed to install packages with these frameworks:
22
23 * Aura
24 * Symfony2
25 * Yii
26
27 **Current Supported Package Types**:
28
29 > Stable types are marked as **bold**, this means that installation paths
30 > for those type will not be change. Any adjustment for those types would
31 > require creation of brand new type that will cover required changes.
32
33 | Framework | Types
34 | --------- | -----
35 | AGL | `agl-module`
36 | AnnotateCms | `annotatecms-module`<br>`annotatecms-component`<br>`annotatecms-service`
37 | CakePHP 2+ | **`cakephp-plugin`**
38 | CodeIgniter | `codeigniter-library`<br>`codeigniter-third-party`<br>`codeigniter-module`
39 | Croogo | `croogo-plugin`<br>`croogo-theme`
40 | Drupal | <b>`drupal-module`<br>`drupal-theme`</b><br>`drupal-profile`<br>`drupal-drush`
41 | FuelPHP v1.x | `fuel-module`<br>`fuel-package`
42 | Joomla | `joomla-component`<br>`joomla-module`<br>`joomla-template`<br>`joomla-plugin`<br>`joomla-library`
43 | Kohana | **`kohana-module`**
44 | Laravel | `laravel-library`
45 | Lithium | **`lithium-library`<br>`lithium-source`**
46 | Magento | `magento-library`<br>`magento-skin`<br>`magento-theme`
47 | Mako | `mako-package`
48 | MediaWiki | `mediawiki-extension`
49 | OXID | `oxid-module`
50 | MODULEWork | `modulework-module`
51 | phpBB | `phpbb-extension`<br>`phpbb-style`<br>`phpbb-language`
52 | PPI | **`ppi-module`**
53 | SilverStripe | `silverstripe-module`<br>`silverstripe-theme`
54 | symfony1 | **`symfony1-plugin`**
55 | TYPO3 Flow | `typo3-flow-package`<br>`typo3-flow-framework`<br>`typo3-flow-plugin`<br>`typo3-flow-site`<br>`typo3-flow-boilerplate`<br>`typo3-flow-build`
56 | TYPO3 CMS | `typo3-cms-extension`
57 | WordPress | <b>`wordpress-plugin`<br>`wordpress-theme`</b><br>`wordpress-muplugin`
58 | Zend | `zend-library`<br>`zend-extra`
59
60 ## Example `composer.json` File
61
62 This is an example for a CakePHP plugin. The only important parts to set in your
63 composer.json file are `"type": "cakephp-plugin"` which describes what your
64 package is and `"require": { "composer/installers": "~1.0" }` which tells composer
65 to load the custom installers.
66
67 ```json
68 {
69 "name": "you/ftp",
70 "type": "cakephp-plugin",
71 "require": {
72 "composer/installers": "~1.0"
73 }
74 }
75 ```
76
77 This would install your package to the `Plugin/Ftp/` folder of a CakePHP app
78 when a user runs `php composer.phar install`.
79
80 So submit your packages to [packagist.org](http://packagist.org)!
81
82 ## Custom Install Paths
83
84 If you are consuming a package that uses the `composer/installers` you can
85 override the install path with the following extra in your `composer.json`:
86
87 ```json
88 {
89 "extra": {
90 "installer-paths": {
91 "your/custom/path/{$name}/": ["shama/ftp", "vendor/package"]
92 }
93 }
94 }
95 ```
96
97 A package type can have a custom installation path with a `type:` prefix.
98
99 ``` json
100 {
101 "extra": {
102 "installer-paths": {
103 "your/custom/path/{$name}/": ["type:wordpress-plugin"]
104 }
105 }
106 }
107 ```
108
109 This would use your custom path for each of the listed packages. The available
110 variables to use in your paths are: `{$name}`, `{$vendor}`, `{$type}`.
111
112 ## Custom Install Names
113
114 If you're a package author and need your package to be named differently when
115 installed consider using the `installer-name` extra.
116
117 For example you have a package named `shama/cakephp-ftp` with the type
118 `cakephp-plugin`. Installing with `composer/installers` would install to the
119 path `Plugin/CakephpFtp`. Due to the strict naming conventions, you as a
120 package author actually need the package to be named and installed to
121 `Plugin/Ftp`. Using the following config within your **package** `composer.json`
122 will allow this:
123
124 ```json
125 {
126 "name": "shama/cakephp-ftp",
127 "type": "cakephp-plugin",
128 "extra": {
129 "installer-name": "Ftp"
130 }
131 }
132 ```
133
134 Please note the name entered into `installer-name` will be the final and will
135 not be inflected.
136
137 ## Contribute!
138
139 * [Fork and clone](https://help.github.com/articles/fork-a-repo).
140 * Run the command `php composer.phar install --dev` to install the dev
141 dependencies. See [Composer](https://github.com/composer/composer#installation--usage).
142 * Use the command `phpunit` to run the tests. See [PHPUnit](http://phpunit.de).
143 * Create a branch, commit, push and send us a
144 [pull request](https://help.github.com/articles/using-pull-requests).
145
146 To ensure a consistent code base, you should make sure the code follows the
147 [Coding Standards](http://symfony.com/doc/2.0/contributing/code/standards.html)
148 which we borrowed from Symfony.
149
150 If you would like to help, please take a look at the list of
151 [issues](https://github.com/composer/installers/issues).
152
153 ### Should we allow dynamic package types or paths? No.
154 What are they? The ability for a package author to determine where a package
155 will be installed either through setting the path directly in their
156 `composer.json` or through a dynamic package type: `"type":
157 "framework-install-here"`.
158
159 It has been proposed many times. Even implemented once early on and then
160 removed. `installers` won't do this because it would allow a single package
161 author to wipe out entire folders without the user's consent. That user would
162 then come here to yell at us.
1 {
2 "name": "composer/installers",
3 "type": "composer-installer",
4 "license": "MIT",
5 "description": "A multi-framework Composer library installer",
6 "keywords": [
7 "installer", "cakephp", "laravel", "kohana",
8 "li3", "lithium", "mako","fuelphp",
9 "codeigniter", "symfony", "phpbb", "ppi",
10 "joomla", "wordpress", "drupal", "zend",
11 "silverstripe", "agl", "TYPO3 Flow", "TYPO3 Neos", "modulework",
12 "TYPO3 CMS"
13 ],
14 "homepage": "http://composer.github.com/installers/",
15 "authors": [
16 {
17 "name": "Kyle Robinson Young",
18 "email": "kyle@dontkry.com",
19 "homepage": "https://github.com/shama"
20 }
21 ],
22 "autoload": {
23 "psr-0": { "Composer\\Installers\\": "src/" }
24 },
25 "extra": {
26 "class": "Composer\\Installers\\Installer",
27 "branch-alias": {
28 "dev-master": "1.0-dev"
29 }
30 },
31 "replace": {
32 "shama/baton": "*"
33 },
34 "require-dev": {
35 "composer/composer": "1.0.*@dev",
36 "phpunit/phpunit": "3.7.*"
37 }
38 }
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <phpunit backupGlobals="false"
4 backupStaticAttributes="false"
5 colors="true"
6 convertErrorsToExceptions="true"
7 convertNoticesToExceptions="true"
8 convertWarningsToExceptions="true"
9 processIsolation="false"
10 stopOnFailure="false"
11 syntaxCheck="false"
12 bootstrap="tests/bootstrap.php"
13 >
14 <testsuites>
15 <testsuite name="Installers Test Suite">
16 <directory>tests/Composer/Installers</directory>
17 </testsuite>
18 </testsuites>
19
20 <filter>
21 <whitelist>
22 <directory>src/Composer/Installers</directory>
23 </whitelist>
24 </filter>
25 </phpunit>
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Composer\Installers;
3
4 class AglInstaller extends BaseInstaller
5 {
6 protected $locations = array(
7 'module' => 'More/{$name}/',
8 );
9
10 /**
11 * Format package name to CamelCase
12 */
13 public function inflectPackageVars($vars)
14 {
15 $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function($matches) {
16 return strtoupper($matches[1]);
17 }, $vars['name']);
18
19 return $vars;
20 }
21 }
1 <?php
2 namespace Composer\Installers;
3
4 class AnnotateCmsInstaller extends BaseInstaller
5 {
6 protected $locations = array(
7 'module' => 'addons/modules/{$name}/',
8 'component' => 'addons/components/{$name}/',
9 'service' => 'addons/services/{$name}/',
10 );
11 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2 namespace Composer\Installers;
3
4 use Composer\Composer;
5 use Composer\Package\PackageInterface;
6
7 abstract class BaseInstaller
8 {
9 protected $locations = array();
10 protected $composer;
11 protected $package;
12
13 /**
14 * Initializes base installer.
15 *
16 * @param PackageInterface $package
17 * @param Composer $composer
18 */
19 public function __construct(PackageInterface $package = null, Composer $composer = null)
20 {
21 $this->composer = $composer;
22 $this->package = $package;
23 }
24
25 /**
26 * Return the install path based on package type.
27 *
28 * @param PackageInterface $package
29 * @param string $frameworkType
30 * @return string
31 */
32 public function getInstallPath(PackageInterface $package, $frameworkType = '')
33 {
34 $type = $this->package->getType();
35
36 $prettyName = $this->package->getPrettyName();
37 if (strpos($prettyName, '/') !== false) {
38 list($vendor, $name) = explode('/', $prettyName);
39 } else {
40 $vendor = '';
41 $name = $prettyName;
42 }
43
44 $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
45
46 $extra = $package->getExtra();
47 if (!empty($extra['installer-name'])) {
48 $availableVars['name'] = $extra['installer-name'];
49 }
50
51 if ($this->composer->getPackage()) {
52 $extra = $this->composer->getPackage()->getExtra();
53 if (!empty($extra['installer-paths'])) {
54 $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type);
55 if ($customPath !== false) {
56 return $this->templatePath($customPath, $availableVars);
57 }
58 }
59 }
60
61 $packageType = substr($type, strlen($frameworkType) + 1);
62 if (!isset($this->locations[$packageType])) {
63 throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
64 }
65
66 return $this->templatePath($this->locations[$packageType], $availableVars);
67 }
68
69 /**
70 * For an installer to override to modify the vars per installer.
71 *
72 * @param array $vars
73 * @return array
74 */
75 public function inflectPackageVars($vars)
76 {
77 return $vars;
78 }
79
80 /**
81 * Gets the installer's locations
82 *
83 * @return array
84 */
85 public function getLocations()
86 {
87 return $this->locations;
88 }
89
90 /**
91 * Replace vars in a path
92 *
93 * @param string $path
94 * @param array $vars
95 * @return string
96 */
97 protected function templatePath($path, array $vars = array())
98 {
99 if (strpos($path, '{') !== false) {
100 extract($vars);
101 preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
102 if (!empty($matches[1])) {
103 foreach ($matches[1] as $var) {
104 $path = str_replace('{$' . $var . '}', $$var, $path);
105 }
106 }
107 }
108
109 return $path;
110 }
111
112 /**
113 * Search through a passed paths array for a custom install path.
114 *
115 * @param array $paths
116 * @param string $name
117 * @param string $type
118 * @return string
119 */
120 protected function mapCustomInstallPaths(array $paths, $name, $type)
121 {
122 foreach ($paths as $path => $names) {
123 if (in_array($name, $names) || in_array('type:' . $type, $names)) {
124 return $path;
125 }
126 }
127
128 return false;
129 }
130 }
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.