WordPress Popular Posts - Version 5.3.0

Version Description

  • Improves compatibility with PHP 8.
  • Allows to override widget theme stylesheets.
  • Each post can have its own thumbnail now when using WPP with WPML/Polylang.
  • Improved Polylang support.
  • Adds a loading animation when using the widget with the Ajaxify widget option enabled.
  • Fixes an issue where the plugin wouldn't generate thumbnails when filenames contains Unicode characters.
  • The /popular-posts REST API endpoint now correctly translate posts when using WPML/Polylang.
  • wpp_get_views() can now return views count from custom time ranges.
  • Post thumbnails will now look sharper on retina displays!
  • Other minor improvements / fixes.

Release notes

Download this release

Release Info

Developer hcabrera
Plugin Icon 128x128 WordPress Popular Posts
Version 5.3.0
Comparing to
See all releases

Code changes from version 5.2.4 to 5.3.0

Files changed (57) hide show
  1. i18n/wordpress-popular-posts.pot +57 -28
  2. readme.txt +18 -2
  3. src/Admin/Admin.php +5 -1
  4. src/Admin/admin-page.php +1 -1
  5. src/Container/WordPressPopularPostsConfiguration.php +14 -2
  6. src/Front/Front.php +42 -0
  7. src/I18N.php +19 -6
  8. src/Image.php +179 -49
  9. src/Moment/CustomFormats/MomentJs.php +0 -152
  10. src/Moment/FormatsInterface.php +0 -24
  11. src/Moment/LICENSE.md +0 -21
  12. src/Moment/Locales/ar_TN.php +0 -44
  13. src/Moment/Locales/ca_ES.php +0 -65
  14. src/Moment/Locales/cs_CZ.php +0 -107
  15. src/Moment/Locales/da_DK.php +0 -43
  16. src/Moment/Locales/de_DE.php +0 -44
  17. src/Moment/Locales/en_GB.php +0 -65
  18. src/Moment/Locales/en_US.php +0 -21
  19. src/Moment/Locales/es_ES.php +0 -46
  20. src/Moment/Locales/fr_FR.php +0 -55
  21. src/Moment/Locales/hu_HU.php +0 -72
  22. src/Moment/Locales/id_ID.php +0 -45
  23. src/Moment/Locales/it_IT.php +0 -74
  24. src/Moment/Locales/ja_JP.php +0 -43
  25. src/Moment/Locales/ko_KR.php +0 -59
  26. src/Moment/Locales/lv_LV.php +0 -56
  27. src/Moment/Locales/nl_NL.php +0 -57
  28. src/Moment/Locales/no_NO.php +0 -43
  29. src/Moment/Locales/oc_LNC.php +0 -63
  30. src/Moment/Locales/pl_PL.php +0 -84
  31. src/Moment/Locales/pt_BR.php +0 -46
  32. src/Moment/Locales/pt_PT.php +0 -4
  33. src/Moment/Locales/ro_RO.php +0 -81
  34. src/Moment/Locales/ru_RU.php +0 -102
  35. src/Moment/Locales/se_SV.php +0 -43
  36. src/Moment/Locales/th_TH.php +0 -44
  37. src/Moment/Locales/tr_TR.php +0 -64
  38. src/Moment/Locales/uk_UA.php +0 -119
  39. src/Moment/Locales/vi_VN.php +0 -47
  40. src/Moment/Locales/zh_CN.php +0 -69
  41. src/Moment/Locales/zh_TW.php +0 -67
  42. src/Moment/Moment.php +0 -1427
  43. src/Moment/MomentException.php +0 -12
  44. src/Moment/MomentFromVo.php +0 -321
  45. src/Moment/MomentHelper.php +0 -70
  46. src/Moment/MomentLocale.php +0 -227
  47. src/Moment/MomentPeriodVo.php +0 -103
  48. src/Output.php +85 -58
  49. src/Rest/Controller.php +20 -565
  50. src/Rest/Endpoint.php +113 -0
  51. src/Rest/PostsEndpoint.php +193 -0
  52. src/Rest/ViewLoggerEndpoint.php +242 -0
  53. src/Rest/WidgetEndpoint.php +136 -0
  54. src/Widget/Widget.php +0 -2
  55. src/WordPressPopularPosts.php +1 -1
  56. src/template-tags.php +60 -41
  57. wordpress-popular-posts.php +2 -2
i18n/wordpress-popular-posts.pot CHANGED
@@ -5,7 +5,7 @@ msgid ""
5
  msgstr ""
6
  "Project-Id-Version: WordPress Popular Posts\n"
7
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/wordpress-popular-posts\n"
8
- "POT-Creation-Date: 2020-07-12 14:41-0400\n"
9
  "PO-Revision-Date: 2015-04-24 13:30-0430\n"
10
  "Last-Translator: Héctor Cabrera <hcabrerab@gmail.com>\n"
11
  "Language-Team: Héctor Cabrera <me@cabrerahector.com>\n"
@@ -14,7 +14,7 @@ msgstr ""
14
  "Content-Type: text/plain; charset=UTF-8\n"
15
  "Content-Transfer-Encoding: 8bit\n"
16
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
- "X-Generator: Poedit 2.3.1\n"
18
  "X-Poedit-KeywordsList: _e;__;__ngettext;__ngettext_noop;_n_noop;_x;_nx;_nx_noop;_ex;"
19
  "esc_attr__;esc_attr_e;esc_attr_x;esc_html__;esc_html_e;esc_html_x;_c;_nc;_n:1,2\n"
20
  "X-Poedit-Basepath: .\n"
@@ -77,7 +77,7 @@ msgid "Settings"
77
  msgstr ""
78
 
79
  #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1088 ../src/Admin/Admin.php:1092
80
- #: ../src/Output.php:735
81
  #, php-format
82
  msgid "%s view"
83
  msgid_plural "%s views"
@@ -85,7 +85,7 @@ msgstr[0] ""
85
  msgstr[1] ""
86
 
87
  #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1090 ../src/Admin/Admin.php:1092
88
- #: ../src/Output.php:718
89
  #, php-format
90
  msgid "%s comment"
91
  msgid_plural "%s comments"
@@ -875,26 +875,50 @@ msgstr ""
875
  msgid "returns linked author name, requires stats_author=1"
876
  msgstr ""
877
 
 
 
 
 
878
  #: ../src/Admin/admin-page.php:878
879
  msgid "returns linked category name, requires stats_category=1"
880
  msgstr ""
881
 
 
 
 
 
882
  #: ../src/Admin/admin-page.php:878
883
  msgid "returns linked taxonomy names, requires stats_taxonomy=1"
884
  msgstr ""
885
 
886
  #: ../src/Admin/admin-page.php:878
887
- msgid "returns views count only, no text"
 
 
 
 
 
 
 
 
888
  msgstr ""
889
 
890
  #: ../src/Admin/admin-page.php:878
891
  msgid "returns comments count only, no text, requires stats_comments=1"
892
  msgstr ""
893
 
 
 
 
 
894
  #: ../src/Admin/admin-page.php:878
895
  msgid "returns post/page date, requires stats_date=1"
896
  msgstr ""
897
 
 
 
 
 
898
  #: ../src/Admin/admin-page.php:878
899
  msgid "outputs number of popular posts found"
900
  msgstr ""
@@ -903,102 +927,107 @@ msgstr ""
903
  msgid "outputs the position of the post in the listing"
904
  msgstr ""
905
 
906
- #: ../src/Output.php:243
907
  msgid "Sorry. No data so far."
908
  msgstr ""
909
 
910
- #: ../src/Output.php:729
 
 
 
 
 
911
  #, php-format
912
  msgid "%s view per day"
913
  msgid_plural "%s views per day"
914
  msgstr[0] ""
915
  msgstr[1] ""
916
 
917
- #: ../src/Output.php:758
918
  #, php-format
919
  msgid "by %s"
920
  msgstr ""
921
 
922
- #: ../src/Output.php:764
923
  #, php-format
924
  msgid "posted %s"
925
  msgstr ""
926
 
927
- #: ../src/Output.php:764
928
  #, php-format
929
  msgid "posted on %s"
930
  msgstr ""
931
 
932
- #: ../src/Output.php:772
933
  #, php-format
934
  msgid "under %s"
935
  msgstr ""
936
 
937
- #: ../src/Rest/Controller.php:306
938
  msgid "Invalid Widget Instance ID"
939
  msgstr ""
940
 
941
- #: ../src/Rest/Controller.php:416
942
  msgid "Return popular posts from specified custom post type(s)."
943
  msgstr ""
944
 
945
- #: ../src/Rest/Controller.php:423
946
  msgid "The maximum number of popular posts to return."
947
  msgstr ""
948
 
949
- #: ../src/Rest/Controller.php:431
950
  msgid "Retrieve the most popular entries published within the specified time range."
951
  msgstr ""
952
 
953
- #: ../src/Rest/Controller.php:439
954
  msgid "An offset point for the collection."
955
  msgstr ""
956
 
957
- #: ../src/Rest/Controller.php:447
958
  msgid "Set the sorting option of the popular posts."
959
  msgstr ""
960
 
961
- #: ../src/Rest/Controller.php:455
962
  msgid "Return popular posts from a specified time range."
963
  msgstr ""
964
 
965
- #: ../src/Rest/Controller.php:463
966
  msgid "Specifies the time unit of the custom time range."
967
  msgstr ""
968
 
969
- #: ../src/Rest/Controller.php:471
970
  msgid "Specifies the number of time units of the custom time range."
971
  msgstr ""
972
 
973
- #: ../src/Rest/Controller.php:479
974
  msgid "Post IDs to exclude from the listing."
975
  msgstr ""
976
 
977
- #: ../src/Rest/Controller.php:487
978
  msgid "Include posts in a specified taxonomy."
979
  msgstr ""
980
 
981
- #: ../src/Rest/Controller.php:495
982
  msgid "Taxonomy IDs, separated by comma (prefix a minus sign to exclude)."
983
  msgstr ""
984
 
985
- #: ../src/Rest/Controller.php:503
986
  msgid "Include popular posts from author ID(s)."
987
  msgstr ""
988
 
989
- #: ../src/Rest/Controller.php:524
990
  msgid "Security nonce."
991
  msgstr ""
992
 
993
- #: ../src/Rest/Controller.php:530
994
  msgid "The post / page ID."
995
  msgstr ""
996
 
997
- #: ../src/Rest/Controller.php:537
998
  msgid "Enables Data Sampling."
999
  msgstr ""
1000
 
1001
- #: ../src/Rest/Controller.php:544
1002
  msgid "Sets the Sampling Rate."
1003
  msgstr ""
1004
 
5
  msgstr ""
6
  "Project-Id-Version: WordPress Popular Posts\n"
7
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/wordpress-popular-posts\n"
8
+ "POT-Creation-Date: 2020-10-12 13:04-0400\n"
9
  "PO-Revision-Date: 2015-04-24 13:30-0430\n"
10
  "Last-Translator: Héctor Cabrera <hcabrerab@gmail.com>\n"
11
  "Language-Team: Héctor Cabrera <me@cabrerahector.com>\n"
14
  "Content-Type: text/plain; charset=UTF-8\n"
15
  "Content-Transfer-Encoding: 8bit\n"
16
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
+ "X-Generator: Poedit 2.4.1\n"
18
  "X-Poedit-KeywordsList: _e;__;__ngettext;__ngettext_noop;_n_noop;_x;_nx;_nx_noop;_ex;"
19
  "esc_attr__;esc_attr_e;esc_attr_x;esc_html__;esc_html_e;esc_html_x;_c;_nc;_n:1,2\n"
20
  "X-Poedit-Basepath: .\n"
77
  msgstr ""
78
 
79
  #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1088 ../src/Admin/Admin.php:1092
80
+ #: ../src/Output.php:757
81
  #, php-format
82
  msgid "%s view"
83
  msgid_plural "%s views"
85
  msgstr[1] ""
86
 
87
  #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1090 ../src/Admin/Admin.php:1092
88
+ #: ../src/Output.php:740
89
  #, php-format
90
  msgid "%s comment"
91
  msgid_plural "%s comments"
875
  msgid "returns linked author name, requires stats_author=1"
876
  msgstr ""
877
 
878
+ #: ../src/Admin/admin-page.php:878
879
+ msgid "returns linked author name with copy, requires stats_author=1"
880
+ msgstr ""
881
+
882
  #: ../src/Admin/admin-page.php:878
883
  msgid "returns linked category name, requires stats_category=1"
884
  msgstr ""
885
 
886
+ #: ../src/Admin/admin-page.php:878
887
+ msgid "returns linked category name with copy, requires stats_category=1"
888
+ msgstr ""
889
+
890
  #: ../src/Admin/admin-page.php:878
891
  msgid "returns linked taxonomy names, requires stats_taxonomy=1"
892
  msgstr ""
893
 
894
  #: ../src/Admin/admin-page.php:878
895
+ msgid "returns linked taxonomy names with copy, requires stats_taxonomy=1"
896
+ msgstr ""
897
+
898
+ #: ../src/Admin/admin-page.php:878
899
+ msgid "returns views count only, no text, requires stats_views=1"
900
+ msgstr ""
901
+
902
+ #: ../src/Admin/admin-page.php:878
903
+ msgid "returns views count with copy, requires stats_views=1"
904
  msgstr ""
905
 
906
  #: ../src/Admin/admin-page.php:878
907
  msgid "returns comments count only, no text, requires stats_comments=1"
908
  msgstr ""
909
 
910
+ #: ../src/Admin/admin-page.php:878
911
+ msgid "returns comments count with copy, requires stats_comments=1"
912
+ msgstr ""
913
+
914
  #: ../src/Admin/admin-page.php:878
915
  msgid "returns post/page date, requires stats_date=1"
916
  msgstr ""
917
 
918
+ #: ../src/Admin/admin-page.php:878
919
+ msgid "returns post/page date with copy, requires stats_date=1"
920
+ msgstr ""
921
+
922
  #: ../src/Admin/admin-page.php:878
923
  msgid "outputs number of popular posts found"
924
  msgstr ""
927
  msgid "outputs the position of the post in the listing"
928
  msgstr ""
929
 
930
+ #: ../src/Output.php:248
931
  msgid "Sorry. No data so far."
932
  msgstr ""
933
 
934
+ #: ../src/Output.php:588
935
+ #, php-format
936
+ msgid "%s ago"
937
+ msgstr ""
938
+
939
+ #: ../src/Output.php:751
940
  #, php-format
941
  msgid "%s view per day"
942
  msgid_plural "%s views per day"
943
  msgstr[0] ""
944
  msgstr[1] ""
945
 
946
+ #: ../src/Output.php:769
947
  #, php-format
948
  msgid "by %s"
949
  msgstr ""
950
 
951
+ #: ../src/Output.php:774
952
  #, php-format
953
  msgid "posted %s"
954
  msgstr ""
955
 
956
+ #: ../src/Output.php:774
957
  #, php-format
958
  msgid "posted on %s"
959
  msgstr ""
960
 
961
+ #: ../src/Output.php:779
962
  #, php-format
963
  msgid "under %s"
964
  msgstr ""
965
 
966
+ #: ../src/Rest/Controller.php:308
967
  msgid "Invalid Widget Instance ID"
968
  msgstr ""
969
 
970
+ #: ../src/Rest/Controller.php:406
971
  msgid "Return popular posts from specified custom post type(s)."
972
  msgstr ""
973
 
974
+ #: ../src/Rest/Controller.php:413
975
  msgid "The maximum number of popular posts to return."
976
  msgstr ""
977
 
978
+ #: ../src/Rest/Controller.php:421
979
  msgid "Retrieve the most popular entries published within the specified time range."
980
  msgstr ""
981
 
982
+ #: ../src/Rest/Controller.php:429
983
  msgid "An offset point for the collection."
984
  msgstr ""
985
 
986
+ #: ../src/Rest/Controller.php:437
987
  msgid "Set the sorting option of the popular posts."
988
  msgstr ""
989
 
990
+ #: ../src/Rest/Controller.php:445
991
  msgid "Return popular posts from a specified time range."
992
  msgstr ""
993
 
994
+ #: ../src/Rest/Controller.php:453
995
  msgid "Specifies the time unit of the custom time range."
996
  msgstr ""
997
 
998
+ #: ../src/Rest/Controller.php:461
999
  msgid "Specifies the number of time units of the custom time range."
1000
  msgstr ""
1001
 
1002
+ #: ../src/Rest/Controller.php:469
1003
  msgid "Post IDs to exclude from the listing."
1004
  msgstr ""
1005
 
1006
+ #: ../src/Rest/Controller.php:477
1007
  msgid "Include posts in a specified taxonomy."
1008
  msgstr ""
1009
 
1010
+ #: ../src/Rest/Controller.php:485
1011
  msgid "Taxonomy IDs, separated by comma (prefix a minus sign to exclude)."
1012
  msgstr ""
1013
 
1014
+ #: ../src/Rest/Controller.php:493
1015
  msgid "Include popular posts from author ID(s)."
1016
  msgstr ""
1017
 
1018
+ #: ../src/Rest/Controller.php:514
1019
  msgid "Security nonce."
1020
  msgstr ""
1021
 
1022
+ #: ../src/Rest/Controller.php:520
1023
  msgid "The post / page ID."
1024
  msgstr ""
1025
 
1026
+ #: ../src/Rest/Controller.php:527
1027
  msgid "Enables Data Sampling."
1028
  msgstr ""
1029
 
1030
+ #: ../src/Rest/Controller.php:534
1031
  msgid "Sets the Sampling Rate."
1032
  msgstr ""
1033
 
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: hcabrera
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=hcabrerab%40gmail%2ecom&lc=GB&item_name=WordPress%20Popular%20Posts%20Plugin&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG_global%2egif%3aNonHosted
4
  Tags: popular, posts, widget, popularity, top
5
  Requires at least: 4.9
6
- Tested up to: 5.5
7
  Requires PHP: 5.4
8
- Stable tag: 5.2.4
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -90,6 +90,22 @@ The FAQ section has been moved [here](https://github.com/cabrerahector/wordpress
90
  4. Statistics panel.
91
 
92
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  = 5.2.4 =
94
 
95
  - Fixes PHP notices affecting Block Editor users on WordPress 5.5.
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=hcabrerab%40gmail%2ecom&lc=GB&item_name=WordPress%20Popular%20Posts%20Plugin&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG_global%2egif%3aNonHosted
4
  Tags: popular, posts, widget, popularity, top
5
  Requires at least: 4.9
6
+ Tested up to: 5.7.1
7
  Requires PHP: 5.4
8
+ Stable tag: 5.3.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
90
  4. Statistics panel.
91
 
92
  == Changelog ==
93
+
94
+ = 5.3.0 =
95
+
96
+ - Improves compatibility with PHP 8.
97
+ - Allows to override widget theme stylesheets.
98
+ - Each post can have its own thumbnail now when using WPP with WPML/Polylang.
99
+ - Improved Polylang support.
100
+ - Adds a loading animation when using the widget with the Ajaxify widget option enabled.
101
+ - Fixes an issue where the plugin wouldn't generate thumbnails when filenames contains Unicode characters.
102
+ - The /popular-posts REST API endpoint now correctly translate posts when using WPML/Polylang.
103
+ - `wpp_get_views()` can now return views count from custom time ranges.
104
+ - Post thumbnails will now look sharper on retina displays!
105
+ - Other minor improvements / fixes.
106
+
107
+ [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-3-improved-php-8-support-retina-display-support-and-more/)
108
+
109
  = 5.2.4 =
110
 
111
  - Fixes PHP notices affecting Block Editor users on WordPress 5.5.
src/Admin/Admin.php CHANGED
@@ -619,7 +619,11 @@ class Admin {
619
  is_plugin_active($plugin_file)
620
  && $plugin_file == $file
621
  ) {
622
- $links[] = '<a href="' . admin_url('options-general.php?page=wordpress-popular-posts') . '">' . __('Settings') . '</a>';
 
 
 
 
623
  }
624
 
625
  return $links;
619
  is_plugin_active($plugin_file)
620
  && $plugin_file == $file
621
  ) {
622
+ array_unshift(
623
+ $links,
624
+ '<a href="' . admin_url('options-general.php?page=wordpress-popular-posts') . '">' . __('Settings') . '</a>',
625
+ '<a href="https://wordpress.org/support/plugin/wordpress-popular-posts/">' . __('Support', 'wordpress-popular-posts') . '</a>'
626
+ );
627
  }
628
 
629
  return $links;
src/Admin/admin-page.php CHANGED
@@ -875,7 +875,7 @@ if ( ! $wpp_rand = get_option("wpp_rand") ) {
875
  <tr>
876
  <td><strong>post_html</strong></td>
877
  <td><?php _e('Sets the HTML structure of each post', 'wordpress-popular-posts'); ?></td>
878
- <td><?php _e('Text string, custom HTML', 'wordpress-popular-posts'); ?>.<br /><br /><strong><?php _e('Available Content Tags', 'wordpress-popular-posts'); ?>:</strong> <br /><br /><em>{thumb}</em> (<?php _e('returns thumbnail linked to post/page, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{thumb_img}</em> (<?php _e('returns thumbnail image without linking to post/page, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{thumb_url}</em> (<?php _e('returns thumbnail url, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{title}</em> (<?php _e('returns linked post/page title', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{pid}</em> (<?php _e('returns the post/page ID', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{summary}</em> (<?php _e('returns post/page excerpt, and requires excerpt_length to be greater than 0', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{stats}</em> (<?php _e('returns the default stats tags', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{rating}</em> (<?php _e('returns post/page current rating, requires WP-PostRatings installed and enabled', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{score}</em> (<?php _e('returns post/page current rating as an integer, requires WP-PostRatings installed and enabled', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{url}</em> (<?php _e('returns the URL of the post/page', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{text_title}</em> (<?php _e('returns post/page title, no link', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{title_attr}</em> (<?php _e('similar to text_title, sanitized for use in title/alt attributes', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{author}</em> (<?php _e('returns linked author name, requires stats_author=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{category}</em> (<?php _e('returns linked category name, requires stats_category=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{taxonomy}</em> (<?php _e('returns linked taxonomy names, requires stats_taxonomy=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{views}</em> (<?php _e('returns views count only, no text', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{comments}</em> (<?php _e('returns comments count only, no text, requires stats_comments=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{date}</em> (<?php _e('returns post/page date, requires stats_date=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{total_items}</em> (<?php _e('outputs number of popular posts found', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{item_position}</em> (<?php _e('outputs the position of the post in the listing', 'wordpress-popular-posts'); ?>)</td>
879
  <td>&lt;li&gt;{thumb} {title} &lt;span class="wpp-meta post-stats"&gt;{stats}&lt;/span&gt;&lt;/li&gt;</td>
880
  <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{thumb} &lt;a href="{url}"&gt;{text_title}&lt;/a&gt;&lt;/li&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_width' => 100,<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_height' => 75<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp thumbnail_width=100 thumbnail_height=75 post_html='&lt;li&gt;{thumb} &lt;a href="{url}"&gt;{text_title}&lt;/a&gt;&lt;/li&gt;']<br /><br /></td>
881
  </tr>
875
  <tr>
876
  <td><strong>post_html</strong></td>
877
  <td><?php _e('Sets the HTML structure of each post', 'wordpress-popular-posts'); ?></td>
878
+ <td><?php _e('Text string, custom HTML', 'wordpress-popular-posts'); ?>.<br /><br /><strong><?php _e('Available Content Tags', 'wordpress-popular-posts'); ?>:</strong> <br /><br /><em>{thumb}</em> (<?php _e('returns thumbnail linked to post/page, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{thumb_img}</em> (<?php _e('returns thumbnail image without linking to post/page, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{thumb_url}</em> (<?php _e('returns thumbnail url, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{title}</em> (<?php _e('returns linked post/page title', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{pid}</em> (<?php _e('returns the post/page ID', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{summary}</em> (<?php _e('returns post/page excerpt, and requires excerpt_length to be greater than 0', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{stats}</em> (<?php _e('returns the default stats tags', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{rating}</em> (<?php _e('returns post/page current rating, requires WP-PostRatings installed and enabled', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{score}</em> (<?php _e('returns post/page current rating as an integer, requires WP-PostRatings installed and enabled', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{url}</em> (<?php _e('returns the URL of the post/page', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{text_title}</em> (<?php _e('returns post/page title, no link', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{title_attr}</em> (<?php _e('similar to text_title, sanitized for use in title/alt attributes', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{author}</em> (<?php _e('returns linked author name, requires stats_author=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{author_copy}</em> (<?php _e('returns linked author name with copy, requires stats_author=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{category}</em> (<?php _e('returns linked category name, requires stats_category=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{category_copy}</em> (<?php _e('returns linked category name with copy, requires stats_category=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{taxonomy}</em> (<?php _e('returns linked taxonomy names, requires stats_taxonomy=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{taxonomy_copy}</em> (<?php _e('returns linked taxonomy names with copy, requires stats_taxonomy=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{views}</em> (<?php _e('returns views count only, no text, requires stats_views=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{views_copy}</em> (<?php _e('returns views count with copy, requires stats_views=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{comments}</em> (<?php _e('returns comments count only, no text, requires stats_comments=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{comments_copy}</em> (<?php _e('returns comments count with copy, requires stats_comments=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{date}</em> (<?php _e('returns post/page date, requires stats_date=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{date_copy}</em> (<?php _e('returns post/page date with copy, requires stats_date=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{total_items}</em> (<?php _e('outputs number of popular posts found', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{item_position}</em> (<?php _e('outputs the position of the post in the listing', 'wordpress-popular-posts'); ?>)</td>
879
  <td>&lt;li&gt;{thumb} {title} &lt;span class="wpp-meta post-stats"&gt;{stats}&lt;/span&gt;&lt;/li&gt;</td>
880
  <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{thumb} &lt;a href="{url}"&gt;{text_title}&lt;/a&gt;&lt;/li&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_width' => 100,<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_height' => 75<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp thumbnail_width=100 thumbnail_height=75 post_html='&lt;li&gt;{thumb} &lt;a href="{url}"&gt;{text_title}&lt;/a&gt;&lt;/li&gt;']<br /><br /></td>
881
  </tr>
src/Container/WordPressPopularPostsConfiguration.php CHANGED
@@ -17,7 +17,7 @@ class WordPressPopularPostsConfiguration implements ContainerConfigurationInterf
17
  $container['widget_options'] = Settings::get('widget_options');
18
 
19
  $container['i18n'] = $container->service(function(Container $container) {
20
- return new \WordPressPopularPosts\I18N();
21
  });
22
 
23
  $container['translate'] = $container->service(function(Container $container) {
@@ -40,8 +40,20 @@ class WordPressPopularPostsConfiguration implements ContainerConfigurationInterf
40
  return new \WordPressPopularPosts\Widget\Widget($container['widget_options'], $container['admin_options'], $container['output'], $container['image'], $container['translate'], $container['themer']);
41
  });
42
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  $container['rest'] = $container->service(function(Container $container) {
44
- return new \WordPressPopularPosts\Rest\Controller($container['admin_options'], $container['translate'], $container['output']);
45
  });
46
 
47
  $container['admin'] = $container->service(function(Container $container) {
17
  $container['widget_options'] = Settings::get('widget_options');
18
 
19
  $container['i18n'] = $container->service(function(Container $container) {
20
+ return new \WordPressPopularPosts\I18N($container['admin_options']);
21
  });
22
 
23
  $container['translate'] = $container->service(function(Container $container) {
40
  return new \WordPressPopularPosts\Widget\Widget($container['widget_options'], $container['admin_options'], $container['output'], $container['image'], $container['translate'], $container['themer']);
41
  });
42
 
43
+ $container['posts_endpoint'] = $container->service(function(Container $container) {
44
+ return new \WordPressPopularPosts\Rest\PostsEndpoint($container['admin_options'], $container['translate']);
45
+ });
46
+
47
+ $container['view_logger_endpoint'] = $container->service(function(Container $container) {
48
+ return new \WordPressPopularPosts\Rest\ViewLoggerEndpoint($container['admin_options'], $container['translate']);
49
+ });
50
+
51
+ $container['widget_endpoint'] = $container->service(function(Container $container) {
52
+ return new \WordPressPopularPosts\Rest\WidgetEndpoint($container['admin_options'], $container['translate'], $container['output']);
53
+ });
54
+
55
  $container['rest'] = $container->service(function(Container $container) {
56
+ return new \WordPressPopularPosts\Rest\Controller($container['posts_endpoint'], $container['view_logger_endpoint'], $container['widget_endpoint']);
57
  });
58
 
59
  $container['admin'] = $container->service(function(Container $container) {
src/Front/Front.php CHANGED
@@ -63,12 +63,54 @@ class Front {
63
  public function hooks()
64
  {
65
  add_shortcode('wpp', [$this, 'wpp_shortcode']);
 
66
  add_action('wp_ajax_update_views_ajax', [$this, 'update_views']);
67
  add_action('wp_ajax_nopriv_update_views_ajax', [$this, 'update_views']);
68
  add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
69
  add_filter('script_loader_tag', [$this, 'convert_inline_js_into_json'], 10, 3);
70
  }
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  /**
73
  * Enqueues public facing assets.
74
  *
63
  public function hooks()
64
  {
65
  add_shortcode('wpp', [$this, 'wpp_shortcode']);
66
+ add_action('wp_head', [$this, 'inline_loading_css']);
67
  add_action('wp_ajax_update_views_ajax', [$this, 'update_views']);
68
  add_action('wp_ajax_nopriv_update_views_ajax', [$this, 'update_views']);
69
  add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
70
  add_filter('script_loader_tag', [$this, 'convert_inline_js_into_json'], 10, 3);
71
  }
72
 
73
+ /**
74
+ *
75
+ */
76
+ public function inline_loading_css()
77
+ {
78
+ ?>
79
+ <style>
80
+ @-webkit-keyframes bgslide {
81
+ from {
82
+ background-position-x: 0;
83
+ }
84
+ to {
85
+ background-position-x: -200%;
86
+ }
87
+ }
88
+
89
+ @keyframes bgslide {
90
+ from {
91
+ background-position-x: 0;
92
+ }
93
+ to {
94
+ background-position-x: -200%;
95
+ }
96
+ }
97
+
98
+ .wpp-widget-placeholder {
99
+ margin: 0 auto;
100
+ width: 60px;
101
+ height: 3px;
102
+ background: #dd3737;
103
+ background: -webkit-gradient(linear, left top, right top, from(#dd3737), color-stop(10%, #571313), to(#dd3737));
104
+ background: linear-gradient(90deg, #dd3737 0%, #571313 10%, #dd3737 100%);
105
+ background-size: 200% auto;
106
+ border-radius: 3px;
107
+ -webkit-animation: bgslide 1s infinite linear;
108
+ animation: bgslide 1s infinite linear;
109
+ }
110
+ </style>
111
+ <?php
112
+ }
113
+
114
  /**
115
  * Enqueues public facing assets.
116
  *
src/I18N.php CHANGED
@@ -14,13 +14,21 @@ namespace WordPressPopularPosts;
14
 
15
  class I18N {
16
  /**
17
- * WordPress hooks.
18
  *
19
- * @since 5.0.0
 
20
  */
21
- public function hooks()
 
 
 
 
 
 
 
22
  {
23
- add_action('plugins_loaded', [$this, 'load_plugin_textdomain']);
24
  }
25
 
26
  /**
@@ -30,7 +38,12 @@ class I18N {
30
  */
31
  public function load_plugin_textdomain()
32
  {
33
- $locale = apply_filters('plugin_locale', get_locale(), 'wordpress-popular-posts');
34
- load_textdomain('wordpress-popular-posts', WP_LANG_DIR . '/' . 'wordpress-popular-posts' . '/' . 'wordpress-popular-posts' . '-' . $locale . '.mo');
 
 
 
 
 
35
  }
36
  }
14
 
15
  class I18N {
16
  /**
17
+ * Plugin options.
18
  *
19
+ * @var array $config
20
+ * @access private
21
  */
22
+ private $config;
23
+
24
+ /**
25
+ * Construct.
26
+ *
27
+ * @since 5.3.0
28
+ */
29
+ public function __construct(array $config)
30
  {
31
+ $this->config = $config;
32
  }
33
 
34
  /**
38
  */
39
  public function load_plugin_textdomain()
40
  {
41
+ // This is basically a "hack" and should be removed in the future
42
+ // if/when we figure out why Polylang doesn't load WPP's mo files
43
+ // while WPML does that automatically.
44
+ if ( ! is_admin() && ! $this->config['tools']['ajax'] && function_exists('PLL') ) {
45
+ unload_textdomain('wordpress-popular-posts');
46
+ load_textdomain('wordpress-popular-posts', WP_LANG_DIR . '/plugins/wordpress-popular-posts-' . get_locale() . '.mo');
47
+ }
48
  }
49
  }
src/Image.php CHANGED
@@ -43,6 +43,14 @@ class Image {
43
  */
44
  private $available_sizes = [];
45
 
 
 
 
 
 
 
 
 
46
  /**
47
  * Construct.
48
  *
@@ -71,6 +79,9 @@ class Image {
71
  $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'];
72
  }
73
  }
 
 
 
74
  }
75
 
76
  /**
@@ -91,23 +102,23 @@ class Image {
91
  * Returns an image.
92
  *
93
  * @since 5.0.0
94
- * @param \stdClass $post_object Post object
95
  * @param array $size Image size (width & height)
96
  * @param string $source Image source
97
  * @param bool $crop Whether to crop the image or not
98
  * @param string $build Whether to build the image or get an existing one
99
  * @return string
100
  */
101
- public function get($post_object, $size, $source, $crop = true, $build = 'manual')
102
  {
103
- // Bail, $post_object is not an actual object
104
- if ( false === $post_object instanceof \stdClass || ! isset($post_object->id) ) {
105
  return '';
106
  }
107
 
108
  $alt = '';
109
  $classes = ['wpp-thumbnail', 'wpp_' . $source];
110
- $filename = $post_object->id . '-' . $source . '-' . $size[0] . 'x' . $size[1];
111
  $cached = $this->exists($filename);
112
 
113
  // We have a thumbnail already, return it
@@ -125,11 +136,11 @@ class Image {
125
  $classes = apply_filters(
126
  'wpp_thumbnail_class_attribute',
127
  $classes,
128
- $post_object->id
129
  );
130
 
131
  /**
132
- * Filters CSS classes assigned to the thumbnail
133
  *
134
  * @since 5.0.0
135
  * @param string Original ALT attribute
@@ -138,8 +149,8 @@ class Image {
138
  */
139
  $alt = apply_filters(
140
  'wpp_thumbnail_alt_attribute',
141
- $this->get_alt_attribute($post_object->id, $source),
142
- $post_object->id
143
  );
144
 
145
  return $this->render(
@@ -157,24 +168,10 @@ class Image {
157
  ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] )
158
  || ( 'featured' == $source && 'predefined' == $build )
159
  ){
160
- /**
161
- * Filters CSS classes assigned to the thumbnail
162
- *
163
- * @since 5.0.0
164
- * @param array CSS classes
165
- * @param int The post ID
166
- * @return array The new CSS classes
167
- */
168
- $classes = apply_filters(
169
- 'wpp_thumbnail_class_attribute',
170
- $classes,
171
- $post_object->id
172
- );
173
-
174
  // Get custom field image URL
175
  if ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] ) {
176
  $thumb_url = get_post_meta(
177
- $post_object->id,
178
  $this->admin_options['tools']['thumbnail']['field'],
179
  true
180
  );
@@ -188,28 +185,12 @@ class Image {
188
  $thumb_url = null;
189
  }
190
  }
191
-
192
- if ( $thumb_url ) {
193
- /**
194
- * Filters CSS classes assigned to the thumbnail
195
- *
196
- * @since 5.0.0
197
- * @param string Original ALT attribute
198
- * @param int The post ID
199
- * @return string The new ALT attribute
200
- */
201
- $alt = apply_filters(
202
- 'wpp_thumbnail_alt_attribute',
203
- '',
204
- $post_object->id
205
- );
206
- }
207
  }
208
  // Get Post Thumbnail
209
  else {
210
  if (
211
  current_theme_supports('post-thumbnails')
212
- && has_post_thumbnail($post_object->id)
213
  ) {
214
  // Find corresponding image size
215
  $stock_size = null;
@@ -232,8 +213,22 @@ class Image {
232
  $stock_size = $size;
233
  }
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  $featured_image = get_the_post_thumbnail(
236
- $post_object->id,
237
  $stock_size
238
  );
239
 
@@ -254,7 +249,7 @@ class Image {
254
 
255
  if ( 'custom_field' == $source && $this->admin_options['tools']['thumbnail']['resize'] ) {
256
  $thumb_url = get_post_meta(
257
- $post_object->id,
258
  $this->admin_options['tools']['thumbnail']['field'],
259
  true
260
  );
@@ -271,10 +266,10 @@ class Image {
271
  }
272
 
273
  if ( $thumb_url && $this->is_image_url($thumb_url) ) {
274
- $file_path = $this->url_to_path($thumb_url, $post_object->id);
275
  }
276
  } else {
277
- $file_meta = $this->get_file_meta($post_object->id, $source);
278
 
279
  if ( is_array($file_meta) && isset($file_meta['path']) ) {
280
  $alt = isset($file_meta['alt']) ? $file_meta['alt'] : '';
@@ -295,9 +290,37 @@ class Image {
295
 
296
  if ( ! $thumb_url ) {
297
  $classes[] = 'wpp_def_no_src';
298
- $thumb_url = $this->get_default_url($post_object->id);
299
  }
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  return $this->render(
302
  $thumb_url,
303
  $size,
@@ -656,7 +679,7 @@ class Image {
656
  }
657
 
658
  /**
659
- * Resizes image.
660
  *
661
  * @since 3.0.0
662
  * @access private
@@ -670,6 +693,75 @@ class Image {
670
  {
671
  $image = wp_get_image_editor($path);
672
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
673
  // valid image, create thumbnail
674
  if ( ! is_wp_error($image) ) {
675
  /**
@@ -693,6 +785,39 @@ class Image {
693
  return false;
694
  }
695
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
696
  /**
697
  * Render image tag.
698
  *
@@ -713,7 +838,8 @@ class Image {
713
  $img_tag = '<!-- ' . $error . ' --> ';
714
  }
715
 
716
- $src = 'src="' . esc_url(is_ssl() ? str_ireplace("http://", "https://", $src) : $src) . '"';
 
717
  $lazyload = ( $this->admin_options['tools']['thumbnail']['lazyload'] ) ? ' loading="lazy"' : '';
718
 
719
  $img_tag .= '<img ' . $src . ' width="' . $size[0] . '" height="' . $size[1] . '" alt="' . esc_attr($alt) . '" class="' . esc_attr($class) . '"' . $lazyload . ' />';
@@ -793,7 +919,11 @@ class Image {
793
  */
794
  private function is_image_url($url)
795
  {
796
- if ( ! filter_var($url, FILTER_VALIDATE_URL) )
 
 
 
 
797
  return false;
798
 
799
  // sanitize URL, just in case
43
  */
44
  private $available_sizes = [];
45
 
46
+ /**
47
+ * Available image descriptors.
48
+ *
49
+ * @since 5.3.0
50
+ * @var array
51
+ */
52
+ private $descriptors = [];
53
+
54
  /**
55
  * Construct.
56
  *
79
  $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'];
80
  }
81
  }
82
+
83
+ // Set descriptors
84
+ $this->descriptors = [1.5, 2, 2.5, 3];
85
  }
86
 
87
  /**
102
  * Returns an image.
103
  *
104
  * @since 5.0.0
105
+ * @param int $post_id Post ID
106
  * @param array $size Image size (width & height)
107
  * @param string $source Image source
108
  * @param bool $crop Whether to crop the image or not
109
  * @param string $build Whether to build the image or get an existing one
110
  * @return string
111
  */
112
+ public function get($post_id, $size, $source, $crop = true, $build = 'manual')
113
  {
114
+ // Bail, $post_id is not an integer
115
+ if ( ! is_numeric($post_id) ) {
116
  return '';
117
  }
118
 
119
  $alt = '';
120
  $classes = ['wpp-thumbnail', 'wpp_' . $source];
121
+ $filename = $post_id . '-' . $source . '-' . $size[0] . 'x' . $size[1];
122
  $cached = $this->exists($filename);
123
 
124
  // We have a thumbnail already, return it
136
  $classes = apply_filters(
137
  'wpp_thumbnail_class_attribute',
138
  $classes,
139
+ $post_id
140
  );
141
 
142
  /**
143
+ * Filters ALT attribute assigned to the thumbnail
144
  *
145
  * @since 5.0.0
146
  * @param string Original ALT attribute
149
  */
150
  $alt = apply_filters(
151
  'wpp_thumbnail_alt_attribute',
152
+ $this->get_alt_attribute($post_id, $source),
153
+ $post_id
154
  );
155
 
156
  return $this->render(
168
  ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] )
169
  || ( 'featured' == $source && 'predefined' == $build )
170
  ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  // Get custom field image URL
172
  if ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] ) {
173
  $thumb_url = get_post_meta(
174
+ $post_id,
175
  $this->admin_options['tools']['thumbnail']['field'],
176
  true
177
  );
185
  $thumb_url = null;
186
  }
187
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
  // Get Post Thumbnail
190
  else {
191
  if (
192
  current_theme_supports('post-thumbnails')
193
+ && has_post_thumbnail($post_id)
194
  ) {
195
  // Find corresponding image size
196
  $stock_size = null;
213
  $stock_size = $size;
214
  }
215
 
216
+ /**
217
+ * Filters CSS classes assigned to the thumbnail
218
+ *
219
+ * @since 5.0.0
220
+ * @param array CSS classes
221
+ * @param int The post ID
222
+ * @return array The new CSS classes
223
+ */
224
+ $classes = apply_filters(
225
+ 'wpp_thumbnail_class_attribute',
226
+ $classes,
227
+ $post_id
228
+ );
229
+
230
  $featured_image = get_the_post_thumbnail(
231
+ $post_id,
232
  $stock_size
233
  );
234
 
249
 
250
  if ( 'custom_field' == $source && $this->admin_options['tools']['thumbnail']['resize'] ) {
251
  $thumb_url = get_post_meta(
252
+ $post_id,
253
  $this->admin_options['tools']['thumbnail']['field'],
254
  true
255
  );
266
  }
267
 
268
  if ( $thumb_url && $this->is_image_url($thumb_url) ) {
269
+ $file_path = $this->url_to_path($thumb_url, $post_id);
270
  }
271
  } else {
272
+ $file_meta = $this->get_file_meta($post_id, $source);
273
 
274
  if ( is_array($file_meta) && isset($file_meta['path']) ) {
275
  $alt = isset($file_meta['alt']) ? $file_meta['alt'] : '';
290
 
291
  if ( ! $thumb_url ) {
292
  $classes[] = 'wpp_def_no_src';
293
+ $thumb_url = $this->get_default_url($post_id);
294
  }
295
 
296
+ /**
297
+ * Filters CSS classes assigned to the thumbnail
298
+ *
299
+ * @since 5.0.0
300
+ * @param array CSS classes
301
+ * @param int The post ID
302
+ * @return array The new CSS classes
303
+ */
304
+ $classes = apply_filters(
305
+ 'wpp_thumbnail_class_attribute',
306
+ $classes,
307
+ $post_id
308
+ );
309
+
310
+ /**
311
+ * Filters ALT attribute assigned to the thumbnail
312
+ *
313
+ * @since 5.0.0
314
+ * @param string Original ALT attribute
315
+ * @param int The post ID
316
+ * @return string The new ALT attribute
317
+ */
318
+ $alt = apply_filters(
319
+ 'wpp_thumbnail_alt_attribute',
320
+ $this->get_alt_attribute($post_id, $source),
321
+ $post_id
322
+ );
323
+
324
  return $this->render(
325
  $thumb_url,
326
  $size,
679
  }
680
 
681
  /**
682
+ * Creates thumbnails.
683
  *
684
  * @since 3.0.0
685
  * @access private
693
  {
694
  $image = wp_get_image_editor($path);
695
 
696
+ // valid image, create thumbnails
697
+ if ( ! is_wp_error($image) ) {
698
+ $original_size = $image->get_size();
699
+ $sizes = [
700
+ '1x' => $size
701
+ ];
702
+ $thumbnail = '';
703
+
704
+ /**
705
+ * Hook to enable/disable retina support.
706
+ * @since 5.3.0
707
+ */
708
+ $retina_support = apply_filters('wpp_retina_support', true);
709
+
710
+ if ( $retina_support ) {
711
+ // Calculate thumbnail sizes
712
+ foreach( $this->descriptors as $descriptor ) {
713
+ $new_size_width = $descriptor * $size[0];
714
+ $new_size_height = $descriptor * $size[1];
715
+
716
+ if (
717
+ $new_size_width <= $original_size['width']
718
+ && $new_size_height <= $original_size['height']
719
+ ) {
720
+ $sizes[$descriptor . 'x'] = [$new_size_width, $new_size_height];
721
+ }
722
+ }
723
+ }
724
+
725
+ $path_parts = null;
726
+
727
+ // Generate thumbnails
728
+ foreach( $sizes as $d => $s ) {
729
+ if ( '1x' == $d ) {
730
+ $thumbnail = $this->generate_thumbnail($path, $filename, $s, $crop);
731
+
732
+ // Image could not be generated, let's bail early.
733
+ if ( ! $thumbnail )
734
+ break;
735
+ } else {
736
+ if ( ! $path_parts )
737
+ $path_parts = pathinfo($filename);
738
+
739
+ $filename_with_descriptor = $path_parts['filename'] . "@{$d}." . $path_parts['extension'];
740
+ $this->generate_thumbnail($path, $filename_with_descriptor, $s, $crop);
741
+ }
742
+ }
743
+
744
+ return $thumbnail;
745
+ }
746
+
747
+ return false;
748
+ }
749
+
750
+ /**
751
+ * Creates image.
752
+ *
753
+ * @since 5.3.0
754
+ * @access private
755
+ * @param string $path Image path
756
+ * @param string $filename Image filename
757
+ * @param array $size Image size
758
+ * @param bool $crop Whether to crop the image or not
759
+ * @return string|bool Image URL on success, false on error
760
+ */
761
+ private function generate_thumbnail($path, $filename, $size, $crop = true)
762
+ {
763
+ $image = wp_get_image_editor($path);
764
+
765
  // valid image, create thumbnail
766
  if ( ! is_wp_error($image) ) {
767
  /**
785
  return false;
786
  }
787
 
788
+ /**
789
+ * Generates srcset attribute for this image.
790
+ *
791
+ * @since 5.3.0
792
+ * @param string $src
793
+ * @return string
794
+ */
795
+ private function get_srcset($src)
796
+ {
797
+ /**
798
+ * Hook to enable/disable retina support.
799
+ * @since 5.3.0
800
+ */
801
+ $retina_support = apply_filters('wpp_retina_support', true);
802
+
803
+ if ( ! $retina_support )
804
+ return '';
805
+
806
+ $path_parts = pathinfo($src);
807
+ $srcset = [$src];
808
+
809
+ foreach( $this->descriptors as $descriptor ) {
810
+ $d = "{$descriptor}x";
811
+ $filename = $path_parts['filename'] . "@{$d}." . $path_parts['extension'];
812
+
813
+ if ( @file_exists(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename) ) {
814
+ $srcset[] = $path_parts['dirname'] . '/' . $filename . ' ' . $d;
815
+ }
816
+ }
817
+
818
+ return ( count($srcset) > 1 ) ? ' srcset="' . implode(', ', $srcset) . '" ' : '';
819
+ }
820
+
821
  /**
822
  * Render image tag.
823
  *
838
  $img_tag = '<!-- ' . $error . ' --> ';
839
  }
840
 
841
+ $srcset = $this->get_srcset($src);
842
+ $src = 'src="' . esc_url(is_ssl() ? str_ireplace("http://", "https://", $src) : $src) . '"' . $srcset;
843
  $lazyload = ( $this->admin_options['tools']['thumbnail']['lazyload'] ) ? ' loading="lazy"' : '';
844
 
845
  $img_tag .= '<img ' . $src . ' width="' . $size[0] . '" height="' . $size[1] . '" alt="' . esc_attr($alt) . '" class="' . esc_attr($class) . '"' . $lazyload . ' />';
919
  */
920
  private function is_image_url($url)
921
  {
922
+ $path = parse_url($url, PHP_URL_PATH);
923
+ $encoded_path = array_map('urlencode', explode('/', $path));
924
+ $parse_url = str_replace($path, implode('/', $encoded_path), $url);
925
+
926
+ if ( ! filter_var($parse_url, FILTER_VALIDATE_URL) )
927
  return false;
928
 
929
  // sanitize URL, just in case
src/Moment/CustomFormats/MomentJs.php DELETED
@@ -1,152 +0,0 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts\Moment\CustomFormats;
4
-
5
- use Moment\FormatsInterface;
6
-
7
- /**
8
- * Class MomentJs
9
- * @package Moment\CustomFormats
10
- */
11
- class MomentJs implements FormatsInterface
12
- {
13
- /**
14
- * @var array
15
- */
16
- protected $tokens = array(
17
- "M" => "n", // 1 2 ... 11 12
18
- "Mo" => "nS", // month: 1st 2nd ... 11th 12th
19
- "MM" => "m", // 01 02 ... 11 12
20
- "MMM" => "M", // Jan Feb ... Nov Dec
21
- "MMMM" => "F", // January February ... November December
22
- "D" => "j", // 1 2 ... 30 30
23
- "Do" => "jS", // day: 1st 2nd ... 30th 31st
24
- "DD" => "d", // 01 02 ... 30 31
25
- "DDD" => "z", // 1 2 ... 364 365
26
- "DDDo" => "zS", // day of year: 1st 2nd ... 364th 365th
27
- "DDDD" => "zS", // day of year: 1st 2nd ... 364th 365th
28
- "d" => "w", // 0 1 ... 5 6
29
- "do" => "wS", // day of week: 0th 1st ... 5th 6th
30
- "dd" => "D", // ***Su Mo ... Fr Sa
31
- "ddd" => "D", // Sun Mon ... Fri Sat
32
- "dddd" => "l", // Sunday Monday ... Friday Saturday
33
- "e" => "w", // 0 1 ... 5 6
34
- "E" => "N", // 1 2 ... 6 7
35
- "w" => "W", // 1 2 ... 52 53
36
- "wo" => "WS", // week of year: 1st 2nd ... 52nd 53rd
37
- "ww" => "W", // ***01 02 ... 52 53
38
- "W" => "W", // 1 2 ... 52 53
39
- "Wo" => "WS", // week of year: 1st 2nd ... 52nd 53rd
40
- "WW" => "W", // ***01 02 ... 52 53
41
- "YY" => "y", // 70 71 ... 29 30
42
- "YYYY" => "Y", // 1970 1971 ... 2029 2030
43
- "gg" => "o", // 70 71 ... 29 30
44
- "gggg" => "o", // ***1970 1971 ... 2029 2030
45
- "GG" => "o", // 70 71 ... 29 30
46
- "GGGG" => "o", // ***1970 1971 ... 2029 2030
47
- "A" => "A", // AM PM
48
- "a" => "a", // am pm
49
- "H" => "G", // 0 1 ... 22 23
50
- "HH" => "H", // 00 01 ... 22 23
51
- "h" => "g", // 1 2 ... 11 12
52
- "hh" => "h", // 01 02 ... 11 12
53
- "m" => "i", // 0 1 ... 58 59
54
- "mm" => "i", // ***00 01 ... 58 59
55
- "s" => "s", // 0 1 ... 58 59
56
- "ss" => "s", // ***00 01 ... 58 59
57
- "S" => "", // 0 1 ... 8 9
58
- "SS" => "", // 0 1 ... 98 99
59
- "SSS" => "", // 0 1 ... 998 999
60
- "z or zz" => "T", // EST CST ... MST PST 
61
- "Z" => "P", // -07:00 -06:00 ... +06:00 +07:00
62
- "ZZ" => "O", // -0700 -0600 ... +0600 +0700
63
- "X" => "U", // 1360013296
64
- "LTS" => "g:i:s A", // 8:30:15 PM
65
- "LT" => "g:i A", // 8:30 PM
66
- "L" => "m/d/Y", // 09/04/1986
67
- "l" => "n/j/Y", // 9/4/1986
68
- "LL" => "F jS Y", // September 4th 1986
69
- "ll" => "M j Y", // Sep 4 1986
70
- "LLL" => "F jS Y g:i A", // September 4th 1986 8:30 PM
71
- "lll" => "M j Y g:i A", // Sep 4 1986 8:30 PM
72
- "LLLL" => "l, F jS Y g:i A", // Thursday, September 4th 1986 8:30 PM
73
- "llll" => "D, M j Y g:i A", // Thu, Sep 4 1986 8:30 PM
74
- );
75
-
76
- /**
77
- * @param $format
78
- *
79
- * @return string
80
- */
81
- public function format($format)
82
- {
83
- return $this->momentJsToPhp($format);
84
- }
85
-
86
- /**
87
- * @return array
88
- */
89
- public function getTokens()
90
- {
91
- return (array)$this->tokens;
92
- }
93
-
94
- /**
95
- * @param array $options
96
- *
97
- * @return MomentJs
98
- */
99
- public function setTokens(array $options)
100
- {
101
- $this->tokens = array_merge($this->tokens, $options);
102
-
103
- return $this;
104
- }
105
-
106
- /**
107
- * @param String $format
108
- *
109
- * @return string
110
- */
111
- protected function momentJsToPhp($format)
112
- {
113
- $tokens = $this->getTokens();
114
-
115
- // find all tokens from string, using regular expression
116
- $regExp = "/(\[[^\[]*\])|(\\\\)?(LTS?|LL?L?L?|l{1,4}|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/";
117
- $matches = array();
118
- preg_match_all($regExp, $format, $matches);
119
-
120
- // if there is no match found then return the string as it is
121
- // TODO: might return escaped string
122
- if (empty($matches) || is_array($matches) === false)
123
- {
124
- return $format;
125
- }
126
-
127
- // to match with extracted tokens
128
- $momentTokens = array_keys($tokens);
129
- $phpMatches = array();
130
-
131
- // ----------------------------------
132
-
133
- foreach ($matches[0] as $id => $match)
134
- {
135
- // if there is a matching php token in token list
136
- if (in_array($match, $momentTokens))
137
- {
138
- // use the php token instead
139
- $string = $tokens[$match];
140
- }
141
- else
142
- {
143
- $string = $match;
144
- }
145
-
146
- $phpMatches[$id] = $string;
147
- }
148
-
149
- // join and return php specific tokens
150
- return implode("", $phpMatches);
151
- }
152
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/FormatsInterface.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts\Moment;
4
-
5
- /**
6
- * Interface FormatsInterface
7
- * @package Moment
8
- */
9
- interface FormatsInterface
10
- {
11
- /**
12
- * @param string $format
13
- *
14
- * @return FormatsInterface
15
- */
16
- public function format($format);
17
-
18
- /**
19
- * @param array $customFormats
20
- *
21
- * @return FormatsInterface
22
- */
23
- public function setTokens(array $customFormats);
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/LICENSE.md DELETED
@@ -1,21 +0,0 @@
1
- Moment.php is freely distributable under the terms of the MIT license.
2
-
3
- Copyright (c) 2074 Tino Ehrich
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/ar_TN.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- // locale: arabic (tn)
4
- // author: Tarek Morgéne https://www.satoripop.com/
5
-
6
- return array(
7
- "months" => explode('_', 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'),
8
- "monthsShort" => explode('_', 'جانفي_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'),
9
- "weekdays" => explode('_', 'الاثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت_الأحد'),
10
- "weekdaysShort" => explode('_', 'أحد_اثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'),
11
- "calendar" => array(
12
- "sameDay" => '[اليوم]',
13
- "nextDay" => '[غدا ]',
14
- "lastDay" => '[أمس ]',
15
- "lastWeek" => 'l [الماضي]',
16
- "sameElse" => 'l',
17
- "withTime" => '[على الساعة] H:i',
18
- "default" => 'd/m/Y',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'في %s',
22
- "past" => 'منذ %s',
23
- "s" => 'ثوان',
24
- "ss" => '%d ثانية',
25
- "m" => 'دقيقة',
26
- "mm" => '%d دقائق',
27
- "h" => 'ساعة',
28
- "hh" => '%d ساعات',
29
- "d" => 'يوم',
30
- "dd" => '%d أيام',
31
- "M" => 'شهر',
32
- "MM" => '%d أشهر',
33
- "y" => 'سنة',
34
- "yy" => '%d سنوات',
35
- ),
36
- "ordinal" => function ($number)
37
- {
38
- return $number . ($number === 1 ? '[er]' : '');
39
- },
40
- "week" => array(
41
- "dow" => 1, // Monday is the first day of the week.
42
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
43
- ),
44
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/ca_ES.php DELETED
@@ -1,65 +0,0 @@
1
- <?php
2
-
3
- // locale: Catalan (ca_ES)
4
- // author: CROWD Studio https://github.com/crowd-studio
5
-
6
- use Moment\Moment;
7
-
8
- return array(
9
- "months" => explode('_', 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'),
10
- "monthsShort" => explode('_', 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'),
11
- "weekdays" => explode('_', 'dilluns_dimarts_dimecres_dijous_divendres_dissabte_diumenge'),
12
- "weekdaysShort" => explode('_', 'dl._dt._dc._dj._dv._ds._dg.'),
13
- "calendar" => array(
14
- "sameDay" => '[avui]',
15
- "nextDay" => '[demà]',
16
- "lastDay" => '[ahir]',
17
- "lastWeek" => '[el] l',
18
- "sameElse" => 'l',
19
- "withTime" => function (Moment $moment) { return '[a' . ($moment->getHour() != 1 ? ' les ' : ' l\'') . ']G.i [h]'; },
20
- "default" => 'd/m/Y',
21
- ),
22
- "relativeTime" => array(
23
- "future" => 'en %s',
24
- "past" => 'fa %s',
25
- "s" => 'uns segons',
26
- "ss" => '%d segons',
27
- "m" => 'un minut',
28
- "mm" => '%d minuts',
29
- "h" => 'una hora',
30
- "hh" => '%d hores',
31
- "d" => 'un dia',
32
- "dd" => '%d dies',
33
- "M" => 'un mes',
34
- "MM" => '%d mesos',
35
- "y" => 'un any',
36
- "yy" => '%d anys',
37
- ),
38
- "ordinal" => function ($number)
39
- {
40
-
41
- switch ($number) {
42
- case 1:
43
- $output = 'r';
44
- break;
45
- case 2:
46
- $output = 'n';
47
- break;
48
- case 3:
49
- $output = 'r';
50
- break;
51
- case 4:
52
- $output = 't';
53
- break;
54
- default:
55
- $output = 'è';
56
- break;
57
- }
58
-
59
- return $number . '[' . $output . ']';
60
- },
61
- "week" => array(
62
- "dow" => 1, // Monday is the first day of the week.
63
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
64
- ),
65
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/cs_CZ.php DELETED
@@ -1,107 +0,0 @@
1
- <?php
2
-
3
- // locale: Czech (Czech Republic) (cs_CZ)
4
- // author: Jan Ptacek https://github.com/ptica
5
-
6
- use Moment\Moment;
7
-
8
- /**
9
- * @param string $direction
10
- * @param string $trueString
11
- * @param string $falseString
12
- *
13
- * @return string
14
- */
15
- $ifPast = function ($direction, $trueString, $falseString)
16
- {
17
- return $direction === 'past' ? $trueString : $falseString;
18
- };
19
-
20
- /**
21
- * @param int $count
22
- * @param int $countSmallerThan
23
- * @param string $trueString
24
- * @param string $falseString
25
- *
26
- * @return string
27
- */
28
- $ifCountSmaller = function ($count, $countSmallerThan, $trueString, $falseString)
29
- {
30
- return $count < $countSmallerThan ? $trueString : $falseString;
31
- };
32
-
33
- return array(
34
- "months" => explode('_', 'ledna_února_března_dubna_května_června_července_srpna_září_října_listopadu_prosince'),
35
- "monthsShort" => explode('_', 'Led_Úno_Bře_Dub_Kvě_Čer_Čvc_Srp_Zář_Říj_Lis_Pro'),
36
- "weekdays" => explode('_', 'pondělí_úterý_středa_čtvrtek_pátek_sobota_neděle'),
37
- "weekdaysShort" => explode('_', 'po_út_st_čt_pá_so_ne'),
38
- "calendar" => array(
39
- "sameDay" => '[dnes]',
40
- "nextDay" => '[zítra]',
41
- "lastDay" => '[včera]',
42
- "lastWeek" => '[minulý] l',
43
- "sameElse" => 'l',
44
- "withTime" => '[v] H:i',
45
- "default" => 'd.m.Y',
46
- ),
47
- "relativeTime" => array(
48
- "future" => 'za %s',
49
- "past" => 'před %s',
50
- "s" => function ($count, $direction, Moment $m) use ($ifPast)
51
- {
52
- return $ifPast($direction, 'okamžikem', 'okamžik');
53
- },
54
- "ss" => function ($count, $direction, Moment $m) use ($ifPast)
55
- {
56
- return $ifPast($direction, 'okamžikem', 'okamžik');
57
- },
58
- "m" => function ($count, $direction, Moment $m) use ($ifPast)
59
- {
60
- return $ifPast($direction, 'minutou', 'minutu');
61
- },
62
- "mm" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller)
63
- {
64
- return $ifPast($direction, '%d minutami', $ifCountSmaller($count, 5, '%d minuty', '%d minut'));
65
- },
66
- "h" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller)
67
- {
68
- return $ifPast($direction, 'hodinou', 'hodinu');
69
- },
70
- "hh" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller)
71
- {
72
- return $ifPast($direction, '%d hodinami', $ifCountSmaller($count, 5, '%d hodiny', '%d hodin'));
73
- },
74
- "d" => function ($count, $direction, Moment $m) use ($ifPast)
75
- {
76
- return $ifPast($direction, 'dnem', 'den');
77
- },
78
- "dd" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller)
79
- {
80
- return $ifPast($direction, '%d dny', $ifCountSmaller($count, 5, '%d dny', '%d dnů'));
81
- },
82
- "M" => function ($count, $direction, Moment $m) use ($ifPast)
83
- {
84
- return $ifPast($direction, 'měsícem', 'měsíc');
85
- },
86
- "MM" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller)
87
- {
88
- return $ifPast($direction, '%d měsíci', $ifCountSmaller($count, 5, '%d měsíce', '%d měsíců'));
89
- },
90
- "y" => function ($count, $direction, Moment $m) use ($ifPast)
91
- {
92
- return $ifPast($direction, 'rokem', 'rok');
93
- },
94
- "yy" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller)
95
- {
96
- return $ifPast($direction, $ifCountSmaller($count, 5, '%d roky', '%d lety'), $ifCountSmaller($count, 5, '%d roky', '%d let'));
97
- },
98
- ),
99
- "ordinal" => function ($number)
100
- {
101
- return $number . '.';
102
- },
103
- "week" => array(
104
- "dow" => 1, // Monday is the first day of the week.
105
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
106
- ),
107
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/da_DK.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
-
3
- // locale: danish (da-dk)
4
- // author: Morten Wulff https://github.com/wulff
5
-
6
- return array(
7
- "months" => explode('_', 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'),
8
- "monthsShort" => explode('_', 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'),
9
- "weekdays" => explode('_', 'mandag_tirsdag_onsdag_torsdag_fredag_lørdag_søndag'),
10
- "weekdaysShort" => explode('_', 'man_tir_ons_tor_fre_lør_søn'),
11
- "calendar" => array(
12
- "sameDay" => '[I dag]',
13
- "nextDay" => '[I morgen]',
14
- "lastDay" => '[I går]',
15
- "lastWeek" => '[Sidste] l',
16
- "sameElse" => 'l',
17
- "withTime" => '[kl] H:i',
18
- "default" => 'd/m/Y',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'om %s',
22
- "past" => '%s siden',
23
- "s" => 'få sekunder',
24
- "ss" => '%d sekunder',
25
- "m" => 'et minut',
26
- "mm" => '%d minutter',
27
- "h" => 'en time',
28
- "hh" => '%d timer',
29
- "d" => 'en dag',
30
- "dd" => '%d dage',
31
- "M" => 'en måned',
32
- "MM" => '%d måneder',
33
- "y" => 'et år',
34
- "yy" => '%d år',
35
- ),
36
- "ordinal" => function ($number) {
37
- return $number . '.';
38
- },
39
- "week" => array(
40
- "dow" => 1, // Monday is the first day of the week.
41
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
42
- ),
43
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/de_DE.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- // locale: German (Germany) (de_DE)
4
- // author: Tino Ehrich (tino@bigpun.me)
5
-
6
- return array(
7
- "months" => explode('_', 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'),
8
- "monthsShort" => explode('_', 'Jan_Feb_Mär_Apr_Mai_Jun_Jul_Aug_Sep_Okt_Nov_Dez'),
9
- "weekdays" => explode('_', 'Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag_Sonntag'),
10
- "weekdaysShort" => explode('_', 'Mo_Di_Mi_Do_Fr_Sa_So'),
11
- "calendar" => array(
12
- "sameDay" => '[Heute]',
13
- "nextDay" => '[Morgen]',
14
- "lastDay" => '[Gestern]',
15
- "lastWeek" => '[Letzten] l',
16
- "sameElse" => 'l',
17
- "withTime" => '[um] G:i [Uhr]',
18
- "default" => 'd.m.Y',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'in %s',
22
- "past" => 'vor %s',
23
- "s" => 'ein paar Sekunden',
24
- "ss" => '%d Sekunden',
25
- "m" => 'einer Minute',
26
- "mm" => '%d Minuten',
27
- "h" => 'einer Stunde',
28
- "hh" => '%d Stunden',
29
- "d" => 'einem Tag',
30
- "dd" => '%d Tagen',
31
- "M" => 'einem Monat',
32
- "MM" => '%d Monaten',
33
- "y" => 'einem Jahr',
34
- "yy" => '%d Jahren',
35
- ),
36
- "ordinal" => function ($number)
37
- {
38
- return $number . '.';
39
- },
40
- "week" => array(
41
- "dow" => 1, // Monday is the first day of the week.
42
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
43
- ),
44
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/en_GB.php DELETED
@@ -1,65 +0,0 @@
1
- <?php
2
-
3
- // locale: great britain english (en-gb)
4
- // author: Chris Gedrim https://github.com/chrisgedrim
5
-
6
- return array(
7
- "months" => explode('_', 'January_February_March_April_May_June_July_August_September_October_November_December'),
8
- "monthsNominative" => explode('_', 'January_February_March_April_May_June_July_August_September_October_November_December'),
9
- "monthsShort" => explode('_', 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'),
10
- "weekdays" => explode('_', 'Monday_Tuesday_Wednesday_Thursday_Friday_Saturday_Sunday'),
11
- "weekdaysShort" => explode('_', 'Mon_Tue_Wed_Thu_Fri_Sat_Sun'),
12
- "calendar" => array(
13
- "sameDay" => '[Today]',
14
- "nextDay" => '[Tomorrow]',
15
- "lastDay" => '[Yesterday]',
16
- "lastWeek" => '[Last] l',
17
- "sameElse" => 'l',
18
- "withTime" => '[at] H:i',
19
- "default" => 'd/m/Y',
20
- ),
21
- "relativeTime" => array(
22
- "future" => 'in %s',
23
- "past" => '%s ago',
24
- "s" => 'a few seconds',
25
- "ss" => '%d seconds',
26
- "m" => 'a minute',
27
- "mm" => '%d minutes',
28
- "h" => 'an hour',
29
- "hh" => '%d hours',
30
- "d" => 'a day',
31
- "dd" => '%d days',
32
- "M" => 'a month',
33
- "MM" => '%d months',
34
- "y" => 'a year',
35
- "yy" => '%d years',
36
- ),
37
- "ordinal" => function ($number)
38
- {
39
- $n = $number % 100;
40
- $ends = array('th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th');
41
-
42
- if ($n >= 11 && $n <= 13)
43
- {
44
- return $number . '[th]';
45
- }
46
-
47
- return $number . '[' . $ends[$number % 10] . ']';
48
- },
49
- "week" => array(
50
- "dow" => 1, // Monday is the first day of the week.
51
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
52
- ),
53
- "customFormats" => array(
54
- "LT" => "G:i", // 22:00
55
- "LTS" => "G:i:s", // 22:00:00
56
- "L" => "d/m/Y", // 12/06/2010
57
- "l" => "j/n/Y", // 12/6/2010
58
- "LL" => "j F Y", // 12 June 2010
59
- "ll" => "j M Y", // 12 Jun 2010
60
- "LLL" => "j F Y G:i", // 12 June 2010 22:00
61
- "lll" => "j M Y G:i", // 12 Jun 2010 22:00
62
- "LLLL" => "l, j F F Y G:i", // Saturday, 12 June June 2010 22:00
63
- "llll" => "D, j M Y G:i", // Sat, 12 Jun 2010 22:00
64
- ),
65
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/en_US.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
-
3
- // locale: american english (en_US)
4
-
5
- $locale = require __DIR__ . '/en_GB.php';
6
- $locale['calendar']['withTime'] = '[at] h:i A';
7
- $locale['calendar']['default'] = 'm/d/Y';
8
- $locale['week']['dow'] = 7;
9
- $locale["customFormats"] = array(
10
- "LT" => "g:i A", // 8:30 PM
11
- "L" => "m/d/Y", // 09/04/1986
12
- "l" => "n/j/Y", // 9/4/1986
13
- "LL" => "F j, Y", // September 4, 1986
14
- "ll" => "M j, Y", // Sep 4, 1986
15
- "LLL" => "F j, Y g:i A", // September 4, 1986 8:30 PM
16
- "lll" => "M j, Y g:i A", // Sep 4, 1986 8:30 PM
17
- "LLLL" => "l, F j, Y g:i A", // Thursday, September 4, 1986 8:30 PM
18
- "llll" => "D, M j, Y g:i A", // Thu, Sep 4, 1986 8:30 PM
19
- );
20
-
21
- return $locale;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/es_ES.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
-
3
- // locale: spanish (es)
4
- // author: Julio Napurí https://github.com/julionc
5
-
6
- use Moment\Moment;
7
-
8
- return array(
9
- "months" => explode('_', 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'),
10
- "monthsShort" => explode('_', 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'),
11
- "weekdays" => explode('_', 'lunes_martes_miércoles_jueves_viernes_sábado_domingo'),
12
- "weekdaysShort" => explode('_', 'lun._mar._mié._jue._vie._sáb._dom.'),
13
- "calendar" => array(
14
- "sameDay" => '[hoy]',
15
- "nextDay" => '[mañana]',
16
- "lastDay" => '[ayer]',
17
- "lastWeek" => '[el] l',
18
- "sameElse" => 'l',
19
- "withTime" => function (Moment $moment) { return '[a la' . ($moment->getHour() != 1 ? 's' : null) . '] G:i [h]'; },
20
- "default" => 'd/m/Y',
21
- ),
22
- "relativeTime" => array(
23
- "future" => 'en %s',
24
- "past" => 'hace %s',
25
- "s" => 'unos segundos',
26
- "ss" => '%d segundos',
27
- "m" => 'un minuto',
28
- "mm" => '%d minutos',
29
- "h" => 'una hora',
30
- "hh" => '%d horas',
31
- "d" => 'un día',
32
- "dd" => '%d días',
33
- "M" => 'un mes',
34
- "MM" => '%d meses',
35
- "y" => 'un año',
36
- "yy" => '%d años',
37
- ),
38
- "ordinal" => function ($number)
39
- {
40
- return $number . 'º';
41
- },
42
- "week" => array(
43
- "dow" => 1, // Monday is the first day of the week.
44
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
45
- ),
46
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/fr_FR.php DELETED
@@ -1,55 +0,0 @@
1
- <?php
2
-
3
- // locale: french (fr)
4
- // author: John Fischer https://github.com/jfroffice
5
-
6
- return array(
7
- "months" => explode('_', 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'),
8
- "monthsShort" => explode('_', 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'),
9
- "weekdays" => explode('_', 'lundi_mardi_mercredi_jeudi_vendredi_samedi_dimanche'),
10
- "weekdaysShort" => explode('_', 'lun._mar._mer._jeu._ven._sam._dim.'),
11
- "calendar" => array(
12
- "sameDay" => '[Aujourd\'hui]',
13
- "nextDay" => '[Demain]',
14
- "lastDay" => '[Hier]',
15
- "lastWeek" => 'l [dernier]',
16
- "sameElse" => 'l',
17
- "withTime" => '[à] G [h] i',
18
- "default" => 'd/m/Y',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'dans %s',
22
- "past" => 'il y a %s',
23
- "s" => 'quelques secondes',
24
- "ss" => '%d secondes',
25
- "m" => 'une minute',
26
- "mm" => '%d minutes',
27
- "h" => 'une heure',
28
- "hh" => '%d heures',
29
- "d" => 'un jour',
30
- "dd" => '%d jours',
31
- "M" => 'un mois',
32
- "MM" => '%d mois',
33
- "y" => 'un an',
34
- "yy" => '%d ans',
35
- ),
36
- "ordinal" => function ($number)
37
- {
38
- return $number . ($number === 1 || $number === '1' ? '[er]' : '');
39
- },
40
- "week" => array(
41
- "dow" => 1, // Monday is the first day of the week.
42
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
43
- ),
44
- "customFormats" => array(
45
- "LT" => "G:i", // 20:30
46
- "L" => "d/m/Y", // 04/09/1986
47
- "l" => "j/n/Y", // 4/9/1986
48
- "LL" => "jS F Y", // 4 Septembre 1986
49
- "ll" => "j M Y", // 4 Sep 1986
50
- "LLL" => "jS F Y G:i", // 4 Septembre 1986 20:30
51
- "lll" => "j M Y G:i", // 4 Sep 1986 20:30
52
- "LLLL" => "l, jS F Y G:i", // Jeudi, 4 Septembre 1986 20:30
53
- "llll" => "D, j M Y G:i", // Jeu, 4 Sep 1986 20:30
54
- ),
55
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/hu_HU.php DELETED
@@ -1,72 +0,0 @@
1
- <?php
2
-
3
- // locale: hungarian (hu)
4
- // author: David Joseph Guzsik https://github.com/seinopsys
5
-
6
- return array(
7
- "months" => explode('_', 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'),
8
-
9
- "monthsShort" => explode('_', 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'),
10
- "weekdays" => explode('_', 'hétfő_kedd_szerda_csütörtök_péntek_szombat_vasárnap'),
11
- "weekdaysShort" => explode('_', 'hét_kedd_sze_csüt_pén_szo_vas'),
12
- "calendar" => array(
13
- "sameDay" => '[ma] l[-kor]',
14
- "nextDay" => '[holnap] l[-kor]',
15
- "lastDay" => '[tegnap] l[-kor]',
16
- "lastWeek" => function($n, $dir, \Moment\Moment $Moment){
17
- $weekEndings = explode('_','vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton');
18
- return '[múlt] [' . $weekEndings[$Moment->getDay()] . '] l[-kor]';
19
- },
20
- "sameElse" => 'l',
21
- "withTime" => 'H:i[-kor]',
22
- "default" => 'Y.m.d.',
23
- ),
24
- "relativeTime" => array(
25
- "future" => '%s múlva',
26
- "past" => '%s',
27
- "s" => function($n, $dir){
28
- return ($dir === 'future') ? 'néhány másodperc' : 'néhány másodperce';
29
- },
30
- "ss" => function($n, $dir){
31
- return "$n " . ($dir === 'future' ? 'másodperc' : 'másodperce');
32
- },
33
- "m" => function($n, $dir){
34
- return 'egy ' . ($dir === 'future' ? 'perc' : 'perce');
35
- },
36
- "mm" => function($n, $dir){
37
- return "$n " . ($dir === 'future' ? 'perc' : 'perce');
38
- },
39
- "h" => function($n, $dir){
40
- return 'egy ' . ($dir === 'future' ? 'óra' : 'órája');
41
- },
42
- "hh" => function($n, $dir){
43
- return "$n " . ($dir === 'future' ? 'óra' : 'órája');
44
- },
45
- "d" => function($n, $dir){
46
- return 'egy ' . ($dir === 'future' ? 'nap' : 'napja');
47
- },
48
- "dd" => function($n, $dir){
49
- return "$n " . ($dir === 'future' ? 'nap' : 'napja');
50
- },
51
- "M" => function($n, $dir){
52
- return 'egy' . ($dir === 'future' ? 'hónap' : 'hónapja');
53
- },
54
- "MM" => function($n, $dir){
55
- return "$n " . ($dir === 'future' ? 'hónap' : 'hónapja');
56
- },
57
- "y" => function($n, $dir){
58
- return 'egy' . ($dir === 'future' ? 'év' : 'éve');
59
- },
60
- "yy" => function($n, $dir){
61
- return "$n " . ($dir === 'future' ? 'év' : 'éve');
62
- },
63
- ),
64
- "ordinal" => function ($number)
65
- {
66
- return "$number.";
67
- },
68
- "week" => array(
69
- "dow" => 1, // Monday is the first day of the week.
70
- "doy" => 7 // The week that contains Jan 1st is the first week of the year.
71
- ),
72
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/id_ID.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
-
3
- // locale: Indonesian (Indonesia) (id-id)
4
- // author: Yuda Sukmana https://github.com/ydatech
5
-
6
- return array(
7
- "months" => explode('_', 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'),
8
- "monthsShort" => explode('_', 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agu_Sep_Okt_Nov_Des'),
9
- "weekdays" => explode('_', 'Senin_Selasa_Rabu_Kamis_Jum\'at_Sabtu_Minggu'),
10
- "weekdaysShort" => explode('_', 'Sen_Sel_Rab_Kam_Jum_Sab_Ming'),
11
- "calendar" => array(
12
- "sameDay" => '[Hari ini]',
13
- "nextDay" => '[Besok]',
14
- "lastDay" => '[Kemarin]',
15
- "lastWeek" => 'l [Kemarin]',
16
- "sameElse" => 'l',
17
- "withTime" => '[pukul] H:i',
18
- "default" => 'd/m/Y',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'dalam %s',
22
- "past" => '%s yang lalu',
23
- "s" => 'beberapa detik',
24
- "ss" => '%d detik',
25
- "m" => 'semenit',
26
- "mm" => '%d menit',
27
- "h" => 'satu jam',
28
- "hh" => '%d jam',
29
- "d" => 'satu hari',
30
- "dd" => '%d hari',
31
- "M" => 'satu bulan',
32
- "MM" => '%d bulan',
33
- "y" => 'satu tahun',
34
- "yy" => '%d tahun',
35
- ),
36
- "ordinal" => function ($number)
37
- {
38
-
39
- return $number;
40
- },
41
- "week" => array(
42
- "dow" => 1, // Monday is the first day of the week.
43
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
44
- ),
45
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/it_IT.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
-
3
- // locale: italia italiano (it_IT)
4
- // author: Marco Manfredini https://github.com/Manfre98
5
-
6
- use Moment\Moment;
7
-
8
- return array(
9
- "months" => explode('_', 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'),
10
- "monthsShort" => explode('_', 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'),
11
- "weekdays" => explode('_', 'lunedì_martedì_mercoledì_giovedì_venerdì_sabato_domenica'),
12
- "weekdaysShort" => explode('_', 'lun_mar_mer_gio_ven_sab_dom'),
13
- "calendar" => array(
14
- "sameDay" => '[Oggi]',
15
- "nextDay" => '[Domani]',
16
- "lastDay" => '[Ieri]',
17
- "lastWeek" => function (Moment $moment) {
18
- switch ($moment->getWeekday()) {
19
- case 7:
20
- return 'l [scorsa]';
21
- default:
22
- return 'l [scorso]';
23
- }
24
- },
25
- "sameElse" => 'l',
26
- "withTime" => function (Moment $moment) {
27
- switch ($moment->getHour()) {
28
- case 0:
29
- return '[a] G:i';
30
- case 1:
31
- return '[all\']G:i';
32
- default:
33
- return '[alle] G:i';
34
- }
35
- },
36
- "default" => 'd/m/Y',
37
- ),
38
- "relativeTime" => array(
39
- "future" => 'tra %s',
40
- "past" => '%s fa',
41
- "s" => 'alcuni secondi',
42
- "ss" => '%d secondi',
43
- "m" => 'un minuto',
44
- "mm" => '%d minuti',
45
- "h" => 'un\'ora',
46
- "hh" => '%d ore',
47
- "d" => 'un giorno',
48
- "dd" => '%d giorni',
49
- "M" => 'un mese',
50
- "MM" => '%d mesi',
51
- "y" => 'un anno',
52
- "yy" => '%d anni',
53
- ),
54
- "ordinal" => function ($number)
55
- {
56
- return $number . 'º';
57
- },
58
- "week" => array(
59
- "dow" => 1, // Monday is the first day of the week.
60
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
61
- ),
62
- "customFormats" => array(
63
- "LT" => "G:i", // 22:00
64
- "LTS" => "G:i:s", // 22:00:00
65
- "L" => "d/m/Y", // 12/06/2010
66
- "l" => "j/n/Y", // 12/6/2010
67
- "LL" => "j F Y", // 12 giugno 2010
68
- "ll" => "j M Y", // 12 giu 2010
69
- "LLL" => "j F Y, G:i", // 12 giugno 2010, 22:00
70
- "lll" => "j M Y, G:i", // 12 giu 2010, 22:00
71
- "LLLL" => "l j F Y, G:i", // sabato 12 giugno 2010, 22:00
72
- "llll" => "D j M Y, G:i", // sab 12 giu 2010, 22:00
73
- ),
74
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/ja_JP.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
- // locale: Japanese ( ja-jp )
3
- // author: Takumi https://github.com/takumi-dev
4
- return array(
5
- "months" => explode('_', '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'),
6
- "monthsShort" => explode('_', '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'),
7
- "weekdays" => explode('_', '月曜日_火曜日_水曜日_木曜日_金曜日_土曜日_日曜日'),
8
- "weekdaysShort" => explode('_', '月_火_水_木_金_土_日'),
9
- "calendar" => array(
10
- "sameDay" => '[今日]',
11
- "nextDay" => '[明日]',
12
- "lastDay" => '[昨日]',
13
- "lastWeek" => '[先週]l',
14
- "sameElse" => 'l',
15
- "withTime" => 'H時i分',
16
- "default" => 'Y年m月d日',
17
- ),
18
- "relativeTime" => array(
19
- "future" => '%s後',
20
- "past" => '%s前',
21
- "s" => '数秒',
22
- "ss" => '%d秒',
23
- "m" => '1分',
24
- "mm" => '%d分',
25
- "h" => '1時間',
26
- "hh" => '%d時間',
27
- "d" => '1日',
28
- "dd" => '%d日',
29
- "M" => '1ヶ月',
30
- "MM" => '%dヶ月',
31
- "y" => '1年',
32
- "yy" => '%d年',
33
- ),
34
- "ordinal" => function ($number)
35
- {
36
- $prefix = '第';
37
- return $prefix.$number;
38
- },
39
- "week" => array(
40
- "dow" => 1, // Monday is the first day of the week.
41
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
42
- ),
43
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/ko_KR.php DELETED
@@ -1,59 +0,0 @@
1
- <?php
2
- // locale: Korean
3
- // author: amouro https://github.com/amouro
4
- return array(
5
- "months" => explode('_', '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'),
6
- "monthsShort" => explode('_', '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'),
7
- "weekdays" => explode('_', '일요일_월요일_화요일_수요일_목요일_금요일_토요일'),
8
- "weekdaysShort" => explode('_', '일_월_화_수_목_금_토'),
9
- "weekdaysMin" => explode('_', '일_월_화_수_목_금_토'),
10
- "calendar" => array(
11
- "sameDay" => '[오늘] LT',
12
- "nextDay" => '[내일] LT',
13
- "lastDay" => '[어제] LT',
14
- "lastWeek" => '[지난주] dddd LT',
15
- "sameElse" => 'L',
16
- "withTime" => 'H:i',
17
- "default" => 'Y년 m월 d일',
18
- ),
19
- "relativeTime" => array(
20
- "future" => '%s 후',
21
- "past" => '%s 전',
22
- "s" => '몇 초',
23
- "ss" => '%d 초',
24
- "m" => '1 분',
25
- "mm" => '%d 분',
26
- "h" => '한 시간',
27
- "hh" => '%d 시간',
28
- "d" => '하루',
29
- "dd" => '%d 일',
30
- "M" => '한 달',
31
- "MM" => '%d 달',
32
- "y" => '일 년',
33
- "yy" => '%d 년',
34
- ),
35
- "ordinal" => function ($number, $token)
36
- {
37
- $symbol = null;
38
-
39
- switch ($token)
40
- {
41
- case 'd':
42
- case 'D':
43
- case 'DDD':
44
- $symbol = '일';
45
- case 'M':
46
- $symbol = '월';
47
- case 'w':
48
- case 'W':
49
- $symbol = '주';
50
- default:
51
- }
52
-
53
- return $number . $symbol;
54
- },
55
- "week" => array(
56
- "dow" => 1, // Monday is the first day of the week.
57
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
58
- ),
59
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/lv_LV.php DELETED
@@ -1,56 +0,0 @@
1
- <?php
2
-
3
- // locale: Latviešu (Latvian) (lv_LV)
4
- // author: Artjoms Nemiro https://github.com/LinMAD
5
-
6
- return array(
7
- 'months' => explode(
8
- '_',
9
- 'Janvārī_Februārī_Martā_Aprīlī_Maijā_Jūnijā_Jūlijā_Augustā_Septembrī_Oktobrī_Novembrī_Decembrī'
10
- ),
11
- 'monthsNominative' => explode(
12
- '_',
13
- 'Janvāris_Februāris_Marts_Aprīlis_Maijs_Jūnijs_Jūlijs_Augusts_Septembris_Oktobris_Novembris_Decembris'
14
- ),
15
- 'monthsShort' => explode(
16
- '_',
17
- 'Janv_Febr_Mar_Apr_Maijs_Jūn_Jūl_Aug_Sept_Okt_Nov_Dec'
18
- ),
19
- 'weekdays' => explode(
20
- '_',
21
- 'Pirmdiena_Otrdiena_Trešdiena_Ceturtdiena_Piektdiena_Sestdiena_Svētdiena'
22
- ),
23
- 'weekdaysShort' => explode('_', 'Pr_Ot_Tr_Ce_Pk_Se_Sv'),
24
- 'calendar' => array(
25
- 'sameDay' => '[Šodien]',
26
- 'nextDay' => '[Rītdien]',
27
- 'lastDay' => '[Vakardien]',
28
- 'lastWeek' => '[Pagājušā] l',
29
- 'sameElse' => 'l',
30
- 'withTime' => '[plkst.] H:i',
31
- 'default' => 'd.m.Y',
32
- ),
33
- 'relativeTime' => array(
34
- 'future' => 'pēc %s',
35
- 'past' => 'pirms %s',
36
- 's' => 'dažām sekundēm',
37
- 'ss' => '%d sekundēm',
38
- 'm' => 'minūtes',
39
- 'mm' => '%d minūtēm',
40
- 'h' => 'stundas',
41
- 'hh' => '%d stundām',
42
- 'd' => 'dienas',
43
- 'dd' => '%d dienām',
44
- 'M' => 'mēneša',
45
- 'MM' => '%d mēnešiem',
46
- 'y' => 'gada',
47
- 'yy' => '%d gadiem',
48
- ),
49
- 'ordinal' => function ($number) {
50
- return $number . '.';
51
- },
52
- 'week' => array(
53
- 'dow' => 1, // Monday is the first day of the week.
54
- 'doy' => 4 // The week that contains Jan 4th is the first week of the year.
55
- ),
56
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/nl_NL.php DELETED
@@ -1,57 +0,0 @@
1
- <?php
2
-
3
- // locale: Dutch (Netherlands, The) (nl_NL)
4
- // author: Peter Notenboom https://github.com/peternotenboom
5
-
6
- return array(
7
- "months" => explode('_', 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'),
8
- "monthsShort" => explode('_', 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'),
9
- "weekdays" => explode('_', 'maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag_zondag'),
10
- "weekdaysShort" => explode('_', 'ma_di_wo_do_vr_za_zo'),
11
- "calendar" => array(
12
- "sameDay" => '[Vandaag]',
13
- "nextDay" => '[Morgen]',
14
- "lastDay" => '[Gisteren]',
15
- "lastWeek" => '[Vorige] l',
16
- "sameElse" => 'l',
17
- "withTime" => '[om] H:i',
18
- "default" => 'd/m/Y',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'in %s',
22
- "past" => '%s geleden',
23
- "s" => 'een paar seconden',
24
- "ss" => '%d seconden',
25
- "m" => 'een minuut',
26
- "mm" => '%d minuten',
27
- "h" => 'een uur',
28
- "hh" => '%d uren',
29
- "d" => 'een dag',
30
- "dd" => '%d dagen',
31
- "M" => 'een maand',
32
- "MM" => '%d maanden',
33
- "y" => 'een jaar',
34
- "yy" => '%d jaren',
35
- ),
36
- "ordinal" => function ($number)
37
- {
38
- return $number; //Possible to add 'e': $m->format('WS'); // 11e. But that also breaks "11e Januari 2015"
39
- },
40
- "week" => array(
41
- "dow" => 1, // Monday is the first day of the week.
42
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
43
- ),
44
- "customFormats" => array(
45
- "LTS" => "G:i:s", // 20:30:15
46
- "LT" => "G:i", // 20:30
47
- "L" => "d/m/Y", // 04/09/1986
48
- "l" => "j/n/Y", // 4/9/1986
49
- "LL" => "jS F Y", // 4 September 1986
50
- "ll" => "j M Y", // 4 Sep 1986
51
- "LLL" => "jS F Y G:i", // 4 September 1986 20:30
52
- "lll" => "j M Y G:i", // 4 Sep 1986 20:30
53
- "LLLL" => "l jS F Y G:i", // Donderdag 4 September 1986 20:30
54
- "llll" => "D j M Y G:i", // Do 4 Sep 1986 20:30
55
- ),
56
-
57
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/no_NO.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
-
3
- // locale: norweigan (no-NO)
4
-
5
- return array(
6
- "months" => explode('_', 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'),
7
- "monthsShort" => explode('_', 'jan_feb_mars_apr_mai_jun_jul_aug_sep_okt_nov_des'),
8
- "weekdays" => explode('_', 'mandag_tirsdag_onsdag_torsdag_fredag_lørdag_søndag'),
9
- "weekdaysShort" => explode('_', 'man_tir_ons_tor_fre_lør_søn'),
10
- "calendar" => array(
11
- "sameDay" => '[I dag]',
12
- "nextDay" => '[I morgen]',
13
- "lastDay" => '[I går]',
14
- "lastWeek" => '[Sidste] l',
15
- "sameElse" => 'l',
16
- "withTime" => '[kl] H:i',
17
- "default" => 'd/m/Y',
18
- ),
19
- "relativeTime" => array(
20
- "future" => 'om %s',
21
- "past" => '%s siden',
22
- "s" => 'få sekunder',
23
- "ss" => '%d sekunder',
24
- "m" => 'ett minutt',
25
- "mm" => '%d minutter',
26
- "h" => 'en time',
27
- "hh" => '%d timer',
28
- "d" => 'en dag',
29
- "dd" => '%d dager',
30
- "M" => 'en måned',
31
- "MM" => '%d måneder',
32
- "y" => 'et år',
33
- "yy" => '%d år',
34
- ),
35
-
36
- "ordinal" => function ($number) {
37
- return $number . '.';
38
- },
39
- "week" => array(
40
- "dow" => 1, // Monday is the first day of the week.
41
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
42
- ),
43
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/oc_LNC.php DELETED
@@ -1,63 +0,0 @@
1
- <?php
2
-
3
- // locale: Occitan languedocian dialect (oc_lnc)
4
- // author: CROWD Studio https://github.com/crowd-studio
5
-
6
- return array(
7
- "months" => explode('_', 'genièr_febrièr_març_abril_mai_junh_julhet_agost_setembre_octobre_novembre_decembre'),
8
- "monthsShort" => explode('_', 'gen._feb._mar._abr._mai._jun._jul._ag._set._oct._nov._dec.'),
9
- "weekdays" => explode('_', 'dimenge_diluns_dimars_dimècres_dijòus_divendres_dissabte'),
10
- "weekdaysShort" => explode('_', 'dg._dl._dm._dc._dj._dv._ds.'),
11
- "calendar" => array(
12
- "sameDay" => '[uèi]',
13
- "nextDay" => '[deman]',
14
- "lastDay" => '[ièr]',
15
- "lastWeek" => 'l [passat]',
16
- "sameElse" => 'l',
17
- "withTime" => '[a] H[o]i',
18
- "default" => 'd/m/Y',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'dins %s',
22
- "past" => 'fa %s',
23
- "s" => 'unas segondas',
24
- "ss" => '%d segondas',
25
- "m" => 'una minuta',
26
- "mm" => '%d minutas',
27
- "h" => 'una ora',
28
- "hh" => '%d oras',
29
- "d" => 'un jorn',
30
- "dd" => '%d jorns',
31
- "M" => 'un mes',
32
- "MM" => '%d meses',
33
- "y" => 'un an',
34
- "yy" => '%d ans',
35
- ),
36
- "ordinal" => function ($number)
37
- {
38
- switch ($number)
39
- {
40
- case 1:
41
- $output = 'r';
42
- break;
43
- case 2:
44
- $output = 'n';
45
- break;
46
- case 3:
47
- $output = 'r';
48
- break;
49
- case 4:
50
- $output = 't';
51
- break;
52
- default:
53
- $output = 'è';
54
- break;
55
- }
56
-
57
- return $number . '[' . $output . ']';
58
- },
59
- "week" => array(
60
- "dow" => 1, // Monday is the first day of the week.
61
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
62
- ),
63
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/pl_PL.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
-
3
- // locale: Polski (Poland) (pl_PL)
4
- // author: Mateusz Błaszczyk https://github.com/Zaszczyk
5
-
6
- use Moment\Moment;
7
-
8
- $ifLastDigitIsSpecial = function ($count, $trueString, $falseString)
9
- {
10
- $specialDigits = array('2', '3', '4');
11
-
12
- return
13
- (in_array(mb_substr((string)$count, -1), $specialDigits) && $count > 20)
14
- || in_array((string)$count, $specialDigits)
15
- ? $trueString : $falseString;
16
- };
17
-
18
- $femaleWeekdays = array('3', '6', '7');
19
-
20
- return array(
21
- "months" => explode('_', 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'),
22
- "monthsNominative" => explode('_', 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'),
23
- "monthsShort" => explode('_', 'sty._lut._mar._kwi._maj_cze._lip._sie._wrz._paź._lis._gru.'),
24
- "weekdays" => explode('_', 'poniedziałek_wtorek_środa_czwartek_piątek_sobota_niedziela'),
25
- "weekdaysShort" => explode('_', 'pon._wt._śr._czw._pt._sob._niedz.'),
26
- "calendar" => array(
27
- "sameDay" => '[dzisiaj]',
28
- "nextDay" => '[jutro]',
29
- "lastDay" => '[wczoraj]',
30
- "lastWeek" => function (Moment $moment) use ($femaleWeekdays)
31
- {
32
- $pre = 'ostatni';
33
-
34
- if (in_array($moment->getWeekday(), $femaleWeekdays))
35
- {
36
- $pre = 'ostatnia';
37
- }
38
-
39
- return '[' . $pre . '] l';
40
- },
41
- "sameElse" => 'l',
42
- "withTime" => '[o] H:i',
43
- "default" => 'd.m.Y',
44
- ),
45
- "relativeTime" => array(
46
- "future" => 'za %s',
47
- "past" => '%s temu',
48
- "s" => 'kilka sekund',
49
- "ss" => function ($count) use ($ifLastDigitIsSpecial)
50
- {
51
- return $ifLastDigitIsSpecial($count, '%d sekundy', '%d sekund');
52
- },
53
- "m" => '1 minutę',
54
- "mm" => function ($count) use ($ifLastDigitIsSpecial)
55
- {
56
- return $ifLastDigitIsSpecial($count, '%d minuty', '%d minut');
57
- },
58
- "h" => '1 godzinę',
59
- "hh" => function ($count) use ($ifLastDigitIsSpecial)
60
- {
61
- return $ifLastDigitIsSpecial($count, '%d godziny', '%d godzin');
62
- },
63
- "d" => '1 dzień',
64
- "dd" => '%d dni',
65
- "M" => '1 miesiąc',
66
- "MM" => function ($count) use ($ifLastDigitIsSpecial)
67
- {
68
- return $ifLastDigitIsSpecial($count, '%d miesiące', '%d miesięcy');
69
- },
70
- "y" => '1 rok',
71
- "yy" => function ($count) use ($ifLastDigitIsSpecial)
72
- {
73
- return $ifLastDigitIsSpecial($count, '%d lata', '%d lat');
74
- },
75
- ),
76
- "ordinal" => function ($number)
77
- {
78
- return $number . '.';
79
- },
80
- "week" => array(
81
- "dow" => 1, // Monday is the first day of the week.
82
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
83
- ),
84
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/pt_BR.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
-
3
- // locale: portuguese (pt-br)
4
- // author: Jefferson Santos https://github.com/jefflssantos
5
-
6
- use Moment\Moment;
7
-
8
- return array(
9
- "months" => explode('_', 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'),
10
- "monthsShort" => explode('_', 'jan._fev._mar._abr._mai._jun._jul._ago._set._out._nov._dez.'),
11
- "weekdays" => explode('_', 'segunda_terça_quarta_quinta_sexta_sábado_domingo'),
12
- "weekdaysShort" => explode('_', 'seg._ter._qua._qui._sex._sáb._dom.'),
13
- "calendar" => array(
14
- "sameDay" => '[hoje]',
15
- "nextDay" => '[amanhã]',
16
- "lastDay" => '[ontem]',
17
- "lastWeek" => '[último] l',
18
- "sameElse" => 'eu',
19
- "withTime" => function (Moment $moment) { return '[à' . ($moment->getHour() !== 1 ? 's' : null) . '] H:i'; },
20
- "default" => 'd/m/Y',
21
- ),
22
- "relativeTime" => array(
23
- "future" => 'em %s',
24
- "past" => 'há %s',
25
- "s" => 'alguns segundos',
26
- "ss" => '%d segundos',
27
- "m" => 'um minuto',
28
- "mm" => '%d minutos',
29
- "h" => 'uma hora',
30
- "hh" => '%d horas',
31
- "d" => 'um dia',
32
- "dd" => '%d dias',
33
- "M" => 'um mês',
34
- "MM" => '%d meses',
35
- "y" => 'um ano',
36
- "yy" => '%d anos',
37
- ),
38
- "ordinal" => function ($number)
39
- {
40
- return $number . 'º';
41
- },
42
- "week" => array(
43
- "dow" => 1, // Monday is the first day of the week.
44
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
45
- ),
46
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/pt_PT.php DELETED
@@ -1,4 +0,0 @@
1
- <?php
2
- // locale: native portuguese (pt_PT)
3
-
4
- return require __DIR__ . '/pt_BR.php';
 
 
 
 
src/Moment/Locales/ro_RO.php DELETED
@@ -1,81 +0,0 @@
1
- <?php
2
-
3
- // locale: romanian (ro-ro)
4
- // author: Calin Rada https://github.com/calinrada
5
-
6
- use Moment\Moment;
7
-
8
- $rtwp = function ($count, $direction, Moment $m, $key)
9
- {
10
- $format = array(
11
- 'mm' => 'minute',
12
- 'hh' => 'ore',
13
- 'dd' => 'zile',
14
- 'MM' => 'luni',
15
- 'yy' => 'ani'
16
- );
17
-
18
- $separator = ' ';
19
-
20
- if ($count % 100 >= 20 || ($count >= 100 && $count % 100 === 0))
21
- {
22
- $separator = ' de ';
23
- }
24
-
25
- return $count . $separator . $format[$key];
26
- };
27
-
28
- return array(
29
- "months" => explode('_', 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'),
30
- "monthsShort" => explode('_', 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'),
31
- "weekdays" => explode('_', 'luni_marți_miercuri_joi_vineri_sâmbătă_duminică'),
32
- "weekdaysShort" => explode('_', 'Lun_Mar_Mie_Joi_Vin_Sâm_Dum'),
33
- "calendar" => array(
34
- "sameDay" => '[azi]',
35
- "nextDay" => '[mâine la]',
36
- "lastDay" => '[ieri la]',
37
- "lastWeek" => '[fosta] dddd [la]',
38
- "sameElse" => 'l',
39
- "withTime" => '[at] H:i',
40
- "default" => 'd/m/Y',
41
- ),
42
- "relativeTime" => array(
43
- "future" => 'peste %s',
44
- "past" => 'În urmă cu %s',
45
- "s" => 'câteva secunde',
46
- "ss" => '%d secunde',
47
- "m" => 'un minut',
48
- "mm" => function ($count, $direction, Moment $m) use ($rtwp)
49
- {
50
- return $rtwp($count, $direction, $m, 'mm');
51
- },
52
- "h" => 'o oră',
53
- "hh" => function ($count, $direction, Moment $m) use ($rtwp)
54
- {
55
- return $rtwp($count, $direction, $m, 'hh');
56
- },
57
- "d" => 'o zi',
58
- "dd" => function ($count, $direction, Moment $m) use ($rtwp)
59
- {
60
- return $rtwp($count, $direction, $m, 'dd');
61
- },
62
- "M" => 'o lună',
63
- "MM" => function ($count, $direction, Moment $m) use ($rtwp)
64
- {
65
- return $rtwp($count, $direction, $m, 'MM');
66
- },
67
- "y" => 'un an',
68
- "yy" => function ($count, $direction, Moment $m) use ($rtwp)
69
- {
70
- return $rtwp($count, $direction, $m, 'yy');
71
- },
72
- ),
73
- "ordinal" => function ($number)
74
- {
75
- return $number;
76
- },
77
- "week" => array(
78
- "dow" => 1, // Monday is the first day of the week.
79
- "doy" => 7 // The week that contains Jan 7th is the first week of the year.
80
- ),
81
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/ru_RU.php DELETED
@@ -1,102 +0,0 @@
1
- <?php
2
-
3
- // locale: Русский (Russia) (ru_RU)
4
- // author: Oleg Bogdanov https://github.com/wormen
5
-
6
- /**
7
- * returns ending for plural form of word by number and array of variants (1, 4, 5)
8
- * example variants for apples ['яблоко', 'яблока', 'яблок']
9
- */
10
-
11
- /**
12
- * @param int $number
13
- * @param array $endingArray
14
- *
15
- * @return string
16
- */
17
- $getNumEnding = function ($number, array $endingArray)
18
- {
19
- $number = $number % 100;
20
-
21
- if ($number >= 11 && $number <= 19)
22
- {
23
- return $endingArray[2];
24
- }
25
-
26
- $i = $number % 10;
27
-
28
- switch ($i)
29
- {
30
- case (1):
31
- $ending = $endingArray[0];
32
- break;
33
- case (2):
34
- case (3):
35
- case (4):
36
- $ending = $endingArray[1];
37
- break;
38
- default:
39
- $ending = $endingArray[2];
40
- }
41
-
42
- return $ending;
43
- };
44
-
45
- return array(
46
- 'months' => explode('_', 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'),
47
- 'monthsNominative' => explode('_', 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'),
48
- 'monthsShort' => explode('_', 'янв_фев_мрт_апр_май_июн_июл_авг_сен_окт_нбр_дек'),
49
- 'weekdays' => explode('_', 'понедельник_вторник_среда_четверг_пятница_суббота_воскресенье'),
50
- 'weekdaysShort' => explode('_', 'пн_вт_ср_чт_пт_сб_вс'),
51
- 'calendar' => array(
52
- 'sameDay' => '[сегодня]',
53
- 'nextDay' => '[завтра]',
54
- 'lastDay' => '[вчера]',
55
- 'lastWeek' => 'l',
56
- 'sameElse' => 'l',
57
- 'withTime' => '[в] H:i',
58
- 'default' => 'd/m/Y',
59
- ),
60
- 'relativeTime' => array(
61
- 'future' => 'через %s',
62
- 'past' => '%s назад',
63
- 's' => 'несколько секунд',
64
- 'ss' => function ($number) use ($getNumEnding)
65
- {
66
- return $getNumEnding($number, array('%d секунду', '%d секунды', '%d секунд'));
67
- },
68
- 'm' => 'минуту',
69
- 'mm' => function ($number) use ($getNumEnding)
70
- {
71
- return $getNumEnding($number, array('%d минуту', '%d минуты', '%d минут'));
72
- },
73
- 'h' => 'час',
74
- 'hh' => function ($number) use ($getNumEnding)
75
- {
76
- return $getNumEnding($number, array('%d час', '%d часа', '%d часов'));
77
- },
78
- 'd' => 'день',
79
- 'dd' => function ($number) use ($getNumEnding)
80
- {
81
- return $getNumEnding($number, array('%d день', '%d дня', '%d дней'));
82
- },
83
- 'M' => 'месяц',
84
- 'MM' => function ($number) use ($getNumEnding)
85
- {
86
- return $getNumEnding($number, array('%d месяц', '%d месяца', '%d месяцев'));
87
- },
88
- 'y' => 'год',
89
- 'yy' => function ($number) use ($getNumEnding)
90
- {
91
- return $getNumEnding($number, array('%d год', '%d года', '%d лет'));
92
- },
93
- ),
94
- 'ordinal' => function ($number)
95
- {
96
- return $number . 'е';
97
- },
98
- 'week' => array(
99
- 'dow' => 1, // Monday is the first day of the week.
100
- 'doy' => 4 // The week that contains Jan 4th is the first week of the year.
101
- ),
102
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/se_SV.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
-
3
- // locale: Swedish (se-SV)
4
- // author: Martin Trobäck https://github.com/lekoaf
5
-
6
- return array(
7
- "months" => explode('_', 'Januari_Februari_Mars_April_Maj_Juni_Juli_Augusti_September_Oktober_November_December'),
8
- "monthsShort" => explode('_', 'Jan_Feb_Mar_Apr_Maj_Jun_Jul_Aug_Sep_Okt_Nov_Dec'),
9
- "weekdays" => explode('_', 'Måndag_Tisdag_Onsdag_Torsdag_Fredag_Lördag_Söndag'),
10
- "weekdaysShort" => explode('_', 'Mån_Tis_Ons_Tor_Fre_Lör_Sön'),
11
- "calendar" => array(
12
- "sameDay" => '[Idag]',
13
- "nextDay" => '[Imorgon]',
14
- "lastDay" => '[Igår]',
15
- "lastWeek" => '[Förra] l',
16
- "sameElse" => 'l',
17
- "withTime" => '[kl] H:i',
18
- "default" => 'Y/m/d',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'om %s',
22
- "past" => '%s sen',
23
- "s" => 'några sekunder',
24
- "ss" => '%d sekunder',
25
- "m" => 'en minut',
26
- "mm" => '%d minuter',
27
- "h" => 'en timme',
28
- "hh" => '%d timmar',
29
- "d" => 'en dag',
30
- "dd" => '%d dagar',
31
- "M" => 'en månad',
32
- "MM" => '%d månader',
33
- "y" => 'ett år',
34
- "yy" => '%d år',
35
- ),
36
- "ordinal" => function ($number) {
37
- return $number;
38
- },
39
- "week" => array(
40
- "dow" => 1, // Monday is the first day of the week.
41
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
42
- ),
43
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/th_TH.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- // locale: Thailand (th_TH)
4
- // author: Tistee Boonsuwan https://github.com/partynetwork
5
-
6
- return array(
7
- "months" => explode('_', 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'),
8
- "monthsShort" => explode('_', 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'),
9
- "weekdays" => explode('_', 'จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์_อาทิตย์'),
10
- "weekdaysShort" => explode('_', 'จ._อ._พ._พฤ_ศ._ส._อา.'),
11
- "calendar" => array(
12
- "sameDay" => '[วันนี้ เวลา]',
13
- "nextDay" => '[พรุ่งนี้ เวลา]',
14
- "lastDay" => '[เมื่อวานนี้]',
15
- "lastWeek" => '[สัปดาห์ที่แล้ว] l',
16
- "sameElse" => 'l',
17
- "withTime" => '[เมื่อ] H:i',
18
- "default" => 'd/m/Y',
19
- ),
20
- "relativeTime" => array(
21
- "future" => 'อีก %s',
22
- "past" => '%s ที่แล้ว',
23
- "s" => 'ไม่กี่วินาที',
24
- "ss" => '%d วินาที',
25
- "m" => '1 นาที',
26
- "mm" => '%d นาที',
27
- "h" => '1 ชั่วโมง',
28
- "hh" => '%d ชั่วโมง',
29
- "d" => '1 วัน',
30
- "dd" => '%d วัน',
31
- "M" => '1 เดือน',
32
- "MM" => '%d เดือน',
33
- "y" => '1 ปี',
34
- "yy" => '%d ปี',
35
- ),
36
- "ordinal" => function ($number)
37
- {
38
- return $number ;
39
- },
40
- "week" => array(
41
- "dow" => 1, // Monday is the first day of the week.
42
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
43
- ),
44
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/tr_TR.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
- /**
3
- * Turkish (tr-TR) language support
4
- * @author Engin Dumlu <engindumlu@gmail.com>
5
- * @github https://github.com/roadrunner
6
- */
7
-
8
- return array(
9
- "months" => explode('_', 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'),
10
- "monthsNominative" => explode('_', 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'),
11
- "monthsShort" => explode('_', 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'),
12
- "weekdays" => explode('_', 'Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi_Pazar'),
13
- "weekdaysShort" => explode('_', 'Pts_Sal_Çar_Per_Cum_Cts_Paz'),
14
- "calendar" => array(
15
- "sameDay" => '[Bugün]',
16
- "nextDay" => '[Yarın]',
17
- "lastDay" => '[Dün]',
18
- "lastWeek" => '[Geçen hafta] l',
19
- "sameElse" => 'l',
20
- "withTime" => 'H:i',
21
- "default" => 'd/m/Y',
22
- ),
23
- "relativeTime" => array(
24
- "future" => '%s sonra',
25
- "past" => '%s önce',
26
- "s" => 'birkaç saniye',
27
- "ss" => '%d saniye',
28
- "m" => 'bir dakika',
29
- "mm" => '%d dakika',
30
- "h" => 'bir saat',
31
- "hh" => '%d saat',
32
- "d" => 'bir gün',
33
- "dd" => '%d gün',
34
- "M" => 'bir ay',
35
- "MM" => '%d ay',
36
- "y" => 'bir yıl',
37
- "yy" => '%d yıl',
38
- ),
39
- "ordinal" => function ($number) {
40
- $n = $number % 100;
41
- $ends = array('inci', 'inci', 'üncü', 'üncü', 'inci', 'ıncı', 'inci', 'inci', 'uncu', 'uncu');
42
-
43
- if ($number > 0 && $n == 0) {
44
- return $number . 'uncu';
45
- }
46
-
47
- return $number . '[' . $ends[$number % 10] . ']';
48
- },
49
- "week" => array(
50
- "dow" => 1, // `Pazartesi` is the first day of the week.
51
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
52
- ),
53
- "customFormats" => array(
54
- "LT" => "G:i", // 20:30
55
- "L" => "d/m/Y", // 04/09/1986
56
- "l" => "j/n/Y", // 4/9/1986
57
- "LL" => "jS F Y", // 4 Septembre 1986
58
- "ll" => "j M Y", // 4 Sep 1986
59
- "LLL" => "jS F Y G:i", // 4 Septembre 1986 20:30
60
- "lll" => "j M Y G:i", // 4 Sep 1986 20:30
61
- "LLLL" => "l, jS F Y G:i", // Jeudi, 4 Septembre 1986 20:30
62
- "llll" => "D, j M Y G:i", // Jeu, 4 Sep 1986 20:30
63
- ),
64
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/uk_UA.php DELETED
@@ -1,119 +0,0 @@
1
- <?php
2
-
3
- // locale: Українська (Ukrainian) (uk_UA)
4
- // author: Mykola Pukhalskyi
5
-
6
- /**
7
- * returns ending for plural form of word by number and array of variants (1, 4, 5)
8
- * example variants for apples ['яблуко', 'яблука', 'яблук']
9
- */
10
-
11
- /**
12
- * @param int $number
13
- * @param array $endingArray
14
- *
15
- * @return string
16
- */
17
- $getNumEnding = function ($number, array $endingArray)
18
- {
19
- $number = $number % 100;
20
-
21
- if ($number >= 11 && $number <= 19)
22
- {
23
- return $endingArray[2];
24
- }
25
-
26
- $i = $number % 10;
27
-
28
- switch ($i)
29
- {
30
- case (1):
31
- $ending = $endingArray[0];
32
- break;
33
- case (2):
34
- case (3):
35
- case (4):
36
- $ending = $endingArray[1];
37
- break;
38
- default:
39
- $ending = $endingArray[2];
40
- }
41
-
42
- return $ending;
43
- };
44
-
45
- return array(
46
- 'months' => explode('_', 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'),
47
- 'monthsNominative' => explode('_', 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'),
48
- 'monthsShort' => explode('_', 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'),
49
- 'weekdays' => explode('_', 'понеділок_вівторок_середа_четвер_п’ятниця_субота_неділя'),
50
- 'weekdaysShort' => explode('_', 'пн_вт_ср_чт_пт_сб_нд'),
51
- 'calendar' => array(
52
- 'sameDay' => '[сьогодні]',
53
- 'nextDay' => '[завтра]',
54
- 'lastDay' => '[вчора]', // or "учора".
55
- 'lastWeek' => 'l',
56
- 'sameElse' => 'l',
57
- 'withTime' => function (\Moment\Moment $number)
58
- {
59
- return $number->format('G') == 11 ? '[об] H:i' : '[о] H:i';
60
- },
61
- 'default' => 'd-m-Y',
62
- ),
63
- 'relativeTime' => array(
64
- // 'future' => 'о %s', // or "об"
65
- 'future' => function (\Moment\Moment $number)
66
- {
67
- return $number->format('G') == 11 ? 'об %s' : 'о %s';
68
- },
69
- 'past' => '%s тому',
70
- 's' => 'кілька секунд',
71
- 'ss' => 'кілька секунд', // needs review by native speaker see https://github.com/fightbulc/moment.php/issues/166
72
- 'm' => 'хвилину',
73
- 'mm' => function ($number) use ($getNumEnding)
74
- {
75
- return $getNumEnding($number, array('%d хвилину', '%d хвилини', '%d хвилин'));
76
- },
77
- 'h' => 'година',
78
- 'hh' => function ($number) use ($getNumEnding)
79
- {
80
- return $getNumEnding($number, array('%d годину', '%d години', '%d годин'));
81
- },
82
- 'd' => 'день',
83
- 'dd' => function ($number) use ($getNumEnding)
84
- {
85
- return $getNumEnding($number, array('%d день', '%d дні', '%d днів'));
86
- },
87
- 'M' => 'місяць',
88
- 'MM' => function ($number) use ($getNumEnding)
89
- {
90
- return $getNumEnding($number, array('%d місяць', '%d місяці', '%d місяців'));
91
- },
92
- 'y' => 'рік',
93
- 'yy' => function ($number) use ($getNumEnding)
94
- {
95
- return $getNumEnding($number, array('%d рік', '%d роки', '%d років'));
96
- },
97
- ),
98
- 'ordinal' => function ($number)
99
- {
100
- $n = $number % 100;
101
- $k = $number % 10;
102
- $ends = array('-ше', '-ге', '-тє', '-те', '-те', '-те', '-ме', '-ме', '-те', '-те');
103
-
104
- if ($n >= 11 && $n <= 13)
105
- {
106
- return $number . '[th]';
107
- }
108
-
109
- if ($n != 13 && $k = 3) {
110
- return $number . '[' . $ends[2] . ']';
111
- }
112
-
113
- return $number . '[' . $ends[$k] . ']';
114
- },
115
- 'week' => array(
116
- 'dow' => 1, // Monday is the first day of the week.
117
- 'doy' => 4 // The week that contains Jan 4th is the first week of the year.
118
- ),
119
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/vi_VN.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
-
3
- // locale: vietnamese - Viet Nam (vi_VN)
4
- // author: Oanh Nguyen https://github.com/oanhnn
5
-
6
- return array(
7
- "months" => explode('_', 'Tháng một_Tháng hai_Tháng ba_Tháng tư_Tháng năm_Tháng sáu_Tháng bảy_Tháng tám_Tháng chín_Tháng mười_Tháng mười một_Tháng mười hai'),
8
- "monthsNominative" => explode('_', 'Tháng 1_Tháng 2_Tháng 3_Tháng 4_Tháng 5_Tháng 6_Tháng 7_Tháng 8_Tháng 9_Tháng 10_Tháng 11_Tháng 12'),
9
- "monthsShort" => explode('_', 'Th1_Th2_Th3_Th4_Th5_Th6_Th7_Th8_Th9_Th10_Th11_Th12'),
10
- "weekdays" => explode('_', 'Thứ 2_Thứ 3_Thứ 4_Thứ 5_Thứ 6_Thứ 7_Chủ nhật'),
11
- "weekdaysShort" => explode('_', 'T2_T3_T4_T5_T6_T7_CN'),
12
- "calendar" => array(
13
- "sameDay" => '[Hôm nay]',
14
- "nextDay" => '[Ngày mai]',
15
- "lastDay" => '[Hôm qua]',
16
- "lastWeek" => '[tuần trước] l',
17
- "sameElse" => 'l',
18
- "withTime" => '[lúc] H:i',
19
- "default" => 'd/m/Y',
20
- ),
21
- "relativeTime" => array(
22
- "future" => 'vào %s',
23
- "past" => '%s trước đây',
24
- "s" => 'một vài giây',
25
- "ss" => '%d giây',
26
- "m" => 'một phút',
27
- "mm" => '%d phút',
28
- "h" => 'một giờ',
29
- "hh" => '%d giờ',
30
- "d" => 'một ngày',
31
- "dd" => '%d ngày',
32
- "M" => 'một tháng',
33
- "MM" => '%d tháng',
34
- "y" => 'một năm',
35
- "yy" => '%d năm',
36
- ),
37
- "ordinal" => function ($number) {
38
- $prefix = "thứ ";
39
-
40
- return $prefix . $number;
41
- },
42
- "week" => array(
43
- "dow" => 1, // Monday is the first day of the week.
44
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
45
- ),
46
- );
47
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/zh_CN.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
-
3
- // locale: chinese (zh-cn)
4
- // author: suupic https://github.com/suupic
5
- // author: Zeno Zeng https://github.com/zenozeng
6
- // author: Senorsen https://github.com/Senorsen
7
- // author: Tino Ehrich https://github.com/fightbulc
8
-
9
- return array(
10
- "months" => explode('_', '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'),
11
- "monthsShort" => explode('_', '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'),
12
- "weekdays" => explode('_', '星期一_星期二_星期三_星期四_星期五_星期六_星期日'),
13
- "weekdaysShort" => explode('_', '周一_周二_周三_周四_周五_周六_周日'),
14
- "weekdaysMin" => explode('_', '一_二_三_四_五_六_日'),
15
- "calendar" => array(
16
- "sameDay" => '[今天]',
17
- "nextDay" => '[明天]',
18
- "lastDay" => '[昨天]',
19
- "lastWeek" => '[上]D',
20
- "sameElse" => '[本]D',
21
- "withTime" => 'H:i',
22
- "default" => 'Y-m-d',
23
- ),
24
- "relativeTime" => array(
25
- "future" => '%s内',
26
- "past" => '%s前',
27
- "s" => '几秒',
28
- "ss" => '%d秒',
29
- "m" => '1分钟',
30
- "mm" => '%d分钟',
31
- "h" => '1小时',
32
- "hh" => '%d小时',
33
- "d" => '1天',
34
- "dd" => '%d天',
35
- "M" => '1个月',
36
- "MM" => '%d个月',
37
- "y" => '1年',
38
- "yy" => '%d年',
39
- ),
40
- "ordinal" => function ($number, $token)
41
- {
42
- $symbol = null;
43
-
44
- switch ($token)
45
- {
46
- case 'd':
47
- case 'w':
48
- $symbol = '[日]';
49
- break;
50
-
51
- case 'n':
52
- $symbol = '[月]';
53
- break;
54
-
55
- case 'W':
56
- $symbol = '[周]';
57
- break;
58
-
59
- default:
60
- }
61
-
62
- return $number . $symbol;
63
- },
64
- "week" => array(
65
- // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
66
- "dow" => 1, // Monday is the first day of the week.
67
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
68
- ),
69
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Locales/zh_TW.php DELETED
@@ -1,67 +0,0 @@
1
- <?php
2
-
3
- // locale: traditional chinese (zh-tw)
4
- // author: Ben https://github.com/ben-lin
5
- // author: Senorsen https://github.com/Senorsen
6
- // author: Tino Ehrich https://github.com/fightbulc
7
-
8
- return array(
9
- "months" => explode('_', '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'),
10
- "monthsShort" => explode('_', '1 月_2 月_3 月_4 月_5 月_6 月_7 月_8 月_9 月_10 月_11 月_12 月'),
11
- "weekdays" => explode('_', '星期一_星期二_星期三_星期四_星期五_星期六_星期日'),
12
- "weekdaysShort" => explode('_', '週一_週二_週三_週四_週五_週六_週日'),
13
- "weekdaysMin" => explode('_', '一_二_三_四_五_六_日'),
14
- "calendar" => array(
15
- "sameDay" => '[今天]',
16
- "nextDay" => '[明天]',
17
- "lastDay" => '[昨天]',
18
- "lastWeek" => '[上]D',
19
- "sameElse" => '[本]D',
20
- "withTime" => 'H:i',
21
- "default" => 'Y-m-d',
22
- ),
23
- "relativeTime" => array(
24
- "future" => '%s內',
25
- "past" => '%s前',
26
- "s" => '幾秒',
27
- "ss" => '%d秒',
28
- "m" => '1 分鐘',
29
- "mm" => '%d 分鐘',
30
- "h" => '1 小時',
31
- "hh" => '%d 小時',
32
- "d" => '1 天',
33
- "dd" => '%d 天',
34
- "M" => '1 個月',
35
- "MM" => '%d 個月',
36
- "y" => '1 年',
37
- "yy" => '%d 年',
38
- ),
39
- "ordinal" => function ($number, $token)
40
- {
41
- $symbol = null;
42
-
43
- switch ($token)
44
- {
45
- case 'd':
46
- case 'w':
47
- $symbol = '[日]';
48
- break;
49
-
50
- case 'n':
51
- $symbol = '[月]';
52
- break;
53
-
54
- case 'W':
55
- $symbol = '[週]';
56
- break;
57
-
58
- default:
59
- }
60
-
61
- return $number . $symbol;
62
- },
63
- "week" => array(
64
- "dow" => 1, // Monday is the first day of the week.
65
- "doy" => 4 // The week that contains Jan 4th is the first week of the year.
66
- ),
67
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/Moment.php DELETED
@@ -1,1427 +0,0 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts\Moment;
4
-
5
- /**
6
- * Moment (1.29.0)
7
- * Wrapper for PHP's DateTime class inspired by moment.js
8
- *
9
- * @package Moment
10
- * @author Tino Ehrich (tino@bigpun.me)
11
- */
12
- class Moment extends \DateTime
13
- {
14
- const NO_TZ_MYSQL = 'Y-m-d H:i:s';
15
- const NO_TZ_NO_SECS = 'Y-m-d H:i';
16
- const NO_TIME = 'Y-m-d';
17
-
18
- /**
19
- * @var string
20
- */
21
- private static $defaultTimezone = 'UTC';
22
-
23
- /**
24
- * @var string
25
- */
26
- private $rawDateTimeString;
27
-
28
- /**
29
- * @var string
30
- */
31
- private $timezoneString;
32
-
33
- /**
34
- * @var boolean
35
- */
36
- private $immutableMode;
37
-
38
- /**
39
- * @param string $locale
40
- * @param bool $findSimilar
41
- *
42
- * @throws MomentException
43
- */
44
- public static function setLocale($locale, $findSimilar = false)
45
- {
46
- // set current language
47
- MomentLocale::setLocale($locale, $findSimilar);
48
- }
49
-
50
- /**
51
- * @param string $timezone
52
- *
53
- * @return void
54
- */
55
- public static function setDefaultTimezone($timezone)
56
- {
57
- // set current language
58
- self::$defaultTimezone = $timezone;
59
- }
60
-
61
- /**
62
- * Creates a new Moment from a DateTime
63
- *
64
- * @param \DateTimeInterface $date
65
- *
66
- * @return Moment
67
- * @throws MomentException
68
- */
69
- public static function fromDateTime(\DateTimeInterface $date)
70
- {
71
- $moment = new static('@' . $date->format('U'));
72
- $moment->setTimezone($date->getTimezone());
73
-
74
- if ($date instanceof \DateTimeImmutable)
75
- {
76
- $moment->setImmutableMode(true);
77
- }
78
-
79
- return $moment;
80
- }
81
-
82
- /**
83
- * Workaround for {@see https://bugs.php.net/bug.php?id=60302} and
84
- * {@see https://github.com/fightbulc/moment.php/issues/89}
85
- *
86
- * @param string $format format of the date
87
- * @param string $time date string to parse
88
- * @param null|\DateTimeZone $timezone optional timezone to parse the string with
89
- * @param null|FormatsInterface $formatsInterface optional interface to use for {@see $format}.
90
- *
91
- * @return static
92
- * @throws MomentException
93
- */
94
- public static function createFromFormat($format, $time, $timezone = null, FormatsInterface $formatsInterface = null)
95
- {
96
- // handle diverse format types
97
- if ($formatsInterface instanceof FormatsInterface)
98
- {
99
- // merge localized custom formats
100
- $localeContent = MomentLocale::getLocaleContent();
101
- if (isset($localeContent['customFormats']) && is_array($localeContent['customFormats']))
102
- {
103
- $formatsInterface->setTokens($localeContent['customFormats']);
104
- }
105
-
106
- $format = $formatsInterface->format($format);
107
- }
108
-
109
- $date = $timezone ?
110
- parent::createFromFormat($format, $time, $timezone) :
111
- parent::createFromFormat($format, $time);
112
-
113
- return static::fromDateTime($date);
114
- }
115
-
116
- /**
117
- * @param string $dateTime
118
- * @param string|null $timezone
119
- * @param bool $immutableMode
120
- *
121
- * @throws MomentException
122
- */
123
- public function __construct($dateTime = 'now', $timezone = null, $immutableMode = false)
124
- {
125
- if ($timezone === null)
126
- {
127
- $timezone = self::$defaultTimezone;
128
- }
129
-
130
- // set moment
131
- MomentLocale::setMoment($this);
132
-
133
- // load locale content
134
- MomentLocale::loadLocaleContent();
135
-
136
- // initialize DateTime
137
- $this->resetDateTime($dateTime, $timezone);
138
-
139
- // set immutable mode
140
- $this->setImmutableMode($immutableMode);
141
- }
142
-
143
- /**
144
- * @param boolean $mode
145
- *
146
- * @return self
147
- */
148
- public function setImmutableMode($mode)
149
- {
150
- // set immutable mode to true or false
151
- $this->immutableMode = $mode;
152
-
153
- return $this;
154
- }
155
-
156
- /**
157
- * @param string $dateTime
158
- * @param string $timezone
159
- *
160
- * @return $this
161
- * @throws MomentException
162
- * @throws \Exception
163
- */
164
- public function resetDateTime($dateTime = 'now', $timezone = null)
165
- {
166
- $lengthDateTime = strlen((int)$dateTime);
167
-
168
- // unix timestamp helper
169
- if ($lengthDateTime >= 9 && $lengthDateTime <= 10)
170
- {
171
- $dateTime = '@' . $dateTime;
172
- }
173
-
174
- if ($timezone === null)
175
- {
176
- $timezone = self::$defaultTimezone;
177
- }
178
-
179
- if ($this->immutableMode)
180
- {
181
- return $this->implicitCloning(__FUNCTION__, func_get_args());
182
- }
183
-
184
- // cache dateTime
185
- $this->setRawDateTimeString($dateTime);
186
-
187
- // create instance
188
- parent::__construct($dateTime, $this->getDateTimeZone($timezone));
189
-
190
- // set timezone if unix time
191
- if (strpos($dateTime, '@') !== false && $timezone)
192
- {
193
- $this->setTimezone($timezone);
194
- }
195
-
196
- // date validation
197
- if ($this->isValidDate() === false)
198
- {
199
- throw new MomentException('Given date of "' . $dateTime . '" is invalid');
200
- }
201
-
202
- return $this;
203
- }
204
-
205
- /**
206
- * @param string|\DateTimeZone $timezone
207
- *
208
- * @return \DateTime|Moment
209
- */
210
- public function setTimezone($timezone)
211
- {
212
- if ($this->immutableMode)
213
- {
214
- return $this->implicitCloning(__FUNCTION__, func_get_args());
215
- }
216
-
217
- if ($timezone instanceof \DateTimeZone)
218
- {
219
- $timezone = $timezone->getName();
220
- }
221
-
222
- $this->setTimezoneString($timezone);
223
-
224
- parent::setTimezone($this->getDateTimeZone($timezone));
225
-
226
- return $this;
227
- }
228
-
229
- /**
230
- * @param null|string $format
231
- * @param null|FormatsInterface $formatsInterface
232
- *
233
- * @return string
234
- * @throws MomentException
235
- */
236
- public function format($format = null, $formatsInterface = null)
237
- {
238
- // set default format
239
- if ($format === null)
240
- {
241
- $format = \DateTime::ISO8601;
242
- }
243
-
244
- // handle diverse format types
245
- if ($formatsInterface instanceof FormatsInterface)
246
- {
247
- // merge localized custom formats
248
- $localeContent = MomentLocale::getLocaleContent();
249
- if (isset($localeContent['customFormats']) && is_array($localeContent['customFormats']))
250
- {
251
- $formatsInterface->setTokens($localeContent['customFormats']);
252
- }
253
-
254
- $format = $formatsInterface->format($format);
255
- }
256
-
257
- // handle ordinals
258
- if (strpos($format, 'S') !== false)
259
- {
260
- preg_match_all('/(\wS)/', $format, $matches);
261
-
262
- if (count($matches) >= 1)
263
- {
264
- foreach ($matches[1] as $part)
265
- {
266
- $token = substr($part, 0, 1);
267
- $number = $this->format($token);
268
- $format = str_replace($part, $this->formatOrdinal($number, $token), $format);
269
- }
270
- }
271
- }
272
-
273
- // handle text
274
- if (strpos($format, '[') !== false)
275
- {
276
- preg_match_all('/\[([^\[]*)\]/', $format, $matches);
277
-
278
- foreach ($matches[1] as $part)
279
- {
280
- $format = preg_replace('/\[' . $part . '\]/u', preg_replace('/(\w)/u', '\\\\\1', $part), $format);
281
- }
282
- }
283
-
284
- // prepare locale formats
285
- $format = MomentLocale::prepareSpecialLocaleTags($format);
286
-
287
- // render moment
288
- $format = parent::format($format);
289
-
290
- // render locale format
291
- $format = MomentLocale::renderSpecialLocaleTags($format);
292
-
293
- return $format;
294
- }
295
-
296
- /**
297
- * @param int $seconds
298
- *
299
- * @return Moment
300
- */
301
- public function addSeconds($seconds = 1)
302
- {
303
- return $this->addTime('second', $seconds);
304
- }
305
-
306
- /**
307
- * @param int $minutes
308
- *
309
- * @return Moment
310
- */
311
- public function addMinutes($minutes = 1)
312
- {
313
- return $this->addTime('minute', $minutes);
314
- }
315
-
316
- /**
317
- * @param int $hours
318
- *
319
- * @return Moment
320
- */
321
- public function addHours($hours = 1)
322
- {
323
- return $this->addTime('hour', $hours);
324
- }
325
-
326
- /**
327
- * @param int $days
328
- *
329
- * @return Moment
330
- */
331
- public function addDays($days = 1)
332
- {
333
- return $this->addTime('day', $days);
334
- }
335
-
336
- /**
337
- * @param int $weeks
338
- *
339
- * @return Moment
340
- */
341
- public function addWeeks($weeks = 1)
342
- {
343
- return $this->addTime('week', $weeks);
344
- }
345
-
346
- /**
347
- * @param int $months
348
- *
349
- * @return Moment
350
- */
351
- public function addMonths($months = 1)
352
- {
353
- return $this->addTime('month', $months);
354
- }
355
-
356
- /**
357
- * @param int $years
358
- *
359
- * @return Moment
360
- */
361
- public function addYears($years = 1)
362
- {
363
- return $this->addTime('year', $years);
364
- }
365
-
366
- /**
367
- * @param int $seconds
368
- *
369
- * @return Moment
370
- */
371
- public function subtractSeconds($seconds = 1)
372
- {
373
- return $this->subtractTime('second', $seconds);
374
- }
375
-
376
- /**
377
- * @param int $minutes
378
- *
379
- * @return Moment
380
- */
381
- public function subtractMinutes($minutes = 1)
382
- {
383
- return $this->subtractTime('minute', $minutes);
384
- }
385
-
386
- /**
387
- * @param int $hours
388
- *
389
- * @return Moment
390
- */
391
- public function subtractHours($hours = 1)
392
- {
393
- return $this->subtractTime('hour', $hours);
394
- }
395
-
396
- /**
397
- * @param int $days
398
- *
399
- * @return Moment
400
- */
401
- public function subtractDays($days = 1)
402
- {
403
- return $this->subtractTime('day', $days);
404
- }
405
-
406
- /**
407
- * @param int $weeks
408
- *
409
- * @return Moment
410
- */
411
- public function subtractWeeks($weeks = 1)
412
- {
413
- return $this->subtractTime('week', $weeks);
414
- }
415
-
416
- /**
417
- * @param int $months
418
- *
419
- * @return Moment
420
- */
421
- public function subtractMonths($months = 1)
422
- {
423
- return $this->subtractTime('month', $months);
424
- }
425
-
426
- /**
427
- * @param int $years
428
- *
429
- * @return Moment
430
- */
431
- public function subtractYears($years = 1)
432
- {
433
- return $this->subtractTime('year', $years);
434
- }
435
-
436
- /**
437
- * @param int $day
438
- *
439
- * @return Moment
440
- * @throws MomentException
441
- */
442
- public function setDay($day)
443
- {
444
- if ($this->immutableMode)
445
- {
446
- return $this->implicitCloning(__FUNCTION__, func_get_args());
447
- }
448
-
449
- $this->setDate($this->format('Y'), $this->format('m'), $day);
450
-
451
- return $this;
452
- }
453
-
454
- /**
455
- * @param int $month
456
- *
457
- * @return Moment
458
- * @throws MomentException
459
- */
460
- public function setMonth($month)
461
- {
462
- if ($this->immutableMode)
463
- {
464
- return $this->implicitCloning(__FUNCTION__, func_get_args());
465
- }
466
-
467
- $this->setDate($this->format('Y'), $month, $this->format('d'));
468
-
469
- return $this;
470
- }
471
-
472
- /**
473
- * @param int $year
474
- *
475
- * @return Moment
476
- * @throws MomentException
477
- */
478
- public function setYear($year)
479
- {
480
- if ($this->immutableMode)
481
- {
482
- return $this->implicitCloning(__FUNCTION__, func_get_args());
483
- }
484
-
485
- $this->setDate($year, $this->format('m'), $this->format('d'));
486
-
487
- return $this;
488
- }
489
-
490
- /**
491
- * @return string
492
- * @throws MomentException
493
- */
494
- public function getDay()
495
- {
496
- return (string)$this->format('d');
497
- }
498
-
499
- /**
500
- * @return string
501
- * @throws MomentException
502
- */
503
- public function getWeekday()
504
- {
505
- return (string)$this->format('N');
506
- }
507
-
508
- /**
509
- * @return string
510
- * @throws MomentException
511
- */
512
- public function getWeekdayNameLong()
513
- {
514
- return (string)$this->format('l');
515
- }
516
-
517
- /**
518
- * @return string
519
- * @throws MomentException
520
- */
521
- public function getWeekdayNameShort()
522
- {
523
- return (string)$this->format('D');
524
- }
525
-
526
- /**
527
- * @return string
528
- * @throws MomentException
529
- */
530
- public function getWeekOfYear()
531
- {
532
- return (string)$this->format('W');
533
- }
534
-
535
- /**
536
- * @return string
537
- * @throws MomentException
538
- */
539
- public function getMonth()
540
- {
541
- return (string)$this->format('m');
542
- }
543
-
544
- /**
545
- * @return string
546
- * @throws MomentException
547
- */
548
- public function getMonthNameLong()
549
- {
550
- return (string)$this->format('F');
551
- }
552
-
553
- /**
554
- * @return string
555
- * @throws MomentException
556
- */
557
- public function getMonthNameShort()
558
- {
559
- return (string)$this->format('M');
560
- }
561
-
562
- /**
563
- * @return string
564
- * @throws MomentException
565
- */
566
- public function getQuarter()
567
- {
568
- $currentMonth = $this->format('n');
569
-
570
- return (string)ceil($currentMonth / 3);
571
- }
572
-
573
- /**
574
- * @return string
575
- * @throws MomentException
576
- */
577
- public function getYear()
578
- {
579
- return (string)$this->format('Y');
580
- }
581
-
582
- /**
583
- * @param int $year
584
- * @param int $month
585
- * @param int $day
586
- *
587
- * @return self|\DateTime
588
- */
589
- public function setDate($year, $month, $day)
590
- {
591
- if ($this->immutableMode)
592
- {
593
- return $this->implicitCloning(__FUNCTION__, func_get_args());
594
- }
595
-
596
- parent::setDate($year, $month, $day);
597
-
598
- return $this;
599
- }
600
-
601
- /**
602
- * @param int $second
603
- *
604
- * @throws MomentException
605
- * @return Moment
606
- */
607
- public function setSecond($second)
608
- {
609
- if ($this->immutableMode)
610
- {
611
- return $this->implicitCloning(__FUNCTION__, func_get_args());
612
- }
613
-
614
- $this->setTime($this->format('H'), $this->format('i'), $second);
615
-
616
- return $this;
617
- }
618
-
619
- /**
620
- * @param int $minute
621
- *
622
- * @return Moment
623
- * @throws MomentException
624
- */
625
- public function setMinute($minute)
626
- {
627
- if ($this->immutableMode)
628
- {
629
- return $this->implicitCloning(__FUNCTION__, func_get_args());
630
- }
631
-
632
- $this->setTime($this->format('H'), $minute, $this->format('s'));
633
-
634
- return $this;
635
- }
636
-
637
- /**
638
- * @param int $hour
639
- *
640
- * @return Moment
641
- * @throws MomentException
642
- */
643
- public function setHour($hour)
644
- {
645
- if ($this->immutableMode)
646
- {
647
- return $this->implicitCloning(__FUNCTION__, func_get_args());
648
- }
649
-
650
- $this->setTime($hour, $this->format('i'), $this->format('s'));
651
-
652
- return $this;
653
- }
654
-
655
- /**
656
- * @return string
657
- * @throws MomentException
658
- */
659
- public function getSecond()
660
- {
661
- return (string)$this->format('s');
662
- }
663
-
664
- /**
665
- * @return string
666
- * @throws MomentException
667
- */
668
- public function getMinute()
669
- {
670
- return (string)$this->format('i');
671
- }
672
-
673
- /**
674
- * @return string
675
- * @throws MomentException
676
- */
677
- public function getHour()
678
- {
679
- return (string)$this->format('H');
680
- }
681
-
682
- /**
683
- * @param int $hour
684
- * @param int $minute
685
- * @param int|null $second
686
- * @param int|null $microseconds
687
- *
688
- * @return $this|\DateTime
689
- */
690
- public function setTime($hour, $minute, $second = null, $microseconds = null)
691
- {
692
- if ($this->immutableMode)
693
- {
694
- return $this->implicitCloning(__FUNCTION__, func_get_args());
695
- }
696
-
697
- parent::setTime($hour, $minute, $second);
698
-
699
- return $this;
700
- }
701
-
702
- /**
703
- * @param string|Moment $fromMoment
704
- * @param null $timezoneString
705
- *
706
- * @return MomentFromVo
707
- * @throws MomentException
708
- */
709
- public function from($fromMoment = 'now', $timezoneString = null)
710
- {
711
- // create moment first
712
- if ($this->isMoment($fromMoment) === false)
713
- {
714
- // use custom timezone or fallback the current moment
715
- $useTimezoneString = $timezoneString !== null ? $timezoneString : $this->getTimezoneString();
716
- $fromMoment = new Moment($fromMoment, $useTimezoneString);
717
- }
718
-
719
- // calc difference between dates
720
- $dateDiff = parent::diff($fromMoment);
721
- $momentFromVo = new MomentFromVo($fromMoment);
722
-
723
- return $momentFromVo
724
- ->setDirection($dateDiff->format('%R'))
725
- ->setSeconds($this->fromToSeconds($dateDiff))
726
- ->setMinutes($this->fromToMinutes($dateDiff))
727
- ->setHours($this->fromToHours($dateDiff))
728
- ->setDays($this->fromToDays($dateDiff))
729
- ->setWeeks($this->fromToWeeks($dateDiff))
730
- ;
731
- }
732
-
733
- /**
734
- * @param null $timezoneString
735
- *
736
- * @return MomentFromVo
737
- * @throws MomentException
738
- */
739
- public function fromNow($timezoneString = null)
740
- {
741
- // use custom timezone or fallback the current moment
742
- $useTimezoneString = $timezoneString !== null ? $timezoneString : $this->getTimezoneString();
743
-
744
- return $this->from('now', $useTimezoneString);
745
- }
746
-
747
- /**
748
- * @param $input
749
- *
750
- * @return bool
751
- */
752
- public function isMoment($input)
753
- {
754
- return $input instanceof Moment;
755
- }
756
-
757
- /**
758
- * @param string $type
759
- * @param int $value
760
- *
761
- * @return Moment
762
- */
763
- private function addTime($type = 'day', $value = 1)
764
- {
765
- if ($this->immutableMode)
766
- {
767
- return $this->implicitCloning(__FUNCTION__, func_get_args());
768
- }
769
-
770
- parent::modify('+' . $value . ' ' . $type);
771
-
772
- return $this;
773
- }
774
-
775
- /**
776
- * @param \DateInterval $dateInterval
777
- *
778
- * @return string
779
- */
780
- private function fromToSeconds(\DateInterval $dateInterval)
781
- {
782
- return
783
- ($dateInterval->days * 24 * 60 * 60)
784
- + ($dateInterval->h * 60 * 60)
785
- + ($dateInterval->i * 60)
786
- + $dateInterval->s;
787
- }
788
-
789
- /**
790
- * @param \DateInterval $dateInterval
791
- *
792
- * @return string
793
- */
794
- private function fromToMinutes(\DateInterval $dateInterval)
795
- {
796
- return $this->fromToSeconds($dateInterval) / 60;
797
- }
798
-
799
- /**
800
- * @param \DateInterval $dateInterval
801
- *
802
- * @return string
803
- */
804
- private function fromToHours(\DateInterval $dateInterval)
805
- {
806
- return $this->fromToMinutes($dateInterval) / 60;
807
- }
808
-
809
- /**
810
- * @param \DateInterval $dateInterval
811
- *
812
- * @return string
813
- */
814
- private function fromToDays(\DateInterval $dateInterval)
815
- {
816
- return $this->fromToHours($dateInterval) / 24;
817
- }
818
-
819
- /**
820
- * @param \DateInterval $dateInterval
821
- *
822
- * @return string
823
- */
824
- private function fromToWeeks(\DateInterval $dateInterval)
825
- {
826
- return $this->fromToDays($dateInterval) / 7;
827
- }
828
-
829
- /**
830
- * @param $period
831
- *
832
- * @return MomentPeriodVo
833
- * @throws MomentException
834
- */
835
- public function getPeriod($period)
836
- {
837
- switch ($period)
838
- {
839
- case 'week':
840
- $interval = $this->format('W');
841
-
842
- $start = new Moment('@' . $this->format('U'));
843
- $start->setTimezone($this->getTimezoneString())
844
- ->subtractDays($this->getDaysAfterStartOfWeek())
845
- ->setTime(0, 0, 0)
846
- ;
847
-
848
- $end = new Moment('@' . $this->format('U'));
849
- $end->setTimezone($this->getTimezoneString())
850
- ->addDays(6 - $this->getDaysAfterStartOfWeek())
851
- ->setTime(23, 59, 59)
852
- ;
853
-
854
- break;
855
-
856
- // ------------------------------
857
-
858
- case 'month':
859
- $maxMonthDays = $this->format('t');
860
- $currentMonthDay = $this->format('j');
861
- $interval = $this->getMonth();
862
-
863
- $start = new Moment('@' . $this->format('U'));
864
- $start->setTimezone($this->getTimezoneString())
865
- ->subtractDays($currentMonthDay - 1)
866
- ->setTime(0, 0, 0)
867
- ;
868
-
869
- $end = new Moment('@' . $this->format('U'));
870
- $end->setTimezone($this->getTimezoneString())
871
- ->addDays($maxMonthDays - $currentMonthDay)
872
- ->setTime(23, 59, 59)
873
- ;
874
-
875
- break;
876
-
877
- // ------------------------------
878
-
879
- case 'quarter':
880
- $quarter = $this->getQuarter();
881
- $momentPeriodVo = MomentHelper::getQuarterPeriod($quarter, $this->getYear(), $this->getTimezoneString());
882
- $start = $momentPeriodVo->getStartDate();
883
- $end = $momentPeriodVo->getEndDate();
884
- $interval = $quarter;
885
- break;
886
-
887
- // ------------------------------
888
-
889
- default:
890
- throw new MomentException("Period \"{$period}\" is not supported. Supported: \"week\", \"month\", \"quarter\".");
891
- }
892
-
893
- $momentPeriodVo = new MomentPeriodVo();
894
-
895
- return $momentPeriodVo
896
- ->setRefDate($this)
897
- ->setInterval($interval)
898
- ->setStartDate($start)
899
- ->setEndDate($end)
900
- ;
901
- }
902
-
903
- /**
904
- * @param bool $withTime
905
- * @param Moment|null $refMoment
906
- *
907
- * @return string
908
- * @throws MomentException
909
- */
910
- public function calendar($withTime = true, Moment $refMoment = null)
911
- {
912
- $refMoment = $refMoment ? $refMoment : new Moment('now', $this->getTimezoneString());
913
- $momentFromVo = $this->cloning()->startOf('day')->from($refMoment->startOf('day'));
914
- $diff = $momentFromVo->getDays();
915
-
916
- // handle time string
917
- $renderedTimeString = MomentLocale::renderLocaleString(array('calendar', 'withTime'), array($this));
918
- $addTime = false;
919
-
920
- // apply cases
921
- if ($diff > 7)
922
- {
923
- $localeKeys = array('calendar', 'default');
924
- }
925
- elseif ($diff > 1)
926
- {
927
- $localeKeys = array('calendar', 'lastWeek');
928
- $addTime = true;
929
- }
930
- elseif ($diff > 0)
931
- {
932
- $localeKeys = array('calendar', 'lastDay');
933
- $addTime = true;
934
- }
935
- elseif ($diff == 0)
936
- {
937
- $localeKeys = array('calendar', 'sameDay');
938
- $addTime = true;
939
- }
940
- elseif ($diff == -1)
941
- {
942
- $localeKeys = array('calendar', 'nextDay');
943
- $addTime = true;
944
- }
945
- elseif ($diff > -7)
946
- {
947
- $localeKeys = array('calendar', 'sameElse');
948
- $addTime = true;
949
- }
950
- else
951
- {
952
- $localeKeys = array('calendar', 'default');
953
- }
954
-
955
- // render format
956
- $format = MomentLocale::renderLocaleString($localeKeys, array($this));
957
-
958
- // add time if valid
959
- if ($addTime && $withTime === true)
960
- {
961
- $format .= ' ' . $renderedTimeString;
962
- }
963
-
964
- return $this->format($format);
965
- }
966
-
967
- /**
968
- * @param string $period
969
- *
970
- * @return Moment
971
- * @throws MomentException
972
- */
973
- public function startOf($period)
974
- {
975
- switch ($period)
976
- {
977
- // set to now, but with 0 seconds
978
- case 'minute':
979
- return $this->setTime($this->getHour(), $this->getMinute(), 0);
980
- break;
981
-
982
- // set to now, but with 0 mins, 0 secs
983
- case 'hour':
984
- return $this->setTime($this->getHour(), 0, 0);
985
- break;
986
-
987
- // set to 00:00:00 today
988
- case 'day':
989
- return $this->setTime(0, 0, 0);
990
- break;
991
-
992
- // set to the first day of this week, 00:00:00
993
- case 'week':
994
- return $this->resetDateTime(
995
- $this->getPeriod('week')->getStartDate()->format('c')
996
- );
997
- break;
998
-
999
- // set to the beginning of the current quarter, 1st day of months, 00:00:00
1000
- case 'quarter':
1001
- return $this->resetDateTime(
1002
- $this->getPeriod('quarter')->getStartDate()->format('c')
1003
- );
1004
- break;
1005
-
1006
- // set to the first of this month, 00:00:00
1007
- case 'month':
1008
- return $this->resetDateTime(
1009
- $this->getPeriod('month')->getStartDate()->format('c')
1010
- );
1011
- break;
1012
-
1013
- // set to January 1st, 00:00:00 this year
1014
- case 'year':
1015
- return $this->setDate($this->getYear(), 1, 1)->setTime(0, 0, 0);
1016
- break;
1017
-
1018
- default:
1019
- return $this;
1020
- }
1021
- }
1022
-
1023
- /**
1024
- * @param string $period
1025
- *
1026
- * @return Moment
1027
- * @throws MomentException
1028
- */
1029
- public function endOf($period)
1030
- {
1031
- switch ($period)
1032
- {
1033
- // set to now, but with 59 seconds
1034
- case 'minute':
1035
- return $this->setTime($this->getHour(), $this->getMinute(), 59);
1036
- break;
1037
-
1038
- // set to now, but with 59 mins, 59 secs
1039
- case 'hour':
1040
- return $this->setTime($this->getHour(), 59, 59);
1041
- break;
1042
-
1043
- // set to 23:59:59 today
1044
- case 'day':
1045
- return $this->setTime(23, 59, 59);
1046
- break;
1047
-
1048
- // set to the last day of this week, 23:59
1049
- case 'week':
1050
- return $this->resetDateTime(
1051
- $this->getPeriod('week')->getEndDate()->format('c')
1052
- );
1053
- break;
1054
-
1055
- // set to the end of the current quarter, last day of months, 23:59:59
1056
- case 'quarter':
1057
- return $this->resetDateTime(
1058
- $this->getPeriod('quarter')->getEndDate()->format('c')
1059
- );
1060
- break;
1061
-
1062
- // set to the last of this month, 23:59:59
1063
- case 'month':
1064
- return $this->resetDateTime(
1065
- $this->getPeriod('month')->getEndDate()->format('c')
1066
- );
1067
- break;
1068
-
1069
- // set to January 1st, 23:59:59 this year
1070
- case 'year':
1071
- return $this->setDate($this->getYear(), 12, 31)->setTime(23, 59, 59);
1072
- break;
1073
-
1074
- default:
1075
- return $this;
1076
- }
1077
- }
1078
-
1079
- /**
1080
- * @return Moment
1081
- */
1082
- public function cloning()
1083
- {
1084
- return clone($this);
1085
- }
1086
-
1087
- /**
1088
- * @param string $method
1089
- * @param array $params
1090
- *
1091
- * @return self
1092
- */
1093
- protected function implicitCloning($method, $params = array())
1094
- {
1095
- $clone = $this->cloning();
1096
-
1097
- $clone->setImmutableMode(false);
1098
- $retval = call_user_func_array(array($clone, $method), $params);
1099
- $clone->setImmutableMode(true);
1100
-
1101
- return is_null($retval) ? $clone : $retval;
1102
- }
1103
-
1104
- /**
1105
- * @param array $weekdayNumbers
1106
- * @param int $forUpcomingWeeks
1107
- *
1108
- * @return Moment[]
1109
- * @throws MomentException
1110
- */
1111
- public function getMomentsByWeekdays(array $weekdayNumbers, $forUpcomingWeeks = 1)
1112
- {
1113
- /** @var Moment[] $moments */
1114
- $dates = array();
1115
-
1116
- // get today's week day number
1117
- $todayWeekday = $this->getWeekday();
1118
-
1119
- // generate for upcoming weeks
1120
- for ($w = 1; $w <= $forUpcomingWeeks; $w++)
1121
- {
1122
- for ($d = 1; $d <= 7; $d++)
1123
- {
1124
- if (in_array($d, $weekdayNumbers) && ($w > 1 || $d > $todayWeekday))
1125
- {
1126
- // calculate add days from today's perspective
1127
- $addDays = $w === 1 ? $d - $todayWeekday : ($d - $todayWeekday) + ($w * 7 - 7);
1128
-
1129
- // set date
1130
- $dates[] = $this->cloning()->addDays($addDays);
1131
- }
1132
- }
1133
- }
1134
-
1135
- return $dates;
1136
- }
1137
-
1138
- /**
1139
- * Returns copy of Moment normalized to UTC timezone
1140
- *
1141
- * @return Moment
1142
- */
1143
- public function toUTC()
1144
- {
1145
- return $this->cloning()->setTimezone('UTC');
1146
- }
1147
-
1148
- /**
1149
- * Check if a moment is the same as another moment
1150
- *
1151
- * @param string|Moment $dateTime
1152
- * @param string $period 'seconds|minute|hour|day|month|year'
1153
- *
1154
- * @return bool
1155
- * @throws MomentException
1156
- */
1157
- public function isSame($dateTime, $period = 'seconds')
1158
- {
1159
- $dateTime = $this->isMoment($dateTime) ? $dateTime : new Moment($dateTime);
1160
-
1161
- return (bool)($this->toUTC()->startOf($period)->getTimestamp() === $dateTime->toUTC()->startOf($period)->getTimestamp());
1162
- }
1163
-
1164
- /**
1165
- * Checks if Moment is before given time
1166
- *
1167
- * @param string|Moment $dateTime
1168
- * @param string $period 'seconds|minute|hour|day|month|year'
1169
- *
1170
- * @return bool
1171
- * @throws MomentException
1172
- */
1173
- public function isBefore($dateTime, $period = 'seconds')
1174
- {
1175
- $dateTime = $this->isMoment($dateTime) ? $dateTime : new Moment($dateTime);
1176
-
1177
- return (bool)($this->toUTC()->startOf($period)->getTimestamp() < $dateTime->toUTC()->startOf($period)->getTimestamp());
1178
- }
1179
-
1180
- /**
1181
- * Checks if Moment is after given time
1182
- *
1183
- * @param string|Moment $dateTime
1184
- * @param string $period 'seconds|minute|hour|day|month|year'
1185
- *
1186
- * @return bool
1187
- * @throws MomentException
1188
- */
1189
- public function isAfter($dateTime, $period = 'seconds')
1190
- {
1191
- $dateTime = $this->isMoment($dateTime) ? $dateTime : new Moment($dateTime);
1192
-
1193
- return $dateTime->isBefore($this, $period);
1194
- }
1195
-
1196
- /**
1197
- * Checks if Moment is between given time range
1198
- *
1199
- * @param string|Moment $minDateTime
1200
- * @param string|Moment $maxDateTime
1201
- * @param boolean $closed
1202
- * @param string $period 'seconds|minute|hour|day|month|year'
1203
- *
1204
- * @return bool
1205
- * @throws MomentException
1206
- */
1207
- public function isBetween($minDateTime, $maxDateTime, $closed = true, $period = 'seconds')
1208
- {
1209
- $isBefore = $this->isBefore($minDateTime, $period);
1210
- $isAfter = $this->isAfter($maxDateTime, $period);
1211
-
1212
- // include endpoints
1213
- if ($closed === true)
1214
- {
1215
- return $isBefore === false && $isAfter === false;
1216
- }
1217
-
1218
- return $isBefore === true && $isAfter === true;
1219
- }
1220
-
1221
- /**
1222
- * @param string $rawDateTimeString
1223
- *
1224
- * @return Moment
1225
- */
1226
- private function setRawDateTimeString($rawDateTimeString)
1227
- {
1228
- if ($this->immutableMode)
1229
- {
1230
- return $this->implicitCloning(__FUNCTION__, func_get_args());
1231
- }
1232
-
1233
- $this->rawDateTimeString = $rawDateTimeString;
1234
-
1235
- return $this;
1236
- }
1237
-
1238
- /**
1239
- * @return string
1240
- */
1241
- private function getRawDateTimeString()
1242
- {
1243
- return $this->rawDateTimeString;
1244
- }
1245
-
1246
- /**
1247
- * @param string $timezoneString
1248
- *
1249
- * @return Moment
1250
- */
1251
- private function setTimezoneString($timezoneString)
1252
- {
1253
- if ($this->immutableMode)
1254
- {
1255
- return $this->implicitCloning(__FUNCTION__, func_get_args());
1256
- }
1257
-
1258
- $this->timezoneString = $timezoneString;
1259
-
1260
- return $this;
1261
- }
1262
-
1263
- /**
1264
- * @return string
1265
- */
1266
- private function getTimezoneString()
1267
- {
1268
- return $this->timezoneString;
1269
- }
1270
-
1271
- /**
1272
- * @param string $timezoneString
1273
- *
1274
- * @return \DateTimeZone
1275
- */
1276
- private function getDateTimeZone($timezoneString)
1277
- {
1278
- // cache timezone
1279
- $this->setTimezoneString($timezoneString);
1280
-
1281
- return new \DateTimeZone($timezoneString);
1282
- }
1283
-
1284
- /**
1285
- * @return int
1286
- * @throws MomentException
1287
- */
1288
- private function getDaysAfterStartOfWeek()
1289
- {
1290
- $dow = MomentLocale::getLocaleString(array('week', 'dow')) % 7;
1291
- $currentWeekDay = (int)$this->getWeekday();
1292
- $distance = (7 - $dow + $currentWeekDay) % 7;
1293
-
1294
- return $distance;
1295
- }
1296
-
1297
- /**
1298
- * @return bool
1299
- * @throws MomentException
1300
- */
1301
- private function isValidDate()
1302
- {
1303
- $rawDateTime = $this->getRawDateTimeString();
1304
-
1305
- if (strpos($rawDateTime, '-') === false)
1306
- {
1307
- return true;
1308
- }
1309
-
1310
- // ----------------------------------
1311
-
1312
- // time with indicator "T"
1313
- if (strpos($rawDateTime, 'T') !== false)
1314
- {
1315
- // remove fraction if any
1316
- $rawDateTime = preg_replace('/\.[0-9][0-9][0-9]/', '', $rawDateTime);
1317
-
1318
- // get timezone if any
1319
- $rawTimeZone = substr($rawDateTime, 19);
1320
-
1321
- // timezone w/ difference in hours: e.g. +0200
1322
- if (empty($rawTimeZone) === false)
1323
- {
1324
- if (strpos($rawTimeZone, '+') !== false || strpos($rawTimeZone, '-') !== false)
1325
- {
1326
- // with colon: +-HH:MM
1327
- if (substr_count($rawTimeZone, ':') > 0)
1328
- {
1329
- $momentDateTime = $this->format('Y-m-d\TH:i:sP');
1330
- }
1331
-
1332
- // without colon: +-HHMM
1333
- else
1334
- {
1335
- $momentDateTime = $this->format('Y-m-d\TH:i:sO');
1336
- }
1337
- }
1338
-
1339
- // timezone with name: e.g. UTC
1340
- else
1341
- {
1342
- $momentDateTime = $this->format('Y-m-d\TH:i:se');
1343
- }
1344
- }
1345
-
1346
- // no timezone specified
1347
- else
1348
- {
1349
- $momentDateTime = $this->format('Y-m-d\TH:i:s');
1350
- }
1351
- }
1352
-
1353
- // time without indicator "T"
1354
- elseif (strpos($rawDateTime, ':') !== false)
1355
- {
1356
- // with seconds
1357
- if (substr_count($rawDateTime, ':') === 2)
1358
- {
1359
- $momentDateTime = $this->format(self::NO_TZ_MYSQL);
1360
- }
1361
- else
1362
- {
1363
- $momentDateTime = $this->format(self::NO_TZ_NO_SECS);
1364
- }
1365
- }
1366
-
1367
- // without time
1368
- else
1369
- {
1370
- $momentDateTime = $this->format(self::NO_TIME);
1371
- }
1372
-
1373
- $isValid = $rawDateTime === $momentDateTime;
1374
-
1375
- // TODO: hack until we include a proper validation
1376
-
1377
- if (!$isValid)
1378
- {
1379
- $rfcs = array(
1380
- self::RFC2822,
1381
- self::RFC822,
1382
- self::RFC1036,
1383
- );
1384
-
1385
- foreach ($rfcs as $rfc)
1386
- {
1387
- if ($this->format($rfc) === $rawDateTime)
1388
- {
1389
- return true;
1390
- }
1391
- }
1392
- }
1393
-
1394
- return $isValid;
1395
- }
1396
-
1397
- /**
1398
- * @param string $type
1399
- * @param int $value
1400
- *
1401
- * @return Moment
1402
- */
1403
- private function subtractTime($type = 'day', $value = 1)
1404
- {
1405
- if ($this->immutableMode)
1406
- {
1407
- return $this->implicitCloning(__FUNCTION__, func_get_args());
1408
- }
1409
-
1410
- parent::modify('-' . $value . ' ' . $type);
1411
-
1412
- return $this;
1413
- }
1414
-
1415
- /**
1416
- * @param int $number
1417
- * @param string $token
1418
- *
1419
- * @return string
1420
- * @throws MomentException
1421
- */
1422
- private function formatOrdinal($number, $token)
1423
- {
1424
- return (string)call_user_func(MomentLocale::getLocaleString(array('ordinal')), $number, $token);
1425
- }
1426
-
1427
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/MomentException.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts\Moment;
4
-
5
- /**
6
- * MomentException
7
- * @package Moment
8
- * @author Tino Ehrich (tino@bigpun.me)
9
- */
10
- class MomentException extends \Exception
11
- {
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/MomentFromVo.php DELETED
@@ -1,321 +0,0 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts\Moment;
4
-
5
- /**
6
- * MomentFromVo
7
- * @package Moment
8
- * @author Tino Ehrich (tino@bigpun.me)
9
- */
10
- class MomentFromVo
11
- {
12
- /**
13
- * @var Moment
14
- */
15
- protected $moment;
16
-
17
- /**
18
- * @var string
19
- */
20
- protected $direction;
21
-
22
- /**
23
- * @var int
24
- */
25
- protected $seconds;
26
-
27
- /**
28
- * @var float
29
- */
30
- protected $minutes;
31
-
32
- /**
33
- * @var float
34
- */
35
- protected $hours;
36
-
37
- /**
38
- * @var float
39
- */
40
- protected $days;
41
-
42
- /**
43
- * @var float
44
- */
45
- protected $weeks;
46
-
47
- /**
48
- * @var string
49
- */
50
- protected $relative;
51
-
52
- /**
53
- * @param Moment $moment
54
- */
55
- public function __construct(Moment $moment)
56
- {
57
- $this->moment = $moment;
58
- }
59
-
60
- /**
61
- * @return Moment
62
- */
63
- public function getMoment()
64
- {
65
- return $this->moment;
66
- }
67
-
68
- /**
69
- * @param $value
70
- *
71
- * @return float
72
- */
73
- protected function getRoundedValue($value)
74
- {
75
- $value = round($value, 2);
76
-
77
- if ($this->getDirection() === 'future')
78
- {
79
- $value = '-' . $value;
80
- }
81
-
82
- return (float)$value;
83
- }
84
-
85
- /**
86
- * @param string $direction
87
- *
88
- * @return MomentFromVo
89
- */
90
- public function setDirection($direction)
91
- {
92
- $this->direction = $direction;
93
-
94
- return $this;
95
- }
96
-
97
- /**
98
- * @return string
99
- */
100
- public function getDirection()
101
- {
102
- return $this->direction === '-' ? 'future' : 'past';
103
- }
104
-
105
- /**
106
- * @param float $days
107
- *
108
- * @return MomentFromVo
109
- */
110
- public function setDays($days)
111
- {
112
- $this->days = $days;
113
-
114
- return $this;
115
- }
116
-
117
- /**
118
- * @return float
119
- */
120
- public function getDays()
121
- {
122
- return $this->getRoundedValue($this->days);
123
- }
124
-
125
- /**
126
- * @param float $hours
127
- *
128
- * @return MomentFromVo
129
- */
130
- public function setHours($hours)
131
- {
132
- $this->hours = $hours;
133
-
134
- return $this;
135
- }
136
-
137
- /**
138
- * @return float
139
- */
140
- public function getHours()
141
- {
142
- return $this->getRoundedValue($this->hours);
143
- }
144
-
145
- /**
146
- * @param float $minutes
147
- *
148
- * @return MomentFromVo
149
- */
150
- public function setMinutes($minutes)
151
- {
152
- $this->minutes = $minutes;
153
-
154
- return $this;
155
- }
156
-
157
- /**
158
- * @return float
159
- */
160
- public function getMinutes()
161
- {
162
- return $this->getRoundedValue($this->minutes);
163
- }
164
-
165
- /**
166
- * @param int $seconds
167
- *
168
- * @return MomentFromVo
169
- */
170
- public function setSeconds($seconds)
171
- {
172
- $this->seconds = $seconds;
173
-
174
- return $this;
175
- }
176
-
177
- /**
178
- * @return int
179
- */
180
- public function getSeconds()
181
- {
182
- return (int)$this->getRoundedValue($this->seconds);
183
- }
184
-
185
- /**
186
- * @param mixed $weeks
187
- *
188
- * @return MomentFromVo
189
- */
190
- public function setWeeks($weeks)
191
- {
192
- $this->weeks = $weeks;
193
-
194
- return $this;
195
- }
196
-
197
- /**
198
- * @return float
199
- */
200
- public function getWeeks()
201
- {
202
- return $this->getRoundedValue($this->weeks);
203
- }
204
-
205
- /**
206
- * @return float
207
- */
208
- public function getMonths()
209
- {
210
- return $this->getRoundedValue($this->weeks / 4);
211
- }
212
-
213
- /**
214
- * @return float
215
- */
216
- public function getYears()
217
- {
218
- return $this->getRoundedValue($this->days / 365);
219
- }
220
-
221
- /**
222
- * @return string
223
- */
224
- public function getRelative()
225
- {
226
- $formatArgs = array();
227
-
228
- if ($this->valueInRange($this->getSeconds(), 0, 3))
229
- {
230
- $localeKeys = array('relativeTime', 's');
231
- $formatArgs[] = 1;
232
- }
233
- elseif ($this->valueInRange($this->getSeconds(), 4, 59))
234
- {
235
- $localeKeys = array('relativeTime', 'ss');
236
- $formatArgs[] = $this->roundAbs($this->getSeconds());
237
- }
238
- elseif ($this->valueInRange($this->getSeconds(), 60, 89))
239
- {
240
- $localeKeys = array('relativeTime', 'm');
241
- $formatArgs[] = 1;
242
- }
243
- elseif ($this->valueInRange($this->getSeconds(), 90, (45 * 60)-1))
244
- {
245
- $localeKeys = array('relativeTime', 'mm');
246
- $formatArgs[] = $this->roundAbs($this->getMinutes());
247
- }
248
- elseif ($this->valueInRange($this->getMinutes(), 45, 89))
249
- {
250
- $localeKeys = array('relativeTime', 'h');
251
- $formatArgs[] = 1;
252
- }
253
- elseif ($this->valueInRange($this->getMinutes(), 90, (22 * 60)-1))
254
- {
255
- $localeKeys = array('relativeTime', 'hh');
256
- $formatArgs[] = $this->roundAbs($this->getHours());
257
- }
258
- elseif ($this->valueInRange($this->getHours(), 22, 35))
259
- {
260
- $localeKeys = array('relativeTime', 'd');
261
- $formatArgs[] = 1;
262
- }
263
- elseif ($this->valueInRange($this->getHours(), 36, (25 * 24)-1))
264
- {
265
- $localeKeys = array('relativeTime', 'dd');
266
- $formatArgs[] = $this->roundAbs($this->getDays());
267
- }
268
- elseif ($this->valueInRange($this->getDays(), 25, 44))
269
- {
270
- $localeKeys = array('relativeTime', 'M');
271
- $formatArgs[] = 1;
272
- }
273
- elseif ($this->valueInRange($this->getDays(), 45, 344))
274
- {
275
- $localeKeys = array('relativeTime', 'MM');
276
- $formatArgs[] = $this->roundAbs($this->getMonths());
277
- }
278
- elseif ($this->valueInRange($this->getDays(), 345, 547))
279
- {
280
- $localeKeys = array('relativeTime', 'y');
281
- $formatArgs[] = 1;
282
- }
283
- else
284
- {
285
- $localeKeys = array('relativeTime', 'yy');
286
- $formatArgs[] = $this->roundAbs($this->getYears());
287
- }
288
-
289
- // add to context
290
- $formatArgs[] = $this->getDirection();
291
- $formatArgs[] = $this->getMoment();
292
-
293
- // render value
294
- $time = MomentLocale::renderLocaleString($localeKeys, $formatArgs);
295
-
296
- // render value result by direction string
297
- return MomentLocale::renderLocaleString(array('relativeTime', $this->getDirection()), array($time));
298
- }
299
-
300
- /**
301
- * @param $value
302
- * @param $from
303
- * @param $to
304
- *
305
- * @return bool
306
- */
307
- private function valueInRange($value, $from, $to)
308
- {
309
- return abs($value) >= $from && abs($value) <= $to ? true : false;
310
- }
311
-
312
- /**
313
- * @param $number
314
- *
315
- * @return float
316
- */
317
- private function roundAbs($number)
318
- {
319
- return round(abs($number));
320
- }
321
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/MomentHelper.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts\Moment;
4
-
5
- /**
6
- * MomentHelper
7
- * @package Moment
8
- * @author Tino Ehrich (tino@bigpun.me)
9
- */
10
- class MomentHelper
11
- {
12
- /**
13
- * @param $quarter
14
- * @param $year
15
- * @param string $timeZoneString
16
- *
17
- * @return MomentPeriodVo
18
- * @throws MomentException
19
- */
20
- public static function getQuarterPeriod($quarter, $year, $timeZoneString = 'UTC')
21
- {
22
- switch ($quarter)
23
- {
24
- case 1:
25
- $startMonth = 1;
26
- $endMonth = 3;
27
- break;
28
- case 2:
29
- $startMonth = 4;
30
- $endMonth = 6;
31
- break;
32
- case 3:
33
- $startMonth = 7;
34
- $endMonth = 9;
35
- break;
36
- case 4:
37
- $startMonth = 10;
38
- $endMonth = 12;
39
- break;
40
- default:
41
- throw new MomentException('Invalid quarter. The range of quarters is 1 - 4. You asked for: ' . $quarter);
42
- }
43
-
44
- // set start
45
- $start = new Moment();
46
- $start
47
- ->setTimezone($timeZoneString)
48
- ->setYear($year)
49
- ->setMonth($startMonth)
50
- ->setDay(1)
51
- ->setTime(0, 0, 0);
52
-
53
- // set end
54
- $end = new Moment();
55
- $end
56
- ->setTimezone($timeZoneString)
57
- ->setYear($year)
58
- ->setMonth($endMonth)
59
- ->setDay($end->format('t'))
60
- ->setTime(23, 59, 59);
61
-
62
- // set period vo
63
- $momentPeriodVo = new MomentPeriodVo();
64
-
65
- return $momentPeriodVo
66
- ->setInterval($quarter)
67
- ->setStartDate($start)
68
- ->setEndDate($end);
69
- }
70
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/MomentLocale.php DELETED
@@ -1,227 +0,0 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts\Moment;
4
-
5
- /**
6
- * MomentLocale
7
- * @package Moment
8
- * @author Tino Ehrich (tino@bigpun.me)
9
- */
10
- class MomentLocale
11
- {
12
- /**
13
- * @var Moment
14
- */
15
- private static $moment;
16
-
17
- /**
18
- * @var string
19
- */
20
- private static $locale = 'en_GB';
21
-
22
- /**
23
- * @var boolean
24
- */
25
- private static $findSimilar = false;
26
-
27
- /**
28
- * @var array
29
- */
30
- private static $localeContent = array();
31
-
32
- /**
33
- * @param Moment $moment
34
- */
35
- public static function setMoment(Moment $moment)
36
- {
37
- self::$moment = $moment;
38
- }
39
-
40
- /**
41
- * @param string $locale
42
- * @param bool $findSimilar
43
- *
44
- * @return void
45
- * @throws MomentException
46
- */
47
- public static function setLocale($locale, $findSimilar = false)
48
- {
49
- self::$locale = $locale;
50
- self::$findSimilar = $findSimilar;
51
- self::loadLocaleContent();
52
- }
53
-
54
- /**
55
- * @return void
56
- * @throws MomentException
57
- */
58
- public static function loadLocaleContent()
59
- {
60
- $pathFile = self::findLocaleFile();
61
-
62
- if (!$pathFile)
63
- {
64
- throw new MomentException('Locale does not exist: ' . $pathFile);
65
- }
66
-
67
- /** @noinspection PhpIncludeInspection */
68
- self::$localeContent = require $pathFile;
69
- }
70
-
71
- /**
72
- * @return array
73
- */
74
- public static function getLocaleContent()
75
- {
76
- return self::$localeContent;
77
- }
78
-
79
- /**
80
- * @param array $keys
81
- *
82
- * @return array|string|\Closure
83
- * @throws MomentException
84
- */
85
- public static function getLocaleString(array $keys)
86
- {
87
- $string = self::$localeContent;
88
-
89
- foreach ($keys as $key)
90
- {
91
- if (isset($string[$key]) === false)
92
- {
93
- if ($key == 'monthsNominative' && isset($string['months']))
94
- {
95
- $string = $string['months'];
96
- continue;
97
- }
98
-
99
- throw new MomentException('Locale string does not exist for key: ' . join(' > ', $keys));
100
- }
101
-
102
- $string = $string[$key];
103
- }
104
-
105
- return $string;
106
- }
107
-
108
- /**
109
- * @param array $localeKeys
110
- * @param array $formatArgs
111
- *
112
- * @return string
113
- * @throws MomentException
114
- */
115
- public static function renderLocaleString(array $localeKeys, array $formatArgs = array())
116
- {
117
- // get locale handler
118
- $localeString = self::getLocaleString($localeKeys);
119
-
120
- // handle callback
121
- if ($localeString instanceof \Closure)
122
- {
123
- $localeString = call_user_func_array($localeString, $formatArgs);
124
- }
125
-
126
- return vsprintf($localeString, $formatArgs);
127
- }
128
-
129
- /**
130
- * @param string $format
131
- *
132
- * @return string
133
- */
134
- public static function prepareSpecialLocaleTags($format)
135
- {
136
- $placeholders = array(
137
- // months
138
- '(?<!\\\)F' => 'n__0001',
139
- '(?<!\\\)M' => 'n__0002',
140
- '(?<!\\\)f' => 'n__0005',
141
- // weekdays
142
- '(?<!\\\)l' => 'N__0003',
143
- '(?<!\\\)D' => 'N__0004',
144
- );
145
-
146
- foreach ($placeholders as $regexp => $tag)
147
- {
148
- $format = preg_replace('/' . $regexp . '/u', $tag, $format);
149
- }
150
-
151
- return $format;
152
- }
153
-
154
- /**
155
- * @param string $format
156
- *
157
- * @return string
158
- * @throws MomentException
159
- */
160
- public static function renderSpecialLocaleTags($format)
161
- {
162
- $placeholders = array(
163
- // months
164
- '\d{1,2}__0001' => 'months',
165
- '\d{1,2}__0002' => 'monthsShort',
166
- '\d{1,2}__0005' => 'monthsNominative',
167
- // weekdays
168
- '\d__0003' => 'weekdays',
169
- '\d__0004' => 'weekdaysShort',
170
- );
171
-
172
- foreach ($placeholders as $regexp => $tag)
173
- {
174
- preg_match_all('/(' . $regexp . ')/', $format, $match);
175
-
176
- if (isset($match[1]))
177
- {
178
- foreach ($match[1] as $date)
179
- {
180
- list($localeIndex, $type) = explode('__', $date);
181
- $localeString = self::renderLocaleString(array($tag, --$localeIndex));
182
- $format = preg_replace('/' . $date . '/u', $localeString, $format);
183
- }
184
- }
185
- }
186
-
187
- return $format;
188
- }
189
-
190
- /**
191
- * @return null|string
192
- */
193
- private static function findLocaleFile()
194
- {
195
- $basePathFile = __DIR__ . '/Locales/' . self::$locale;
196
- $pathFile = $basePathFile . '.php';
197
-
198
- if (file_exists($pathFile) === false)
199
- {
200
- $pathFile = null;
201
-
202
- if (self::$findSimilar && $similarLocales = self::fetchSimilarLocales($basePathFile))
203
- {
204
- $pathFile = $similarLocales[0];
205
- }
206
- }
207
-
208
- return $pathFile;
209
- }
210
-
211
- /**
212
- * @param string $path
213
- *
214
- * @return null|array
215
- */
216
- private static function fetchSimilarLocales($path)
217
- {
218
- $locales = glob($path . '*.php');
219
-
220
- if ($locales && !empty($locales))
221
- {
222
- return $locales;
223
- }
224
-
225
- return null;
226
- }
227
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Moment/MomentPeriodVo.php DELETED
@@ -1,103 +0,0 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts\Moment;
4
-
5
- /**
6
- * MomentPeriodVo
7
- * @package Moment
8
- * @author Tino Ehrich (tino@bigpun.me)
9
- */
10
- class MomentPeriodVo
11
- {
12
- /** @var Moment */
13
- protected $startDate;
14
-
15
- /** @var Moment */
16
- protected $endDate;
17
-
18
- /** @var Moment */
19
- protected $refDate;
20
-
21
- /** @var int */
22
- protected $interval;
23
-
24
- /**
25
- * @return int
26
- */
27
- public function getInterval()
28
- {
29
- return $this->interval;
30
- }
31
-
32
- /**
33
- * @param int $interval
34
- *
35
- * @return MomentPeriodVo
36
- */
37
- public function setInterval($interval)
38
- {
39
- $this->interval = $interval;
40
-
41
- return $this;
42
- }
43
-
44
- /**
45
- * @param Moment $reference
46
- *
47
- * @return MomentPeriodVo
48
- */
49
- public function setRefDate(Moment $reference)
50
- {
51
- $this->refDate = $reference;
52
-
53
- return $this;
54
- }
55
-
56
- /**
57
- * @return \Moment\Moment
58
- */
59
- public function getRefDate()
60
- {
61
- return $this->refDate;
62
- }
63
-
64
- /**
65
- * @param Moment $end
66
- *
67
- * @return MomentPeriodVo
68
- */
69
- public function setEndDate(Moment $end)
70
- {
71
- $this->endDate = $end;
72
-
73
- return $this;
74
- }
75
-
76
- /**
77
- * @return Moment
78
- */
79
- public function getEndDate()
80
- {
81
- return $this->endDate;
82
- }
83
-
84
- /**
85
- * @param Moment $start
86
- *
87
- * @return MomentPeriodVo
88
- */
89
- public function setStartDate(Moment $start)
90
- {
91
- $this->startDate = $start;
92
-
93
- return $this;
94
- }
95
-
96
- /**
97
- * @return Moment
98
- */
99
- public function getStartDate()
100
- {
101
- return $this->startDate;
102
- }
103
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Output.php CHANGED
@@ -85,7 +85,7 @@ class Output {
85
  * @param WordPressPopularPosts\Translate $translate
86
  * @param \WordPressPopularPosts\Themer $themer
87
  */
88
- public function __construct(array $public_options = [], array $admin_options = [], Image $thumbnail, Translate $translate, \WordPressPopularPosts\Themer $themer)
89
  {
90
  $this->public_options = $public_options;
91
  $this->admin_options = $admin_options;
@@ -156,7 +156,7 @@ class Output {
156
  // Got some posts, format 'em!
157
  if ( ! empty($this->data) ) {
158
 
159
- $this->output = "\n" . "<!-- WordPress Popular Posts" . ( WP_DEBUG ? ' v' . WPP_VERSION : '' ) . " -->" . "\n";
160
 
161
  // Allow WP themers / coders access to raw data
162
  // so they can build their own output
@@ -171,7 +171,12 @@ class Output {
171
  ) {
172
  $this->output .= '<div class="popular-posts-sr">';
173
 
174
- $theme_stylesheet = $this->themer->get_theme($this->public_options['theme']['name'])['path'] . '/style.css';
 
 
 
 
 
175
  $theme_css_rules = wp_strip_all_tags(file_get_contents($theme_stylesheet), true);
176
  $additional_styles = '';
177
 
@@ -285,7 +290,7 @@ class Output {
285
  }
286
 
287
  // Thumbnail
288
- $post_thumbnail = $this->get_thumbnail($post_object);
289
 
290
  // Post excerpt
291
  $post_excerpt = $this->get_excerpt($post_object, $post_id);
@@ -313,7 +318,35 @@ class Output {
313
  $post_comments = $this->get_comments($post_object);
314
 
315
  // Post meta
316
- $post_meta = join(' | ', $this->get_metadata($post_object, $post_id));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
 
318
  $prettify_numbers = apply_filters('wpp_pretiffy_numbers', true);
319
 
@@ -330,10 +363,15 @@ class Output {
330
  'url' => $permalink,
331
  'text_title' => $post_title,
332
  'taxonomy' => $post_taxonomies,
 
333
  'author' => ( ! empty($post_author) ) ? '<a href="' . get_author_posts_url($post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid ) . '">' . $post_author . '</a>' : '',
 
334
  'views' => ( $this->public_options['order_by'] == "views" || $this->public_options['order_by'] == "comments" ) ? ($prettify_numbers ? Helper::prettify_number($post_views) : number_format_i18n($post_views)) : ($prettify_numbers ? Helper::prettify_number($post_views, 2) : number_format_i18n($post_views, 2)),
 
335
  'comments' => $prettify_numbers ? Helper::prettify_number($post_comments) : number_format_i18n($post_comments),
 
336
  'date' => $post_date,
 
337
  'total_items' => count($this->data),
338
  'item_position' => $position
339
  ];
@@ -413,11 +451,11 @@ class Output {
413
  * @return string
414
  */
415
  private function get_permalink(\stdClass $post_object, $post_id) {
416
- $permalink = get_permalink($post_object->id);
 
 
417
 
418
- return $post_object->id != $post_id
419
- ? $this->translate->url($permalink, $this->translate->get_current_language())
420
- : $permalink;
421
  }
422
 
423
  /**
@@ -425,16 +463,16 @@ class Output {
425
  *
426
  * @since 3.0.0
427
  * @access private
428
- * @param object $post_object
429
  * @return string
430
  */
431
- private function get_thumbnail(\stdClass $post_object)
432
  {
433
  $thumbnail = '';
434
 
435
  if ( $this->public_options['thumbnail']['active'] ) {
436
  $thumbnail = $this->thumbnail->get(
437
- $post_object,
438
  [
439
  $this->public_options['thumbnail']['width'],
440
  $this->public_options['thumbnail']['height']
@@ -547,23 +585,9 @@ class Output {
547
  $date = '';
548
 
549
  if ( $this->public_options['stats_tag']['date']['active'] ) {
550
- // Check locale
551
- if ( ! $current_language_locale = $this->translate->get_locale($this->translate->get_current_language()) ) {
552
- $current_language_locale = get_locale();
553
- }
554
-
555
- try {
556
- Moment\Moment::setLocale($current_language_locale);
557
- } // Locale not found, fallback to English (US)
558
- catch( \Exception $e ) {
559
- Moment\Moment::setLocale('en_US');
560
- }
561
-
562
- $m = new Moment\Moment('@' . strtotime($post_object->date));
563
-
564
- $date = ( 'relative' == $this->public_options['stats_tag']['date']['format'] )
565
- ? $m->fromNow()->getRelative()
566
- : $m->format($this->public_options['stats_tag']['date']['format']);
567
  }
568
 
569
  return $date;
@@ -619,7 +643,7 @@ class Output {
619
  continue;
620
 
621
  $term_link = $this->translate->url($term_link, $this->translate->get_current_language());
622
- $post_tax .= "<a href=\"{$term_link}\" class=\"{$taxonomy} {$taxonomy}-{$term->term_id}\">{$term->name}</a>" . $taxonomy_separator;
623
  }
624
  }
625
  }
@@ -704,7 +728,8 @@ class Output {
704
  * @param integer $post_id
705
  * @return array
706
  */
707
- private function get_metadata(\stdClass $post_object, $post_id)
 
708
  {
709
  $stats = [];
710
 
@@ -712,18 +737,16 @@ class Output {
712
 
713
  // comments
714
  if ( $this->public_options['stats_tag']['comment_count'] ) {
715
- $comments = $this->get_comments($post_object);
716
-
717
  $comments_text = sprintf(
718
  _n('%s comment', '%s comments', $comments, 'wordpress-popular-posts'),
719
  $prettify_numbers ? Helper::prettify_number($comments) : number_format_i18n($comments)
720
  );
 
 
721
  }
722
 
723
  // views
724
  if ( $this->public_options['stats_tag']['views'] ) {
725
- $pageviews = $this->get_pageviews($post_object);
726
-
727
  if ( $this->public_options['order_by'] == 'avg' ) {
728
  $views_text = sprintf(
729
  _n('%s view per day', '%s views per day', $pageviews, 'wordpress-popular-posts'),
@@ -736,41 +759,25 @@ class Output {
736
  $prettify_numbers ? Helper::prettify_number($pageviews) : number_format_i18n($pageviews)
737
  );
738
  }
739
- }
740
 
741
- if ( "comments" == $this->public_options['order_by'] ) {
742
- if ( $this->public_options['stats_tag']['comment_count'] )
743
- $stats[] = '<span class="wpp-comments">' . $comments_text . '</span>'; // First comments count
744
- if ( $this->public_options['stats_tag']['views'] )
745
- $stats[] = '<span class="wpp-views">' . $views_text . "</span>"; // ... then views
746
- } else {
747
- if ( $this->public_options['stats_tag']['views'] )
748
- $stats[] = '<span class="wpp-views">' . $views_text . "</span>"; // First views count
749
- if ( $this->public_options['stats_tag']['comment_count'] )
750
- $stats[] = '<span class="wpp-comments">' . $comments_text . '</span>'; // ... then comments
751
  }
752
 
753
  // author
754
  if ( $this->public_options['stats_tag']['author'] ) {
755
- $author = $this->get_author($post_object, $post_id);
756
  $author_url = get_author_posts_url($post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid);
757
  $display_name = '<a href="' . $this->translate->url($author_url, $this->translate->get_current_language()) . '">' . $author . '</a>';
758
- $stats[] = '<span class="wpp-author">' . sprintf(__('by %s', 'wordpress-popular-posts'), $display_name) . '</span>';
759
  }
760
 
761
  // date
762
  if ( $this->public_options['stats_tag']['date']['active'] ) {
763
- $date = $this->get_date($post_object);
764
- $stats[] = '<span class="wpp-date">' . ( 'relative' == $this->public_options['stats_tag']['date']['format'] ? sprintf(__('posted %s', 'wordpress-popular-posts'), $date) : sprintf(__('posted on %s', 'wordpress-popular-posts'), $date) ) . '</span>';
765
  }
766
 
767
  // taxonomy
768
- if ( $this->public_options['stats_tag']['category'] ) {
769
- $post_tax = $this->get_taxonomies($post_id);
770
-
771
- if ( $post_tax != '' ) {
772
- $stats[] = '<span class="wpp-category">' . sprintf(__('under %s', 'wordpress-popular-posts'), $post_tax) . '</span>';
773
- }
774
  }
775
 
776
  return $stats;
@@ -786,13 +793,13 @@ class Output {
786
  * @param bool Used to display post rating (if functionality is available)
787
  * @return string
788
  */
789
- private function format_content($string, $data = [], $rating) {
790
 
791
  if ( empty($string) || ( empty($data) || ! is_array($data) ) )
792
  return false;
793
 
794
  $params = [];
795
- $pattern = '/\{(pid|excerpt|summary|meta|stats|title|title_attr|image|thumb|thumb_img|thumb_url|rating|score|url|text_title|author|taxonomy|category|views|comments|date|total_items|item_position)\}/i';
796
  preg_match_all($pattern, $string, $matches);
797
 
798
  array_map('strtolower', $matches[0]);
@@ -867,22 +874,42 @@ class Output {
867
  $string = str_replace("{author}", $data['author'], $string);
868
  }
869
 
 
 
 
 
870
  if ( in_array("{taxonomy}", $matches[0]) || in_array("{category}", $matches[0]) ) {
871
  $string = str_replace(["{taxonomy}", "{category}"], $data['taxonomy'], $string);
872
  }
873
 
 
 
 
 
874
  if ( in_array("{views}", $matches[0]) ) {
875
  $string = str_replace("{views}", $data['views'], $string);
876
  }
877
 
 
 
 
 
878
  if ( in_array("{comments}", $matches[0]) ) {
879
  $string = str_replace("{comments}", $data['comments'], $string);
880
  }
881
 
 
 
 
 
882
  if ( in_array("{date}", $matches[0]) ) {
883
  $string = str_replace("{date}", $data['date'], $string);
884
  }
885
 
 
 
 
 
886
  if ( in_array("{total_items}", $matches[0]) ) {
887
  $string = str_replace("{total_items}", $data['total_items'], $string);
888
  }
85
  * @param WordPressPopularPosts\Translate $translate
86
  * @param \WordPressPopularPosts\Themer $themer
87
  */
88
+ public function __construct(array $public_options, array $admin_options, Image $thumbnail, Translate $translate, \WordPressPopularPosts\Themer $themer)
89
  {
90
  $this->public_options = $public_options;
91
  $this->admin_options = $admin_options;
156
  // Got some posts, format 'em!
157
  if ( ! empty($this->data) ) {
158
 
159
+ $this->output = "\n" . ( WP_DEBUG ? '<!-- WordPress Popular Posts v' . WPP_VERSION . ( $this->admin_options['tools']['cache']['active'] ? ' - cached' : '' ) . ' -->' : '' ) . "\n";
160
 
161
  // Allow WP themers / coders access to raw data
162
  // so they can build their own output
171
  ) {
172
  $this->output .= '<div class="popular-posts-sr">';
173
 
174
+ if ( @file_exists(get_template_directory() . '/wordpress-popular-posts/themes/' . $this->public_options['theme']['name'] . '/style.css') ) {
175
+ $theme_stylesheet = get_template_directory() . '/wordpress-popular-posts/themes/' . $this->public_options['theme']['name'] . '/style.css';
176
+ } else {
177
+ $theme_stylesheet = $this->themer->get_theme($this->public_options['theme']['name'])['path'] . '/style.css';
178
+ }
179
+
180
  $theme_css_rules = wp_strip_all_tags(file_get_contents($theme_stylesheet), true);
181
  $additional_styles = '';
182
 
290
  }
291
 
292
  // Thumbnail
293
+ $post_thumbnail = $this->get_thumbnail($post_id);
294
 
295
  // Post excerpt
296
  $post_excerpt = $this->get_excerpt($post_object, $post_id);
318
  $post_comments = $this->get_comments($post_object);
319
 
320
  // Post meta
321
+ $meta_arr = $this->get_metadata(
322
+ $post_object,
323
+ $post_id,
324
+ $post_date,
325
+ $post_taxonomies,
326
+ $post_author,
327
+ $post_views,
328
+ $post_comments
329
+ );
330
+
331
+ if (
332
+ is_array($meta_arr)
333
+ && ! empty($meta_arr)
334
+ && "views" == $this->public_options['order_by']
335
+ ) {
336
+ $keys = ['views', 'comments', 'author', 'date', 'taxonomy'];
337
+ $new_meta_arr = [];
338
+
339
+ foreach($keys as $key) {
340
+ if ( isset($meta_arr[$key]))
341
+ $new_meta_arr[$key] = $meta_arr[$key];
342
+ }
343
+
344
+ if ( ! empty($new_meta_arr) )
345
+ $meta_arr = $new_meta_arr;
346
+ }
347
+
348
+ $post_meta_separator = apply_filters('wpp_post_meta_separator', ' | ');
349
+ $post_meta = join($post_meta_separator, $meta_arr);
350
 
351
  $prettify_numbers = apply_filters('wpp_pretiffy_numbers', true);
352
 
363
  'url' => $permalink,
364
  'text_title' => $post_title,
365
  'taxonomy' => $post_taxonomies,
366
+ 'taxonomy_copy' => isset($meta_arr['taxonomy']) ? $meta_arr['taxonomy'] : null,
367
  'author' => ( ! empty($post_author) ) ? '<a href="' . get_author_posts_url($post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid ) . '">' . $post_author . '</a>' : '',
368
+ 'author_copy' => isset($meta_arr['author']) ? $meta_arr['author'] : null,
369
  'views' => ( $this->public_options['order_by'] == "views" || $this->public_options['order_by'] == "comments" ) ? ($prettify_numbers ? Helper::prettify_number($post_views) : number_format_i18n($post_views)) : ($prettify_numbers ? Helper::prettify_number($post_views, 2) : number_format_i18n($post_views, 2)),
370
+ 'views_copy' => isset($meta_arr['views']) ? $meta_arr['views'] : null,
371
  'comments' => $prettify_numbers ? Helper::prettify_number($post_comments) : number_format_i18n($post_comments),
372
+ 'comments_copy' => isset($meta_arr['comments']) ? $meta_arr['comments'] : null,
373
  'date' => $post_date,
374
+ 'date_copy' => isset($meta_arr['date']) ? $meta_arr['date'] : null,
375
  'total_items' => count($this->data),
376
  'item_position' => $position
377
  ];
451
  * @return string
452
  */
453
  private function get_permalink(\stdClass $post_object, $post_id) {
454
+ if ( $post_object->id != $post_id ) {
455
+ return get_permalink($post_id);
456
+ }
457
 
458
+ return get_permalink($post_object->id);
 
 
459
  }
460
 
461
  /**
463
  *
464
  * @since 3.0.0
465
  * @access private
466
+ * @param int $post_id
467
  * @return string
468
  */
469
+ private function get_thumbnail($post_id)
470
  {
471
  $thumbnail = '';
472
 
473
  if ( $this->public_options['thumbnail']['active'] ) {
474
  $thumbnail = $this->thumbnail->get(
475
+ $post_id,
476
  [
477
  $this->public_options['thumbnail']['width'],
478
  $this->public_options['thumbnail']['height']
585
  $date = '';
586
 
587
  if ( $this->public_options['stats_tag']['date']['active'] ) {
588
+ $date = ( 'relative' == $this->public_options['stats_tag']['date']['format'] )
589
+ ? sprintf(__('%s ago', 'wordpress-popular-posts'), human_time_diff(strtotime($post_object->date), current_time('timestamp')))
590
+ : date_i18n($this->public_options['stats_tag']['date']['format'], strtotime($post_object->date));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
591
  }
592
 
593
  return $date;
643
  continue;
644
 
645
  $term_link = $this->translate->url($term_link, $this->translate->get_current_language());
646
+ $post_tax .= "<a href=\"{$term_link}\" class=\"wpp-taxonomy {$taxonomy} {$taxonomy}-{$term->term_id}\">{$term->name}</a>" . $taxonomy_separator;
647
  }
648
  }
649
  }
728
  * @param integer $post_id
729
  * @return array
730
  */
731
+ //private function get_metadata(\stdClass $post_object, $post_id)
732
+ private function get_metadata(\stdClass $post_object, $post_id, $date, $post_tax, $author, $pageviews, $comments)
733
  {
734
  $stats = [];
735
 
737
 
738
  // comments
739
  if ( $this->public_options['stats_tag']['comment_count'] ) {
 
 
740
  $comments_text = sprintf(
741
  _n('%s comment', '%s comments', $comments, 'wordpress-popular-posts'),
742
  $prettify_numbers ? Helper::prettify_number($comments) : number_format_i18n($comments)
743
  );
744
+
745
+ $stats['comments'] = '<span class="wpp-comments">' . $comments_text . '</span>';
746
  }
747
 
748
  // views
749
  if ( $this->public_options['stats_tag']['views'] ) {
 
 
750
  if ( $this->public_options['order_by'] == 'avg' ) {
751
  $views_text = sprintf(
752
  _n('%s view per day', '%s views per day', $pageviews, 'wordpress-popular-posts'),
759
  $prettify_numbers ? Helper::prettify_number($pageviews) : number_format_i18n($pageviews)
760
  );
761
  }
 
762
 
763
+ $stats['views'] = '<span class="wpp-views">' . $views_text . "</span>";
 
 
 
 
 
 
 
 
 
764
  }
765
 
766
  // author
767
  if ( $this->public_options['stats_tag']['author'] ) {
 
768
  $author_url = get_author_posts_url($post_object->uid != $post_id ? get_post_field('post_author', $post_id) : $post_object->uid);
769
  $display_name = '<a href="' . $this->translate->url($author_url, $this->translate->get_current_language()) . '">' . $author . '</a>';
770
+ $stats['author'] = '<span class="wpp-author">' . sprintf(__('by %s', 'wordpress-popular-posts'), $display_name) . '</span>';
771
  }
772
 
773
  // date
774
  if ( $this->public_options['stats_tag']['date']['active'] ) {
775
+ $stats['date'] = '<span class="wpp-date">' . ( 'relative' == $this->public_options['stats_tag']['date']['format'] ? sprintf(__('posted %s', 'wordpress-popular-posts'), $date) : sprintf(__('posted on %s', 'wordpress-popular-posts'), $date) ) . '</span>';
 
776
  }
777
 
778
  // taxonomy
779
+ if ( $this->public_options['stats_tag']['category'] && $post_tax != '' ) {
780
+ $stats['taxonomy'] = '<span class="wpp-category">' . sprintf(__('under %s', 'wordpress-popular-posts'), $post_tax) . '</span>';
 
 
 
 
781
  }
782
 
783
  return $stats;
793
  * @param bool Used to display post rating (if functionality is available)
794
  * @return string
795
  */
796
+ private function format_content($string, $data, $rating) {
797
 
798
  if ( empty($string) || ( empty($data) || ! is_array($data) ) )
799
  return false;
800
 
801
  $params = [];
802
+ $pattern = '/\{(pid|excerpt|summary|meta|stats|title|title_attr|image|thumb|thumb_img|thumb_url|rating|score|url|text_title|author|author_copy|taxonomy|taxonomy_copy|category|category_copy|views|views_copy|comments|comments_copy|date|date_copy|total_items|item_position)\}/i';
803
  preg_match_all($pattern, $string, $matches);
804
 
805
  array_map('strtolower', $matches[0]);
874
  $string = str_replace("{author}", $data['author'], $string);
875
  }
876
 
877
+ if ( in_array("{author_copy}", $matches[0]) ) {
878
+ $string = str_replace("{author_copy}", $data['author_copy'], $string);
879
+ }
880
+
881
  if ( in_array("{taxonomy}", $matches[0]) || in_array("{category}", $matches[0]) ) {
882
  $string = str_replace(["{taxonomy}", "{category}"], $data['taxonomy'], $string);
883
  }
884
 
885
+ if ( in_array("{taxonomy_copy}", $matches[0]) || in_array("{category_copy}", $matches[0]) ) {
886
+ $string = str_replace(["{taxonomy_copy}", "{category_copy}"], $data['taxonomy_copy'], $string);
887
+ }
888
+
889
  if ( in_array("{views}", $matches[0]) ) {
890
  $string = str_replace("{views}", $data['views'], $string);
891
  }
892
 
893
+ if ( in_array("{views_copy}", $matches[0]) ) {
894
+ $string = str_replace("{views_copy}", $data['views_copy'], $string);
895
+ }
896
+
897
  if ( in_array("{comments}", $matches[0]) ) {
898
  $string = str_replace("{comments}", $data['comments'], $string);
899
  }
900
 
901
+ if ( in_array("{comments_copy}", $matches[0]) ) {
902
+ $string = str_replace("{comments_copy}", $data['comments_copy'], $string);
903
+ }
904
+
905
  if ( in_array("{date}", $matches[0]) ) {
906
  $string = str_replace("{date}", $data['date'], $string);
907
  }
908
 
909
+ if ( in_array("{date_copy}", $matches[0]) ) {
910
+ $string = str_replace("{date_copy}", $data['date_copy'], $string);
911
+ }
912
+
913
  if ( in_array("{total_items}", $matches[0]) ) {
914
  $string = str_replace("{total_items}", $data['total_items'], $string);
915
  }
src/Rest/Controller.php CHANGED
@@ -1,47 +1,44 @@
1
  <?php
2
  namespace WordPressPopularPosts\Rest;
3
 
4
- use WordPressPopularPosts\Helper;
5
- use WordPressPopularPosts\Query;
6
-
7
- class Controller extends \WP_REST_Controller {
8
 
9
  /**
10
- * Plugin options.
11
  *
12
- * @var array $config
13
  * @access private
14
  */
15
- private $config;
16
 
17
  /**
18
- * Translate object.
19
  *
20
- * @var \WordPressPopularPosts\Translate $translate
21
  * @access private
22
  */
23
- private $translate;
24
 
25
  /**
26
- * Output object.
27
  *
28
- * @var \WordPressPopularPosts\Output $output
29
  * @access private
30
  */
31
- private $output;
32
 
33
  /**
34
  * Initialize class.
35
  *
36
- * @param array
37
- * @param \WordPressPopularPosts\Translate
38
- * @param \WordPressPopularPosts\Output
39
  */
40
- public function __construct(array $config, \WordPressPopularPosts\Translate $translate, \WordPressPopularPosts\Output $output)
41
  {
42
- $this->config = $config;
43
- $this->translate = $translate;
44
- $this->output = $output;
45
  }
46
 
47
  /**
@@ -59,550 +56,8 @@ class Controller extends \WP_REST_Controller {
59
  */
60
  public function register_routes()
61
  {
62
- $version = '1';
63
- $namespace = 'wordpress-popular-posts/v' . $version;
64
-
65
- register_rest_route($namespace, '/popular-posts', [
66
- [
67
- 'methods' => \WP_REST_Server::READABLE,
68
- 'callback' => [$this, 'get_items'],
69
- 'permission_callback' => '__return_true',
70
- 'args' => $this->get_collection_params()
71
- ],
72
- [
73
- 'methods' => \WP_REST_Server::CREATABLE,
74
- 'callback' => [$this, 'update_views_count'],
75
- 'permission_callback' => '__return_true',
76
- 'args' => $this->get_tracking_params(),
77
- ]
78
- ]);
79
-
80
- // Widget endpoint
81
- register_rest_route($namespace, '/popular-posts/widget/(?P<id>[\d]+)', [
82
- [
83
- 'methods' => \WP_REST_Server::READABLE,
84
- 'callback' => [$this, 'get_widget'],
85
- 'permission_callback' => '__return_true',
86
- 'args' => $this->get_widget_params(),
87
- ]
88
- ]);
89
- }
90
-
91
- /**
92
- * Gets popular posts.
93
- *
94
- * @since 1.0.0
95
- * @param \WP_REST_Request $request Full data about the request.
96
- * @return \WP_REST_Response
97
- */
98
- public function get_items($request)
99
- {
100
- $params = $request->get_params();
101
- $popular_posts = [];
102
-
103
- $query = $this->maybe_query($params);
104
- $results = $query->get_posts();
105
-
106
- if ( is_array($results) && ! empty($results) ) {
107
- foreach( $results as $popular_post ) {
108
- $popular_posts[] = $this->prepare_item($popular_post, $request);
109
- }
110
- }
111
-
112
- return new \WP_REST_Response($popular_posts, 200);
113
- }
114
-
115
- /**
116
- * Updates the views count of a post / page.
117
- *
118
- * @since 4.1.0
119
- *
120
- * @param \WP_REST_Request $request Full details about the request.
121
- * @return string
122
- */
123
- public function update_views_count($request){
124
- global $wpdb;
125
-
126
- $post_ID = $request->get_param('wpp_id');
127
- $sampling = $request->get_param('sampling');
128
- $sampling_rate = $request->get_param('sampling_rate');
129
-
130
- $table = $wpdb->prefix . "popularposts";
131
- $wpdb->show_errors();
132
-
133
- // Get translated object ID
134
- $post_ID = $this->translate->get_object_id(
135
- $post_ID,
136
- get_post_type($post_ID),
137
- true,
138
- $this->translate->get_default_language()
139
- );
140
-
141
- $now = Helper::now();
142
- $curdate = Helper::curdate();
143
- $views = ($sampling)
144
- ? $sampling_rate
145
- : 1;
146
-
147
- // Allow WP themers / coders perform an action
148
- // before updating views count
149
- if ( has_action('wpp_pre_update_views') )
150
- do_action('wpp_pre_update_views', $post_ID, $views);
151
-
152
- $result1 = $result2 = false;
153
-
154
- $exec_time = 0;
155
- $start = Helper::microtime_float();
156
-
157
- // Store views data in persistent object cache
158
- if (
159
- wp_using_ext_object_cache()
160
- && defined('WPP_CACHE_VIEWS')
161
- && WPP_CACHE_VIEWS
162
- ) {
163
-
164
- $now_datetime = new \DateTime($now, new \DateTimeZone(Helper::get_timezone()));
165
- $timestamp = $now_datetime->getTimestamp();
166
- $date_time = $now_datetime->format('Y-m-d H:i');
167
- $date_time_with_seconds = $now_datetime->format('Y-m-d H:i:s');
168
- $high_accuracy = false;
169
-
170
- $key = $high_accuracy ? $timestamp : $date_time;
171
-
172
- if ( ! $wpp_cache = wp_cache_get('_wpp_cache', 'transient') ) {
173
- $wpp_cache = [
174
- 'last_updated' => $date_time_with_seconds,
175
- 'data' => [
176
- $post_ID => [
177
- $key => 1
178
- ]
179
- ]
180
- ];
181
- } else {
182
- if ( ! isset($wpp_cache['data'][$post_ID][$key]) ) {
183
- $wpp_cache['data'][$post_ID][$key] = 1;
184
- } else {
185
- $wpp_cache['data'][$post_ID][$key] += 1;
186
- }
187
- }
188
-
189
- // Update cache
190
- wp_cache_set('_wpp_cache', $wpp_cache, 'transient', 0);
191
-
192
- // How long has it been since the last time we saved to the database?
193
- $last_update = $now_datetime->diff(new \DateTime($wpp_cache['last_updated'], new \DateTimeZone(Helper::get_timezone())));
194
- $diff_in_minutes = $last_update->days * 24 * 60;
195
- $diff_in_minutes += $last_update->h * 60;
196
- $diff_in_minutes += $last_update->i;
197
-
198
- // It's been more than 2 minutes, save everything to DB
199
- if ( $diff_in_minutes > 2 ) {
200
-
201
- $query_data = "INSERT INTO {$table}data (`postid`,`day`,`last_viewed`,`pageviews`) VALUES ";
202
- $query_summary = "INSERT INTO {$table}summary (`postid`,`pageviews`,`view_date`,`view_datetime`) VALUES ";
203
-
204
- foreach( $wpp_cache['data'] as $pid => $data ) {
205
- $views_count = 0;
206
-
207
- foreach( $data as $ts => $cached_views ){
208
- $views_count += $cached_views;
209
- $ts = Helper::is_timestamp($ts) ? $ts : strtotime($ts);
210
-
211
- $query_summary .= $wpdb->prepare("(%d,%d,%s,%s),", [
212
- $pid,
213
- $cached_views,
214
- date("Y-m-d", $ts),
215
- date("Y-m-d H:i:s", $ts)
216
- ]);
217
- }
218
-
219
- $query_data .= $wpdb->prepare( "(%d,%s,%s,%s),", [
220
- $pid,
221
- $date_time_with_seconds,
222
- $date_time_with_seconds,
223
- $views_count
224
- ]);
225
- }
226
-
227
- $query_data = rtrim($query_data, ",") . " ON DUPLICATE KEY UPDATE pageviews=pageviews+VALUES(pageviews),last_viewed=VALUES(last_viewed);";
228
- $query_summary = rtrim($query_summary, ",") . ";";
229
-
230
- // Clear cache
231
- $wpp_cache['last_updated'] = $date_time_with_seconds;
232
- $wpp_cache['data'] = [];
233
- wp_cache_set('_wpp_cache', $wpp_cache, 'transient', 0);
234
-
235
- // Save
236
- $result1 = $wpdb->query($query_data);
237
- $result2 = $wpdb->query($query_summary);
238
- }
239
- else {
240
- $result1 = $result2 = true;
241
- }
242
- } // Live update to the DB
243
- else {
244
- // Update all-time table
245
- $result1 = $wpdb->query($wpdb->prepare(
246
- "INSERT INTO {$table}data
247
- (postid, day, last_viewed, pageviews) VALUES (%d, %s, %s, %d)
248
- ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, last_viewed = %s;",
249
- $post_ID,
250
- $now,
251
- $now,
252
- $views,
253
- $views,
254
- $now
255
- ));
256
-
257
- // Update range (summary) table
258
- $result2 = $wpdb->query($wpdb->prepare(
259
- "INSERT INTO {$table}summary
260
- (postid, pageviews, view_date, view_datetime) VALUES (%d, %d, %s, %s)
261
- ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, view_datetime = %s;",
262
- $post_ID,
263
- $views,
264
- $curdate,
265
- $now,
266
- $views,
267
- $now
268
- ));
269
- }
270
-
271
- $end = Helper::microtime_float();
272
- $exec_time += round($end - $start, 6);
273
-
274
- $response = ['results' => ''];
275
-
276
- if ( !$result1 || !$result2 ) {
277
- $response['results'] = 'WPP: failed to update views count!';
278
- return new \WP_REST_Response($response, 500);
279
- }
280
-
281
- // Allow WP themers / coders perform an action
282
- // after updating views count
283
- if ( has_action('wpp_post_update_views') )
284
- do_action('wpp_post_update_views', $post_ID);
285
-
286
- $response['results'] = "WPP: OK. Execution time: " . $exec_time . " seconds";
287
- return new \WP_REST_Response($response, 201);
288
- }
289
-
290
- /**
291
- * Retrieves a popular posts widget for display.
292
- *
293
- * @since 4.1.0
294
- *
295
- * @param \WP_REST_Request $request Full details about the request.
296
- * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
297
- */
298
- public function get_widget($request)
299
- {
300
- $instance_id = $request->get_param('id');
301
- $is_single = $request->get_param('is_single');
302
- $lang = $request->get_param('lang');
303
- $widget = get_option('widget_wpp');
304
-
305
- if ( $data = $this->prepare_widget_item_for_response($instance_id, $is_single, $lang, $widget, $request) )
306
- return new \WP_REST_Response($data, 200);
307
-
308
- return new \WP_Error('invalid_instance', __('Invalid Widget Instance ID', 'wordpress-popular-posts'));
309
- }
310
-
311
- /**
312
- * Prepares widget instance for response.
313
- *
314
- * @since 5.0.0
315
- * @param int
316
- * @param int
317
- * @param string
318
- * @param array
319
- * @param \WP_REST_Request
320
- * @return array|boolean
321
- */
322
- public function prepare_widget_item_for_response($instance_id, $is_single, $lang, $widget, $request)
323
- {
324
- // Valid instance
325
- if ( $widget && isset($widget[$instance_id]) ) {
326
-
327
- $instance = $widget[$instance_id];
328
-
329
- // Expose widget ID for customization
330
- if ( ! isset($instance['widget_id']) )
331
- $instance['widget_id'] = 'wpp-' . $instance_id;
332
-
333
- // Multilang support
334
- if ( $lang ) {
335
- $current_locale = get_locale();
336
- $locale = null;
337
-
338
- // Polylang support
339
- if ( function_exists('PLL') ) {
340
- $lang_object = PLL()->model->get_language($lang);
341
- $locale = ( $lang_object && isset($lang_object->locale) ) ? $lang_object->locale : null;
342
- }
343
-
344
- // Reload locale if needed
345
- if ( $locale && $locale != $current_locale ) {
346
- $this->translate->set_current_language($lang);
347
- unload_textdomain('wordpress-popular-posts');
348
- load_textdomain('wordpress-popular-posts', WP_LANG_DIR . '/plugins/wordpress-popular-posts-' . $locale . '.mo');
349
- }
350
- }
351
-
352
- $popular_posts = $this->maybe_query($instance);
353
-
354
- if ( is_numeric($is_single) && $is_single > 0 ) {
355
- add_filter('wpp_is_single', function($id) use ($is_single) {
356
- return $is_single;
357
- });
358
- }
359
-
360
- $this->output->set_data($popular_posts->get_posts());
361
- $this->output->set_public_options($instance);
362
- $this->output->build_output();
363
-
364
- return [
365
- 'widget' => ( $this->config['tools']['cache']['active'] ? '<!-- cached -->' : '' ) . $this->output->get_output()
366
- ];
367
- }
368
-
369
- return false;
370
- }
371
-
372
- /**
373
- * Retrieves the popular post's WP_Post object and formats it for the REST response.
374
- *
375
- * @since 4.1.0
376
- *
377
- * @param object $popular_post The popular post object.
378
- * @param \WP_REST_Request $request Full details about the request.
379
- * @return array|mixed The formatted WP_Post object.
380
- */
381
- private function prepare_item($popular_post, $request)
382
- {
383
- $wp_post = get_post($popular_post->id);
384
-
385
- // Borrow prepare_item_for_response method from WP_REST_Posts_Controller.
386
- $posts_controller = new \WP_REST_Posts_Controller($wp_post->post_type, $request);
387
- $data = $posts_controller->prepare_item_for_response($wp_post, $request);
388
-
389
- // Add pageviews from popular_post object to response.
390
- $data->data['pageviews'] = $popular_post->pageviews;
391
-
392
- return $this->prepare_response_for_collection($data);
393
- }
394
-
395
- /**
396
- * Retrieves the query params for the collections.
397
- *
398
- * @since 4.1.0
399
- *
400
- * @return array Query parameters for the collection.
401
- */
402
- public function get_collection_params()
403
- {
404
- return [
405
- 'post_type' => [
406
- 'description' => __('Return popular posts from specified custom post type(s).'),
407
- 'type' => 'string',
408
- 'default' => 'post',
409
- 'sanitize_callback' => 'sanitize_text_field',
410
- 'validate_callback' => 'rest_validate_request_arg',
411
- ],
412
- 'limit' => [
413
- 'description' => __('The maximum number of popular posts to return.'),
414
- 'type' => 'integer',
415
- 'default' => 10,
416
- 'sanitize_callback' => 'absint',
417
- 'validate_callback' => 'rest_validate_request_arg',
418
- 'minimum' => 1,
419
- ],
420
- 'freshness' => [
421
- 'description' => __('Retrieve the most popular entries published within the specified time range.'),
422
- 'type' => 'string',
423
- 'enum' => ['0', '1'],
424
- 'default' => '0',
425
- 'sanitize_callback' => 'sanitize_text_field',
426
- 'validate_callback' => 'rest_validate_request_arg',
427
- ],
428
- 'offset' => [
429
- 'description' => __('An offset point for the collection.'),
430
- 'type' => 'integer',
431
- 'default' => 0,
432
- 'minimum' => 0,
433
- 'sanitize_callback' => 'absint',
434
- 'validate_callback' => 'rest_validate_request_arg',
435
- ],
436
- 'order_by' => [
437
- 'description' => __('Set the sorting option of the popular posts.'),
438
- 'type' => 'string',
439
- 'enum' => ['views', 'comments'],
440
- 'default' => 'views',
441
- 'sanitize_callback' => 'sanitize_text_field',
442
- 'validate_callback' => 'rest_validate_request_arg',
443
- ],
444
- 'range' => [
445
- 'description' => __('Return popular posts from a specified time range.'),
446
- 'type' => 'string',
447
- 'enum' => ['last24hours', 'last7days', 'last30days', 'all', 'custom'],
448
- 'default' => 'last24hours',
449
- 'sanitize_callback' => 'sanitize_text_field',
450
- 'validate_callback' => 'rest_validate_request_arg',
451
- ],
452
- 'time_unit' => [
453
- 'description' => __('Specifies the time unit of the custom time range.'),
454
- 'type' => 'string',
455
- 'enum' => ['minute', 'hour', 'day', 'week', 'month'],
456
- 'default' => 'hour',
457
- 'sanitize_callback' => 'sanitize_text_field',
458
- 'validate_callback' => 'rest_validate_request_arg',
459
- ],
460
- 'time_quantity' => [
461
- 'description' => __('Specifies the number of time units of the custom time range.'),
462
- 'type' => 'integer',
463
- 'default' => 24,
464
- 'minimum' => 1,
465
- 'sanitize_callback' => 'absint',
466
- 'validate_callback' => 'rest_validate_request_arg',
467
- ],
468
- 'pid' => [
469
- 'description' => __('Post IDs to exclude from the listing.'),
470
- 'type' => 'string',
471
- 'sanitize_callback' => function($pid) {
472
- return rtrim(preg_replace('|[^0-9,]|', '', $pid), ',');
473
- },
474
- 'validate_callback' => 'rest_validate_request_arg',
475
- ],
476
- 'taxonomy' => [
477
- 'description' => __('Include posts in a specified taxonomy.'),
478
- 'type' => 'string',
479
- 'sanitize_callback' => function($taxonomy) {
480
- return empty($taxonomy) ? 'category' : $taxonomy;
481
- },
482
- 'validate_callback' => 'rest_validate_request_arg',
483
- ],
484
- 'term_id' => [
485
- 'description' => __('Taxonomy IDs, separated by comma (prefix a minus sign to exclude).'),
486
- 'type' => 'string',
487
- 'sanitize_callback' => function($term_id) {
488
- return rtrim(preg_replace('|[^0-9,;-]|', '', $term_id), ',');
489
- },
490
- 'validate_callback' => 'rest_validate_request_arg',
491
- ],
492
- 'author' => [
493
- 'description' => __('Include popular posts from author ID(s).'),
494
- 'type' => 'string',
495
- 'sanitize_callback' => function($author) {
496
- return rtrim(preg_replace('|[^0-9,]|', '', $author), ',');
497
- },
498
- 'validate_callback' => 'rest_validate_request_arg',
499
- ],
500
- ];
501
- }
502
-
503
- /**
504
- * Retrieves the query params for tracking views count.
505
- *
506
- * @since 4.1.0
507
- *
508
- * @return array Query parameters for tracking views count.
509
- */
510
- public function get_tracking_params()
511
- {
512
- return [
513
- 'token' => [
514
- 'description' => __('Security nonce.'),
515
- 'type' => 'string',
516
- 'sanitize_callback' => 'sanitize_text_field',
517
- 'validate_callback' => 'rest_validate_request_arg',
518
- ],
519
- 'wpp_id' => [
520
- 'description' => __('The post / page ID.'),
521
- 'type' => 'integer',
522
- 'default' => 0,
523
- 'sanitize_callback' => 'absint',
524
- 'validate_callback' => 'rest_validate_request_arg',
525
- ],
526
- 'sampling' => [
527
- 'description' => __('Enables Data Sampling.'),
528
- 'type' => 'integer',
529
- 'default' => 0,
530
- 'sanitize_callback' => 'absint',
531
- 'validate_callback' => 'rest_validate_request_arg',
532
- ],
533
- 'sampling_rate' => [
534
- 'description' => __('Sets the Sampling Rate.'),
535
- 'type' => 'integer',
536
- 'default' => 100,
537
- 'sanitize_callback' => 'absint',
538
- 'validate_callback' => 'rest_validate_request_arg',
539
- ]
540
- ];
541
- }
542
-
543
- /**
544
- * Retrieves the query params for getting a widget instance.
545
- *
546
- * @since 4.1.0
547
- *
548
- * @return array Query parameters for getting a widget instance.
549
- */
550
- public function get_widget_params()
551
- {
552
- return [
553
- 'i_single' => [
554
- 'type' => 'integer',
555
- 'default' => null,
556
- 'sanitize_callback' => 'absint'
557
- ],
558
- 'lang' => [
559
- 'type' => 'string',
560
- 'default' => null,
561
- 'sanitize_callback' => 'sanitize_text_field'
562
- ],
563
- ];
564
- }
565
-
566
- /**
567
- * Gets Query object from cache if it exists,
568
- * otherwise a new Query object will be
569
- * instantiated and returned.
570
- *
571
- * @since 5.0.3
572
- * @param array
573
- * @return Query
574
- */
575
- private function maybe_query(array $params)
576
- {
577
- // Return cached results
578
- if ( $this->config['tools']['cache']['active'] ) {
579
- $key = 'wpp_' . md5(json_encode($params));
580
- $query = \WordPressPopularPosts\Cache::get($key);
581
-
582
- if ( false === $query ) {
583
- $query = new Query($params);
584
-
585
- $time_value = $this->config['tools']['cache']['interval']['value'];
586
- $time_unit = $this->config['tools']['cache']['interval']['time'];
587
-
588
- // No popular posts found, check again in 1 minute
589
- if ( ! $query->get_posts() ) {
590
- $time_value = 1;
591
- $time_unit = 'minute';
592
- }
593
-
594
- \WordPressPopularPosts\Cache::set(
595
- $key,
596
- $query,
597
- $time_value,
598
- $time_unit
599
- );
600
- }
601
- } // Get real-time popular posts
602
- else {
603
- $query = new Query($params);
604
- }
605
-
606
- return $query;
607
  }
608
  }
1
  <?php
2
  namespace WordPressPopularPosts\Rest;
3
 
4
+ class Controller {
 
 
 
5
 
6
  /**
7
+ * Posts Endpoint.
8
  *
9
+ * @var \WordPressPopularPosts\Rest\PostsEndpoint
10
  * @access private
11
  */
12
+ private $posts_endpoint;
13
 
14
  /**
15
+ * View Logger Endpoint.
16
  *
17
+ * @var \WordPressPopularPosts\Rest\ViewLoggerEndpoint
18
  * @access private
19
  */
20
+ private $view_logger_endpoint;
21
 
22
  /**
23
+ * View Logger Endpoint.
24
  *
25
+ * @var \WordPressPopularPosts\Rest\WidgetEndpoint
26
  * @access private
27
  */
28
+ private $widget_endpoint;
29
 
30
  /**
31
  * Initialize class.
32
  *
33
+ * @param \WordPressPopularPosts\Rest\PostsEndpoint
34
+ * @param \WordPressPopularPosts\Rest\ViewLoggerEndpoint
35
+ * @param \WordPressPopularPosts\Rest\WidgetEndpoint
36
  */
37
+ public function __construct(\WordPressPopularPosts\Rest\PostsEndpoint $posts_endpoint, \WordPressPopularPosts\Rest\ViewLoggerEndpoint $view_logger_endpoint, \WordPressPopularPosts\Rest\WidgetEndpoint $widget_endpoint)
38
  {
39
+ $this->posts_endpoint = $posts_endpoint;
40
+ $this->view_logger_endpoint = $view_logger_endpoint;
41
+ $this->widget_endpoint = $widget_endpoint;
42
  }
43
 
44
  /**
56
  */
57
  public function register_routes()
58
  {
59
+ $this->posts_endpoint->register();
60
+ $this->view_logger_endpoint->register();
61
+ $this->widget_endpoint->register();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  }
63
  }
src/Rest/Endpoint.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WordPressPopularPosts\Rest;
3
+
4
+ use WordPressPopularPosts\Query;
5
+
6
+ abstract class Endpoint extends \WP_REST_Controller {
7
+
8
+ /**
9
+ * Plugin options.
10
+ *
11
+ * @var array $config
12
+ * @access private
13
+ */
14
+ protected $config;
15
+
16
+ /**
17
+ * Translate object.
18
+ *
19
+ * @var \WordPressPopularPosts\Translate $translate
20
+ * @access private
21
+ */
22
+ protected $translate;
23
+
24
+ /**
25
+ * Initializes class.
26
+ *
27
+ * @param array
28
+ * @param \WordPressPopularPosts\Translate
29
+ * @param \WordPressPopularPosts\Output
30
+ */
31
+ public function __construct(array $config, \WordPressPopularPosts\Translate $translate)
32
+ {
33
+ $this->config = $config;
34
+ $this->translate = $translate;
35
+ }
36
+
37
+ /**
38
+ * Registers the endpoint(s).
39
+ *
40
+ * @since 5.3.0
41
+ */
42
+ abstract public function register();
43
+
44
+ /**
45
+ * Gets Query object from cache if it exists,
46
+ * otherwise a new Query object will be
47
+ * instantiated and returned.
48
+ *
49
+ * @since 5.0.3
50
+ * @param array
51
+ * @return Query
52
+ */
53
+ protected function maybe_query(array $params)
54
+ {
55
+ // Return cached results
56
+ if ( $this->config['tools']['cache']['active'] ) {
57
+ $key = 'wpp_' . md5(json_encode($params));
58
+ $query = \WordPressPopularPosts\Cache::get($key);
59
+
60
+ if ( false === $query ) {
61
+ $query = new Query($params);
62
+
63
+ $time_value = $this->config['tools']['cache']['interval']['value'];
64
+ $time_unit = $this->config['tools']['cache']['interval']['time'];
65
+
66
+ // No popular posts found, check again in 1 minute
67
+ if ( ! $query->get_posts() ) {
68
+ $time_value = 1;
69
+ $time_unit = 'minute';
70
+ }
71
+
72
+ \WordPressPopularPosts\Cache::set(
73
+ $key,
74
+ $query,
75
+ $time_value,
76
+ $time_unit
77
+ );
78
+ }
79
+ } // Get real-time popular posts
80
+ else {
81
+ $query = new Query($params);
82
+ }
83
+
84
+ return $query;
85
+ }
86
+
87
+ /**
88
+ * Sets language/locale.
89
+ *
90
+ * @since 5.3.0
91
+ */
92
+ protected function set_lang($lang)
93
+ {
94
+ // Multilang support
95
+ if ( $lang ) {
96
+ $current_locale = get_locale();
97
+ $locale = null;
98
+
99
+ // Polylang support
100
+ if ( function_exists('PLL') ) {
101
+ $lang_object = PLL()->model->get_language($lang);
102
+ $locale = ( $lang_object && isset($lang_object->locale) ) ? $lang_object->locale : null;
103
+ }
104
+
105
+ // Reload locale if needed
106
+ if ( $locale && $locale != $current_locale ) {
107
+ $this->translate->set_current_language($lang);
108
+ unload_textdomain('wordpress-popular-posts');
109
+ load_textdomain('wordpress-popular-posts', WP_LANG_DIR . '/plugins/wordpress-popular-posts-' . $locale . '.mo');
110
+ }
111
+ }
112
+ }
113
+ }
src/Rest/PostsEndpoint.php ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WordPressPopularPosts\Rest;
3
+
4
+ class PostsEndpoint extends Endpoint {
5
+
6
+ /**
7
+ * Registers the endpoint(s).
8
+ *
9
+ * @since 5.3.0
10
+ */
11
+ public function register()
12
+ {
13
+ $version = '1';
14
+ $namespace = 'wordpress-popular-posts/v' . $version;
15
+
16
+ register_rest_route($namespace, '/popular-posts', [
17
+ [
18
+ 'methods' => \WP_REST_Server::READABLE,
19
+ 'callback' => [$this, 'get_items'],
20
+ 'permission_callback' => '__return_true',
21
+ 'args' => $this->get_collection_params()
22
+ ]
23
+ ]);
24
+ }
25
+
26
+ /**
27
+ * Gets popular posts.
28
+ *
29
+ * @since 5.3.0
30
+ * @param \WP_REST_Request $request Full data about the request.
31
+ * @return \WP_REST_Response
32
+ */
33
+ public function get_items($request)
34
+ {
35
+ $params = $request->get_params();
36
+ $lang = isset($params['lang']) ? $params['lang'] : null;
37
+ $popular_posts = [];
38
+
39
+ // Multilang support
40
+ $this->set_lang($lang);
41
+
42
+ $query = $this->maybe_query($params);
43
+ $results = $query->get_posts();
44
+
45
+ if ( is_array($results) && ! empty($results) ) {
46
+ foreach( $results as $popular_post ) {
47
+ $popular_posts[] = $this->prepare_item($popular_post, $request);
48
+ }
49
+ }
50
+
51
+ return new \WP_REST_Response($popular_posts, 200);
52
+ }
53
+
54
+ /**
55
+ * Retrieves the popular post's WP_Post object and formats it for the REST response.
56
+ *
57
+ * @since 4.1.0
58
+ *
59
+ * @param object $popular_post The popular post object.
60
+ * @param \WP_REST_Request $request Full details about the request.
61
+ * @return array|mixed The formatted WP_Post object.
62
+ */
63
+ private function prepare_item($popular_post, $request)
64
+ {
65
+ if ( $request->get_param('lang') ) {
66
+ $post_ID = $this->translate->get_object_id(
67
+ $popular_post->id,
68
+ get_post_type($popular_post->id)
69
+ );
70
+ } else {
71
+ $post_ID = $popular_post->id;
72
+ }
73
+
74
+ $wp_post = get_post($post_ID);
75
+
76
+ // Borrow prepare_item_for_response method from WP_REST_Posts_Controller.
77
+ $posts_controller = new \WP_REST_Posts_Controller($wp_post->post_type, $request);
78
+ $data = $posts_controller->prepare_item_for_response($wp_post, $request);
79
+
80
+ // Add pageviews from popular_post object to response.
81
+ $data->data['pageviews'] = $popular_post->pageviews;
82
+
83
+ return $this->prepare_response_for_collection($data);
84
+ }
85
+
86
+ /**
87
+ * Retrieves the query params for the collections.
88
+ *
89
+ * @since 4.1.0
90
+ *
91
+ * @return array Query parameters for the collection.
92
+ */
93
+ public function get_collection_params()
94
+ {
95
+ return [
96
+ 'post_type' => [
97
+ 'description' => __('Return popular posts from specified custom post type(s).'),
98
+ 'type' => 'string',
99
+ 'default' => 'post',
100
+ 'sanitize_callback' => 'sanitize_text_field',
101
+ 'validate_callback' => 'rest_validate_request_arg',
102
+ ],
103
+ 'limit' => [
104
+ 'description' => __('The maximum number of popular posts to return.'),
105
+ 'type' => 'integer',
106
+ 'default' => 10,
107
+ 'sanitize_callback' => 'absint',
108
+ 'validate_callback' => 'rest_validate_request_arg',
109
+ 'minimum' => 1,
110
+ ],
111
+ 'freshness' => [
112
+ 'description' => __('Retrieve the most popular entries published within the specified time range.'),
113
+ 'type' => 'string',
114
+ 'enum' => ['0', '1'],
115
+ 'default' => '0',
116
+ 'sanitize_callback' => 'sanitize_text_field',
117
+ 'validate_callback' => 'rest_validate_request_arg',
118
+ ],
119
+ 'offset' => [
120
+ 'description' => __('An offset point for the collection.'),
121
+ 'type' => 'integer',
122
+ 'default' => 0,
123
+ 'minimum' => 0,
124
+ 'sanitize_callback' => 'absint',
125
+ 'validate_callback' => 'rest_validate_request_arg',
126
+ ],
127
+ 'order_by' => [
128
+ 'description' => __('Set the sorting option of the popular posts.'),
129
+ 'type' => 'string',
130
+ 'enum' => ['views', 'comments'],
131
+ 'default' => 'views',
132
+ 'sanitize_callback' => 'sanitize_text_field',
133
+ 'validate_callback' => 'rest_validate_request_arg',
134
+ ],
135
+ 'range' => [
136
+ 'description' => __('Return popular posts from a specified time range.'),
137
+ 'type' => 'string',
138
+ 'enum' => ['last24hours', 'last7days', 'last30days', 'all', 'custom'],
139
+ 'default' => 'last24hours',
140
+ 'sanitize_callback' => 'sanitize_text_field',
141
+ 'validate_callback' => 'rest_validate_request_arg',
142
+ ],
143
+ 'time_unit' => [
144
+ 'description' => __('Specifies the time unit of the custom time range.'),
145
+ 'type' => 'string',
146
+ 'enum' => ['minute', 'hour', 'day', 'week', 'month'],
147
+ 'default' => 'hour',
148
+ 'sanitize_callback' => 'sanitize_text_field',
149
+ 'validate_callback' => 'rest_validate_request_arg',
150
+ ],
151
+ 'time_quantity' => [
152
+ 'description' => __('Specifies the number of time units of the custom time range.'),
153
+ 'type' => 'integer',
154
+ 'default' => 24,
155
+ 'minimum' => 1,
156
+ 'sanitize_callback' => 'absint',
157
+ 'validate_callback' => 'rest_validate_request_arg',
158
+ ],
159
+ 'pid' => [
160
+ 'description' => __('Post IDs to exclude from the listing.'),
161
+ 'type' => 'string',
162
+ 'sanitize_callback' => function($pid) {
163
+ return rtrim(preg_replace('|[^0-9,]|', '', $pid), ',');
164
+ },
165
+ 'validate_callback' => 'rest_validate_request_arg',
166
+ ],
167
+ 'taxonomy' => [
168
+ 'description' => __('Include posts in a specified taxonomy.'),
169
+ 'type' => 'string',
170
+ 'sanitize_callback' => function($taxonomy) {
171
+ return empty($taxonomy) ? 'category' : $taxonomy;
172
+ },
173
+ 'validate_callback' => 'rest_validate_request_arg',
174
+ ],
175
+ 'term_id' => [
176
+ 'description' => __('Taxonomy IDs, separated by comma (prefix a minus sign to exclude).'),
177
+ 'type' => 'string',
178
+ 'sanitize_callback' => function($term_id) {
179
+ return rtrim(preg_replace('|[^0-9,;-]|', '', $term_id), ',');
180
+ },
181
+ 'validate_callback' => 'rest_validate_request_arg',
182
+ ],
183
+ 'author' => [
184
+ 'description' => __('Include popular posts from author ID(s).'),
185
+ 'type' => 'string',
186
+ 'sanitize_callback' => function($author) {
187
+ return rtrim(preg_replace('|[^0-9,]|', '', $author), ',');
188
+ },
189
+ 'validate_callback' => 'rest_validate_request_arg',
190
+ ],
191
+ ];
192
+ }
193
+ }
src/Rest/ViewLoggerEndpoint.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WordPressPopularPosts\Rest;
3
+
4
+ use WordPressPopularPosts\Helper;
5
+
6
+ class ViewLoggerEndpoint extends Endpoint {
7
+
8
+ /**
9
+ * Registers the endpoint(s).
10
+ *
11
+ * @since 5.3.0
12
+ */
13
+ public function register()
14
+ {
15
+ $version = '1';
16
+ $namespace = 'wordpress-popular-posts/v' . $version;
17
+
18
+ register_rest_route($namespace, '/popular-posts', [
19
+ [
20
+ 'methods' => \WP_REST_Server::CREATABLE,
21
+ 'callback' => [$this, 'update_views_count'],
22
+ 'permission_callback' => '__return_true',
23
+ 'args' => $this->get_tracking_params(),
24
+ ]
25
+ ]);
26
+ }
27
+
28
+ /**
29
+ * Updates the views count of a post / page.
30
+ *
31
+ * @since 4.1.0
32
+ *
33
+ * @param \WP_REST_Request $request Full details about the request.
34
+ * @return string
35
+ */
36
+ public function update_views_count($request){
37
+ global $wpdb;
38
+
39
+ $post_ID = $request->get_param('wpp_id');
40
+ $sampling = $request->get_param('sampling');
41
+ $sampling_rate = $request->get_param('sampling_rate');
42
+
43
+ $table = $wpdb->prefix . "popularposts";
44
+ $wpdb->show_errors();
45
+
46
+ // Get translated object ID
47
+ $post_ID = $this->translate->get_object_id(
48
+ $post_ID,
49
+ get_post_type($post_ID),
50
+ true,
51
+ $this->translate->get_default_language()
52
+ );
53
+
54
+ $now = Helper::now();
55
+ $curdate = Helper::curdate();
56
+ $views = ($sampling)
57
+ ? $sampling_rate
58
+ : 1;
59
+
60
+ // Allow WP themers / coders perform an action
61
+ // before updating views count
62
+ if ( has_action('wpp_pre_update_views') )
63
+ do_action('wpp_pre_update_views', $post_ID, $views);
64
+
65
+ $result1 = $result2 = false;
66
+
67
+ $exec_time = 0;
68
+ $start = Helper::microtime_float();
69
+
70
+ // Store views data in persistent object cache
71
+ if (
72
+ wp_using_ext_object_cache()
73
+ && defined('WPP_CACHE_VIEWS')
74
+ && WPP_CACHE_VIEWS
75
+ ) {
76
+
77
+ $now_datetime = new \DateTime($now, new \DateTimeZone(Helper::get_timezone()));
78
+ $timestamp = $now_datetime->getTimestamp();
79
+ $date_time = $now_datetime->format('Y-m-d H:i');
80
+ $date_time_with_seconds = $now_datetime->format('Y-m-d H:i:s');
81
+ $high_accuracy = false;
82
+
83
+ $key = $high_accuracy ? $timestamp : $date_time;
84
+
85
+ if ( ! $wpp_cache = wp_cache_get('_wpp_cache', 'transient') ) {
86
+ $wpp_cache = [
87
+ 'last_updated' => $date_time_with_seconds,
88
+ 'data' => [
89
+ $post_ID => [
90
+ $key => 1
91
+ ]
92
+ ]
93
+ ];
94
+ } else {
95
+ if ( ! isset($wpp_cache['data'][$post_ID][$key]) ) {
96
+ $wpp_cache['data'][$post_ID][$key] = 1;
97
+ } else {
98
+ $wpp_cache['data'][$post_ID][$key] += 1;
99
+ }
100
+ }
101
+
102
+ // Update cache
103
+ wp_cache_set('_wpp_cache', $wpp_cache, 'transient', 0);
104
+
105
+ // How long has it been since the last time we saved to the database?
106
+ $last_update = $now_datetime->diff(new \DateTime($wpp_cache['last_updated'], new \DateTimeZone(Helper::get_timezone())));
107
+ $diff_in_minutes = $last_update->days * 24 * 60;
108
+ $diff_in_minutes += $last_update->h * 60;
109
+ $diff_in_minutes += $last_update->i;
110
+
111
+ // It's been more than 2 minutes, save everything to DB
112
+ if ( $diff_in_minutes > 2 ) {
113
+
114
+ $query_data = "INSERT INTO {$table}data (`postid`,`day`,`last_viewed`,`pageviews`) VALUES ";
115
+ $query_summary = "INSERT INTO {$table}summary (`postid`,`pageviews`,`view_date`,`view_datetime`) VALUES ";
116
+
117
+ foreach( $wpp_cache['data'] as $pid => $data ) {
118
+ $views_count = 0;
119
+
120
+ foreach( $data as $ts => $cached_views ){
121
+ $views_count += $cached_views;
122
+ $ts = Helper::is_timestamp($ts) ? $ts : strtotime($ts);
123
+
124
+ $query_summary .= $wpdb->prepare("(%d,%d,%s,%s),", [
125
+ $pid,
126
+ $cached_views,
127
+ date("Y-m-d", $ts),
128
+ date("Y-m-d H:i:s", $ts)
129
+ ]);
130
+ }
131
+
132
+ $query_data .= $wpdb->prepare( "(%d,%s,%s,%s),", [
133
+ $pid,
134
+ $date_time_with_seconds,
135
+ $date_time_with_seconds,
136
+ $views_count
137
+ ]);
138
+ }
139
+
140
+ $query_data = rtrim($query_data, ",") . " ON DUPLICATE KEY UPDATE pageviews=pageviews+VALUES(pageviews),last_viewed=VALUES(last_viewed);";
141
+ $query_summary = rtrim($query_summary, ",") . ";";
142
+
143
+ // Clear cache
144
+ $wpp_cache['last_updated'] = $date_time_with_seconds;
145
+ $wpp_cache['data'] = [];
146
+ wp_cache_set('_wpp_cache', $wpp_cache, 'transient', 0);
147
+
148
+ // Save
149
+ $result1 = $wpdb->query($query_data);
150
+ $result2 = $wpdb->query($query_summary);
151
+ }
152
+ else {
153
+ $result1 = $result2 = true;
154
+ }
155
+ } // Live update to the DB
156
+ else {
157
+ // Update all-time table
158
+ $result1 = $wpdb->query($wpdb->prepare(
159
+ "INSERT INTO {$table}data
160
+ (postid, day, last_viewed, pageviews) VALUES (%d, %s, %s, %d)
161
+ ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, last_viewed = %s;",
162
+ $post_ID,
163
+ $now,
164
+ $now,
165
+ $views,
166
+ $views,
167
+ $now
168
+ ));
169
+
170
+ // Update range (summary) table
171
+ $result2 = $wpdb->query($wpdb->prepare(
172
+ "INSERT INTO {$table}summary
173
+ (postid, pageviews, view_date, view_datetime) VALUES (%d, %d, %s, %s)
174
+ ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, view_datetime = %s;",
175
+ $post_ID,
176
+ $views,
177
+ $curdate,
178
+ $now,
179
+ $views,
180
+ $now
181
+ ));
182
+ }
183
+
184
+ $end = Helper::microtime_float();
185
+ $exec_time += round($end - $start, 6);
186
+
187
+ $response = ['results' => ''];
188
+
189
+ if ( ! $result1 || ! $result2 ) {
190
+ $response['results'] = 'WPP: failed to update views count!';
191
+ return new \WP_REST_Response($response, 500);
192
+ }
193
+
194
+ // Allow WP themers / coders perform an action
195
+ // after updating views count
196
+ if ( has_action('wpp_post_update_views') )
197
+ do_action('wpp_post_update_views', $post_ID);
198
+
199
+ $response['results'] = "WPP: OK. Execution time: " . $exec_time . " seconds";
200
+ return new \WP_REST_Response($response, 201);
201
+ }
202
+
203
+ /**
204
+ * Retrieves the query params for tracking views count.
205
+ *
206
+ * @since 4.1.0
207
+ *
208
+ * @return array Query parameters for tracking views count.
209
+ */
210
+ public function get_tracking_params()
211
+ {
212
+ return [
213
+ 'token' => [
214
+ 'description' => __('Security nonce.'),
215
+ 'type' => 'string',
216
+ 'sanitize_callback' => 'sanitize_text_field',
217
+ 'validate_callback' => 'rest_validate_request_arg',
218
+ ],
219
+ 'wpp_id' => [
220
+ 'description' => __('The post / page ID.'),
221
+ 'type' => 'integer',
222
+ 'default' => 0,
223
+ 'sanitize_callback' => 'absint',
224
+ 'validate_callback' => 'rest_validate_request_arg',
225
+ ],
226
+ 'sampling' => [
227
+ 'description' => __('Enables Data Sampling.'),
228
+ 'type' => 'integer',
229
+ 'default' => 0,
230
+ 'sanitize_callback' => 'absint',
231
+ 'validate_callback' => 'rest_validate_request_arg',
232
+ ],
233
+ 'sampling_rate' => [
234
+ 'description' => __('Sets the Sampling Rate.'),
235
+ 'type' => 'integer',
236
+ 'default' => 100,
237
+ 'sanitize_callback' => 'absint',
238
+ 'validate_callback' => 'rest_validate_request_arg',
239
+ ]
240
+ ];
241
+ }
242
+ }
src/Rest/WidgetEndpoint.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WordPressPopularPosts\Rest;
3
+
4
+ class WidgetEndpoint extends Endpoint {
5
+
6
+ /**
7
+ * Output object.
8
+ *
9
+ * @var \WordPressPopularPosts\Output $output
10
+ * @access private
11
+ */
12
+ protected $output;
13
+
14
+ /**
15
+ * Initializes class.
16
+ *
17
+ * @param array
18
+ * @param \WordPressPopularPosts\Translate
19
+ * @param \WordPressPopularPosts\Output
20
+ */
21
+ public function __construct(array $config, \WordPressPopularPosts\Translate $translate, \WordPressPopularPosts\Output $output)
22
+ {
23
+ $this->config = $config;
24
+ $this->translate = $translate;
25
+ $this->output = $output;
26
+ }
27
+
28
+ /**
29
+ * Registers the endpoint(s).
30
+ *
31
+ * @since 5.3.0
32
+ */
33
+ public function register()
34
+ {
35
+ $version = '1';
36
+ $namespace = 'wordpress-popular-posts/v' . $version;
37
+
38
+ register_rest_route($namespace, '/popular-posts/widget/(?P<id>[\d]+)', [
39
+ [
40
+ 'methods' => \WP_REST_Server::READABLE,
41
+ 'callback' => [$this, 'get_widget'],
42
+ 'permission_callback' => '__return_true',
43
+ 'args' => $this->get_widget_params(),
44
+ ]
45
+ ]);
46
+ }
47
+
48
+ /**
49
+ * Retrieves a popular posts widget for display.
50
+ *
51
+ * @since 4.1.0
52
+ *
53
+ * @param \WP_REST_Request $request Full details about the request.
54
+ * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
55
+ */
56
+ public function get_widget($request)
57
+ {
58
+ $instance_id = $request->get_param('id');
59
+ $is_single = $request->get_param('is_single');
60
+ $lang = $request->get_param('lang');
61
+ $widget = get_option('widget_wpp');
62
+
63
+ if ( $data = $this->prepare_widget_item_for_response($instance_id, $is_single, $lang, $widget, $request) )
64
+ return new \WP_REST_Response($data, 200);
65
+
66
+ return new \WP_Error('invalid_instance', __('Invalid Widget Instance ID', 'wordpress-popular-posts'));
67
+ }
68
+
69
+ /**
70
+ * Prepares widget instance for response.
71
+ *
72
+ * @since 5.0.0
73
+ * @param int
74
+ * @param int
75
+ * @param string
76
+ * @param array
77
+ * @param \WP_REST_Request
78
+ * @return array|boolean
79
+ */
80
+ public function prepare_widget_item_for_response($instance_id, $is_single, $lang, $widget, $request)
81
+ {
82
+ // Valid instance
83
+ if ( $widget && isset($widget[$instance_id]) ) {
84
+
85
+ $instance = $widget[$instance_id];
86
+
87
+ // Expose widget ID for customization
88
+ if ( ! isset($instance['widget_id']) )
89
+ $instance['widget_id'] = 'wpp-' . $instance_id;
90
+
91
+ // Multilang support
92
+ $this->set_lang($lang);
93
+
94
+ $popular_posts = $this->maybe_query($instance);
95
+
96
+ if ( is_numeric($is_single) && $is_single > 0 ) {
97
+ add_filter('wpp_is_single', function($id) use ($is_single) {
98
+ return $is_single;
99
+ });
100
+ }
101
+
102
+ $this->output->set_data($popular_posts->get_posts());
103
+ $this->output->set_public_options($instance);
104
+ $this->output->build_output();
105
+
106
+ return [
107
+ 'widget' => ( $this->config['tools']['cache']['active'] ? '<!-- cached -->' : '' ) . $this->output->get_output()
108
+ ];
109
+ }
110
+
111
+ return false;
112
+ }
113
+
114
+ /**
115
+ * Retrieves the query params for getting a widget instance.
116
+ *
117
+ * @since 4.1.0
118
+ *
119
+ * @return array Query parameters for getting a widget instance.
120
+ */
121
+ public function get_widget_params()
122
+ {
123
+ return [
124
+ 'is_single' => [
125
+ 'type' => 'integer',
126
+ 'default' => null,
127
+ 'sanitize_callback' => 'absint'
128
+ ],
129
+ 'lang' => [
130
+ 'type' => 'string',
131
+ 'default' => null,
132
+ 'sanitize_callback' => 'sanitize_text_field'
133
+ ],
134
+ ];
135
+ }
136
+ }
src/Widget/Widget.php CHANGED
@@ -424,8 +424,6 @@ class Widget extends \WP_Widget {
424
  $this->output->set_data($popular_posts->get_posts());
425
  $this->output->set_public_options($instance);
426
  $this->output->build_output();
427
-
428
- echo ( $this->admin_options['tools']['cache']['active'] ? '<!-- cached -->' : '' );
429
  $this->output->output();
430
  }
431
  }
424
  $this->output->set_data($popular_posts->get_posts());
425
  $this->output->set_public_options($instance);
426
  $this->output->build_output();
 
 
427
  $this->output->output();
428
  }
429
  }
src/WordPressPopularPosts.php CHANGED
@@ -74,7 +74,7 @@ class WordPressPopularPosts {
74
  */
75
  public function init()
76
  {
77
- $this->i18n->hooks();
78
  $this->rest->hooks();
79
  $this->admin->hooks();
80
  $this->front->hooks();
74
  */
75
  public function init()
76
  {
77
+ $this->i18n->load_plugin_textdomain();
78
  $this->rest->hooks();
79
  $this->admin->hooks();
80
  $this->front->hooks();
src/template-tags.php CHANGED
@@ -8,61 +8,80 @@
8
  *
9
  * @link https://github.com/cabrerahector/wordpress-popular-posts/wiki/2.-Template-tags#wpp_get_views
10
  * @since 2.0.3
11
- * @global object $wpdb
12
- * @param int $id
13
- * @param string $range
14
- * @param bool $number_format
15
  * @return string
16
  */
17
  function wpp_get_views($id = NULL, $range = NULL, $number_format = true)
18
  {
19
  // have we got an id?
20
- if ( empty($id) || is_null($id) || ! is_numeric($id) ) {
21
  return "-1";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  } else {
23
- global $wpdb;
 
 
24
 
25
- $table_name = $wpdb->prefix . "popularposts";
 
 
 
 
 
 
 
 
 
 
26
 
27
- if ( ! $range || 'all' == $range ) {
28
- $query = "SELECT pageviews FROM {$table_name}data WHERE postid = '{$id}'";
29
- } else {
30
- $interval = "";
31
-
32
- switch( $range ){
33
- case "last24hours":
34
- case "daily":
35
- $interval = "24 HOUR";
36
- break;
37
-
38
- case "last7days":
39
- case "weekly":
40
- $interval = "6 DAY";
41
- break;
42
-
43
- case "last30days":
44
- case "monthly":
45
- $interval = "29 DAY";
46
- break;
47
-
48
- default:
49
- $interval = "24 HOUR";
50
- break;
51
- }
52
 
53
- $now = current_time('mysql');
 
54
 
55
- $query = "SELECT SUM(pageviews) FROM {$table_name}summary WHERE postid = '{$id}' AND view_datetime > DATE_SUB('{$now}', INTERVAL {$interval}) LIMIT 1;";
56
- }
57
 
58
- $result = $wpdb->get_var($query);
 
 
 
59
 
60
- if ( ! $result ) {
61
- return "0";
62
- }
 
 
63
 
64
- return ($number_format) ? number_format_i18n(intval($result)) : $result;
65
- }
 
 
 
 
 
 
 
 
 
 
 
66
  }
67
 
68
  /**
8
  *
9
  * @link https://github.com/cabrerahector/wordpress-popular-posts/wiki/2.-Template-tags#wpp_get_views
10
  * @since 2.0.3
11
+ * @param int $id The Post ID.
12
+ * @param string|array $range Either an string (eg. 'last7days') or -since 5.3- an array (eg. ['range' => 'custom', 'time_unit' => 'day', 'time_quantity' => 7])
13
+ * @param bool $number_format Whether to format the number (eg. 9,999) or not (eg. 9999)
 
14
  * @return string
15
  */
16
  function wpp_get_views($id = NULL, $range = NULL, $number_format = true)
17
  {
18
  // have we got an id?
19
+ if ( empty($id) || is_null($id) || ! is_numeric($id) )
20
  return "-1";
21
+
22
+ $args = [
23
+ 'range' => 'last24hours',
24
+ '_postID' => $id
25
+ ];
26
+
27
+ if (
28
+ is_array($range)
29
+ && isset($range['range'])
30
+ && isset($range['time_unit'])
31
+ && isset($range['time_quantity'])
32
+ ) {
33
+ $args['range'] = $range['range'];
34
+ $args['time_unit'] = $range['time_unit'];
35
+ $args['time_quantity'] = $range['time_quantity'];
36
  } else {
37
+ $range = is_string($range) ? trim($range) : null;
38
+ $args['range'] = ! $range ? 'last24hours' : $range;
39
+ }
40
 
41
+ add_filter('wpp_query_fields', 'wpp_get_views_fields', 10, 2);
42
+ add_filter('wpp_query_where', 'wpp_get_views_where', 10, 2);
43
+ add_filter('wpp_query_group_by', 'wpp_get_views_group_by', 10, 2);
44
+ add_filter('wpp_query_order_by', 'wpp_get_views_order_by', 10, 2);
45
+ add_filter('wpp_query_limit', 'wpp_get_views_limit', 10, 2);
46
+ $query = new \WordPressPopularPosts\Query($args);
47
+ remove_filter('wpp_query_fields', 'wpp_get_views_fields', 10);
48
+ remove_filter('wpp_query_where', 'wpp_get_views_where', 10);
49
+ remove_filter('wpp_query_group_by', 'wpp_get_views_group_by', 10);
50
+ remove_filter('wpp_query_order_by', 'wpp_get_views_order_by', 10);
51
+ remove_filter('wpp_query_limit', 'wpp_get_views_limit', 10);
52
 
53
+ $results = $query->get_posts();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ if ( empty($results) )
56
+ return 0;
57
 
58
+ return $number_format ? number_format_i18n(intval($results[0]->pageviews)) : $results[0]->pageviews;
59
+ }
60
 
61
+ function wpp_get_views_fields($fields, $options)
62
+ {
63
+ return 'IFNULL(v.pageviews, 0) AS pageviews';
64
+ }
65
 
66
+ function wpp_get_views_where($where, $options)
67
+ {
68
+ global $wpdb;
69
+ return $wpdb->prepare($where . ' AND p.ID = %d ', $options['_postID']);
70
+ }
71
 
72
+ function wpp_get_views_group_by($groupby, $options)
73
+ {
74
+ return '';
75
+ }
76
+
77
+ function wpp_get_views_order_by($orderby, $options)
78
+ {
79
+ return '';
80
+ }
81
+
82
+ function wpp_get_views_limit($limit, $options)
83
+ {
84
+ return '';
85
  }
86
 
87
  /**
wordpress-popular-posts.php CHANGED
@@ -16,7 +16,7 @@
16
  * Plugin Name: WordPress Popular Posts
17
  * Plugin URI: https://wordpress.org/plugins/wordpress-popular-posts/
18
  * Description: A highly customizable widget that displays the most popular posts on your blog.
19
- * Version: 5.2.4
20
  * Author: Hector Cabrera
21
  * Author URI: https://cabrerahector.com/
22
  * License: GPL-2.0+
@@ -29,7 +29,7 @@ if ( ! defined( 'WPINC' ) ) {
29
  die();
30
  }
31
 
32
- define('WPP_VERSION', '5.2.4');
33
  define('WPP_MIN_PHP_VERSION', '5.4');
34
  define('WPP_MIN_WP_VERSION', '4.9');
35
 
16
  * Plugin Name: WordPress Popular Posts
17
  * Plugin URI: https://wordpress.org/plugins/wordpress-popular-posts/
18
  * Description: A highly customizable widget that displays the most popular posts on your blog.
19
+ * Version: 5.3.0
20
  * Author: Hector Cabrera
21
  * Author URI: https://cabrerahector.com/
22
  * License: GPL-2.0+
29
  die();
30
  }
31
 
32
+ define('WPP_VERSION', '5.3.0');
33
  define('WPP_MIN_PHP_VERSION', '5.4');
34
  define('WPP_MIN_WP_VERSION', '4.9');
35