Modern Events Calendar Lite - Version 6.2.7

Version Description

12 January 2022 = - Fixed: "Add new plugin" page error

Download this release

Release Info

Developer webnus
Plugin Icon 128x128 Modern Events Calendar Lite
Version 6.2.7
Comparing to
See all releases

Code changes from version 6.2.5 to 6.2.7

Files changed (138) hide show
  1. app/api/Stripe/Discount.php +0 -1
  2. app/core/puc/.editorconfig +15 -0
  3. app/core/puc/.gitignore +40 -0
  4. app/core/puc/Puc/v4/Factory.php +6 -0
  5. app/core/puc/Puc/v4p11/Autoloader.php +63 -0
  6. app/core/puc/Puc/v4p11/DebugBar/Extension.php +190 -0
  7. app/core/puc/Puc/v4p11/DebugBar/Panel.php +165 -0
  8. app/core/puc/Puc/v4p11/DebugBar/PluginExtension.php +33 -0
  9. app/core/puc/Puc/v4p11/DebugBar/PluginPanel.php +38 -0
  10. app/core/puc/Puc/v4p11/DebugBar/ThemePanel.php +21 -0
  11. app/core/puc/Puc/v4p11/Factory.php +365 -0
  12. app/core/puc/Puc/v4p11/InstalledPackage.php +103 -0
  13. app/core/puc/Puc/v4p11/Metadata.php +132 -0
  14. app/core/puc/Puc/v4p11/OAuthSignature.php +100 -0
  15. app/core/puc/Puc/v4p11/Plugin/Info.php +132 -0
  16. app/core/puc/Puc/v4p11/Plugin/Package.php +184 -0
  17. app/core/puc/Puc/v4p11/Plugin/Ui.php +278 -0
  18. app/core/puc/Puc/v4p11/Plugin/Update.php +112 -0
  19. app/core/puc/Puc/v4p11/Plugin/UpdateChecker.php +414 -0
  20. app/core/puc/Puc/v4p11/Scheduler.php +266 -0
  21. app/core/puc/Puc/v4p11/StateStore.php +207 -0
  22. app/core/puc/Puc/v4p11/Theme/Package.php +65 -0
  23. app/core/puc/Puc/v4p11/Theme/Update.php +84 -0
  24. app/core/puc/Puc/v4p11/Theme/UpdateChecker.php +152 -0
  25. app/core/puc/Puc/v4p11/Update.php +34 -0
  26. app/core/puc/Puc/v4p11/UpdateChecker.php +999 -0
  27. app/core/puc/Puc/v4p11/UpgraderStatus.php +199 -0
  28. app/core/puc/Puc/v4p11/Utils.php +69 -0
  29. app/core/puc/Puc/v4p11/Vcs/Api.php +302 -0
  30. app/core/puc/Puc/v4p11/Vcs/BaseChecker.php +27 -0
  31. app/core/puc/Puc/v4p11/Vcs/BitBucketApi.php +273 -0
  32. app/core/puc/Puc/v4p11/Vcs/GitHubApi.php +441 -0
  33. app/core/puc/Puc/v4p11/Vcs/GitLabApi.php +399 -0
  34. app/core/puc/Puc/v4p11/Vcs/PluginUpdateChecker.php +293 -0
  35. app/core/puc/Puc/v4p11/Vcs/Reference.php +49 -0
  36. app/core/puc/Puc/v4p11/Vcs/ThemeUpdateChecker.php +118 -0
  37. app/core/puc/README.md +326 -0
  38. app/core/puc/composer.json +23 -0
  39. app/core/puc/css/puc-debug-bar.css +70 -0
  40. app/core/puc/examples/plugin.json +52 -0
  41. app/core/puc/examples/theme.json +5 -0
  42. app/core/puc/js/debug-bar.js +52 -0
  43. app/core/puc/languages/plugin-update-checker-ca.mo +0 -0
  44. app/core/puc/languages/plugin-update-checker-ca.po +48 -0
  45. app/core/puc/languages/plugin-update-checker-cs_CZ.mo +0 -0
  46. app/core/puc/languages/plugin-update-checker-cs_CZ.po +45 -0
  47. app/core/puc/languages/plugin-update-checker-da_DK.mo +0 -0
  48. app/core/puc/languages/plugin-update-checker-da_DK.po +42 -0
  49. app/core/puc/languages/plugin-update-checker-de_DE.mo +0 -0
  50. app/core/puc/languages/plugin-update-checker-de_DE.po +38 -0
  51. app/core/puc/languages/plugin-update-checker-es_AR.mo +0 -0
  52. app/core/puc/languages/plugin-update-checker-es_AR.po +48 -0
  53. app/core/puc/languages/plugin-update-checker-es_CL.mo +0 -0
  54. app/core/puc/languages/plugin-update-checker-es_CL.po +48 -0
  55. app/core/puc/languages/plugin-update-checker-es_CO.mo +0 -0
  56. app/core/puc/languages/plugin-update-checker-es_CO.po +48 -0
  57. app/core/puc/languages/plugin-update-checker-es_CR.mo +0 -0
  58. app/core/puc/languages/plugin-update-checker-es_CR.po +48 -0
  59. app/core/puc/languages/plugin-update-checker-es_DO.mo +0 -0
  60. app/core/puc/languages/plugin-update-checker-es_DO.po +48 -0
  61. app/core/puc/languages/plugin-update-checker-es_ES.mo +0 -0
  62. app/core/puc/languages/plugin-update-checker-es_ES.po +48 -0
  63. app/core/puc/languages/plugin-update-checker-es_GT.mo +0 -0
  64. app/core/puc/languages/plugin-update-checker-es_GT.po +48 -0
  65. app/core/puc/languages/plugin-update-checker-es_HN.mo +0 -0
  66. app/core/puc/languages/plugin-update-checker-es_HN.po +48 -0
  67. app/core/puc/languages/plugin-update-checker-es_MX.mo +0 -0
  68. app/core/puc/languages/plugin-update-checker-es_MX.po +48 -0
  69. app/core/puc/languages/plugin-update-checker-es_PE.mo +0 -0
  70. app/core/puc/languages/plugin-update-checker-es_PE.po +48 -0
  71. app/core/puc/languages/plugin-update-checker-es_PR.mo +0 -0
  72. app/core/puc/languages/plugin-update-checker-es_PR.po +48 -0
  73. app/core/puc/languages/plugin-update-checker-es_UY.mo +0 -0
  74. app/core/puc/languages/plugin-update-checker-es_UY.po +48 -0
  75. app/core/puc/languages/plugin-update-checker-es_VE.mo +0 -0
  76. app/core/puc/languages/plugin-update-checker-es_VE.po +48 -0
  77. app/core/puc/languages/plugin-update-checker-fa_IR.mo +0 -0
  78. app/core/puc/languages/plugin-update-checker-fa_IR.po +38 -0
  79. app/core/puc/languages/plugin-update-checker-fr_CA.mo +0 -0
  80. app/core/puc/languages/plugin-update-checker-fr_CA.po +48 -0
  81. app/core/puc/languages/plugin-update-checker-fr_FR.mo +0 -0
  82. app/core/puc/languages/plugin-update-checker-fr_FR.po +42 -0
  83. app/core/puc/languages/plugin-update-checker-hu_HU.mo +0 -0
  84. app/core/puc/languages/plugin-update-checker-hu_HU.po +41 -0
  85. app/core/puc/languages/plugin-update-checker-it_IT.mo +0 -0
  86. app/core/puc/languages/plugin-update-checker-it_IT.po +38 -0
  87. app/core/puc/languages/plugin-update-checker-ja.mo +0 -0
  88. app/core/puc/languages/plugin-update-checker-ja.po +57 -0
  89. app/core/puc/languages/plugin-update-checker-nl_BE.mo +0 -0
  90. app/core/puc/languages/plugin-update-checker-nl_BE.po +48 -0
  91. app/core/puc/languages/plugin-update-checker-nl_NL.mo +0 -0
  92. app/core/puc/languages/plugin-update-checker-nl_NL.po +48 -0
  93. app/core/puc/languages/plugin-update-checker-pt_BR.mo +0 -0
  94. app/core/puc/languages/plugin-update-checker-pt_BR.po +48 -0
  95. app/core/puc/languages/plugin-update-checker-ru_RU.mo +0 -0
  96. app/core/puc/languages/plugin-update-checker-ru_RU.po +48 -0
  97. app/core/puc/languages/plugin-update-checker-sl_SI.mo +0 -0
  98. app/core/puc/languages/plugin-update-checker-sl_SI.po +48 -0
  99. app/core/puc/languages/plugin-update-checker-sv_SE.mo +0 -0
  100. app/core/puc/languages/plugin-update-checker-sv_SE.po +42 -0
  101. app/core/puc/languages/plugin-update-checker-tr_TR.mo +0 -0
  102. app/core/puc/languages/plugin-update-checker-tr_TR.po +48 -0
  103. app/core/puc/languages/plugin-update-checker-uk_UA.mo +0 -0
  104. app/core/puc/languages/plugin-update-checker-uk_UA.po +48 -0
  105. app/core/puc/languages/plugin-update-checker-zh_CN.mo +0 -0
  106. app/core/puc/languages/plugin-update-checker-zh_CN.po +48 -0
  107. app/core/puc/languages/plugin-update-checker.pot +49 -0
  108. app/core/puc/license.txt +7 -0
  109. app/core/puc/load-v4p11.php +28 -0
  110. app/core/puc/plugin-update-checker.php +10 -0
  111. app/core/puc/vendor/Parsedown.php +9 -0
  112. app/core/puc/vendor/ParsedownLegacy.php +1535 -0
  113. app/core/puc/vendor/ParsedownModern.php +1538 -0
  114. app/core/puc/vendor/PucReadmeParser.php +348 -0
  115. app/features/dlfile.php +11 -0
  116. app/features/events.php +19 -15
  117. app/features/fes.php +6 -0
  118. app/features/gateways.php +6631 -0
  119. app/features/gateways/paypal_ipn_cart.php +0 -30
  120. app/features/mec.php +67 -34
  121. app/features/mec/booking.php +6 -1
  122. app/features/mec/dashboard.php +1 -18
  123. app/features/profile/profile.php +11 -0
  124. app/features/schema.php +2 -3
  125. app/features/update.php +43 -3
  126. app/libraries/book.php +2 -1
  127. app/libraries/envato.php +0 -384
  128. app/libraries/eventFields.php +15 -1
  129. app/libraries/factory.php +37 -4
  130. app/libraries/main.php +22 -64
  131. app/modules/next-event/multiple.php +7 -0
  132. app/skins/single.php +9 -10
  133. assets/js/frontend.js +2 -0
  134. changelog.txt +21 -1
  135. languages/modern-events-calendar-lite-cs_CZ.mo +0 -0
  136. languages/modern-events-calendar-lite-cs_CZ.po +1190 -700
  137. languages/modern-events-calendar-lite-de_DE.mo +0 -0
  138. languages/modern-events-calendar-lite-de_DE.po +1077 -469
app/api/Stripe/Discount.php CHANGED
@@ -5,7 +5,6 @@ namespace Stripe;
5
  /**
6
  * Class Discount.
7
  *
8
- * @property string $object
9
  * @property string $checkout_session The Checkout session that this coupon is applied to, if it is applied to a particular session in payment mode. Will not be present for subscription mode.
10
  * @property \Stripe\Coupon $coupon Hash describing the coupon applied to create this discount.
11
  * @property string|\Stripe\Customer $customer The ID of the customer associated with this discount.
5
  /**
6
  * Class Discount.
7
  *
 
8
  * @property string $checkout_session The Checkout session that this coupon is applied to, if it is applied to a particular session in payment mode. Will not be present for subscription mode.
9
  * @property \Stripe\Coupon $coupon Hash describing the coupon applied to create this discount.
10
  * @property string|\Stripe\Customer $customer The ID of the customer associated with this discount.
app/core/puc/.editorconfig ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [*]
2
+ charset=utf-8
3
+ end_of_line=lf
4
+ insert_final_newline=false
5
+ indent_style=tab
6
+ tab_width=4
7
+
8
+ [{phpunit.xml.dist,*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}]
9
+ indent_style=space
10
+ indent_size=4
11
+
12
+ [*.svg]
13
+ indent_style=space
14
+ indent_size=4
15
+
app/core/puc/.gitignore ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Created by .ignore support plugin (hsz.mobi)
2
+ ### JetBrains template
3
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
4
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
5
+
6
+ # The entire IDEA/PhpStorm directory
7
+ .idea/
8
+
9
+ # CMake
10
+ cmake-build-*/
11
+
12
+ # Mongo Explorer plugin
13
+ .idea/**/mongoSettings.xml
14
+
15
+ # File-based project format
16
+ *.iws
17
+
18
+ # IntelliJ
19
+ out/
20
+
21
+ # mpeltonen/sbt-idea plugin
22
+ .idea_modules/
23
+
24
+ # JIRA plugin
25
+ atlassian-ide-plugin.xml
26
+
27
+ # Cursive Clojure plugin
28
+ .idea/replstate.xml
29
+
30
+ # Crashlytics plugin (for Android Studio and IntelliJ)
31
+ com_crashlytics_export_strings.xml
32
+ crashlytics.properties
33
+ crashlytics-build.properties
34
+ fabric.properties
35
+
36
+ # Editor-based Rest Client
37
+ .idea/httpRequests
38
+
39
+ # Android studio 3.1+ serialized cache file
40
+ .idea/caches/build_file_checksums.ser
app/core/puc/Puc/v4/Factory.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4_Factory', false) ):
3
+
4
+ class Puc_v4_Factory extends Puc_v4p11_Factory { }
5
+
6
+ endif;
app/core/puc/Puc/v4p11/Autoloader.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_Autoloader', false) ):
4
+
5
+ class Puc_v4p11_Autoloader {
6
+ private $prefix = '';
7
+ private $rootDir = '';
8
+ private $libraryDir = '';
9
+
10
+ private $staticMap;
11
+
12
+ public function __construct() {
13
+ $this->rootDir = dirname(__FILE__) . '/';
14
+ $nameParts = explode('_', __CLASS__, 3);
15
+ $this->prefix = $nameParts[0] . '_' . $nameParts[1] . '_';
16
+
17
+ $this->libraryDir = $this->rootDir . '../..';
18
+ if ( !self::isPhar() ) {
19
+ $this->libraryDir = realpath($this->libraryDir);
20
+ }
21
+ $this->libraryDir = $this->libraryDir . '/';
22
+
23
+ $this->staticMap = array(
24
+ 'PucReadmeParser' => 'vendor/PucReadmeParser.php',
25
+ 'Parsedown' => 'vendor/Parsedown.php',
26
+ 'Puc_v4_Factory' => 'Puc/v4/Factory.php',
27
+ );
28
+
29
+ spl_autoload_register(array($this, 'autoload'));
30
+ }
31
+
32
+ /**
33
+ * Determine if this file is running as part of a Phar archive.
34
+ *
35
+ * @return bool
36
+ */
37
+ private static function isPhar() {
38
+ //Check if the current file path starts with "phar://".
39
+ static $pharProtocol = 'phar://';
40
+ return (substr(__FILE__, 0, strlen($pharProtocol)) === $pharProtocol);
41
+ }
42
+
43
+ public function autoload($className) {
44
+ if ( isset($this->staticMap[$className]) && file_exists($this->libraryDir . $this->staticMap[$className]) ) {
45
+ /** @noinspection PhpIncludeInspection */
46
+ include ($this->libraryDir . $this->staticMap[$className]);
47
+ return;
48
+ }
49
+
50
+ if (strpos($className, $this->prefix) === 0) {
51
+ $path = substr($className, strlen($this->prefix));
52
+ $path = str_replace('_', '/', $path);
53
+ $path = $this->rootDir . $path . '.php';
54
+
55
+ if (file_exists($path)) {
56
+ /** @noinspection PhpIncludeInspection */
57
+ include $path;
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ endif;
app/core/puc/Puc/v4p11/DebugBar/Extension.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_DebugBar_Extension', false) ):
3
+
4
+ class Puc_v4p11_DebugBar_Extension {
5
+ const RESPONSE_BODY_LENGTH_LIMIT = 4000;
6
+
7
+ /** @var Puc_v4p11_UpdateChecker */
8
+ protected $updateChecker;
9
+ protected $panelClass = 'Puc_v4p11_DebugBar_Panel';
10
+
11
+ public function __construct($updateChecker, $panelClass = null) {
12
+ $this->updateChecker = $updateChecker;
13
+ if ( isset($panelClass) ) {
14
+ $this->panelClass = $panelClass;
15
+ }
16
+
17
+ if ( version_compare(PHP_VERSION, '5.3', '>=') && (strpos($this->panelClass, '\\') === false) ) {
18
+ $this->panelClass = __NAMESPACE__ . '\\' . $this->panelClass;
19
+ }
20
+
21
+ add_filter('debug_bar_panels', array($this, 'addDebugBarPanel'));
22
+ add_action('debug_bar_enqueue_scripts', array($this, 'enqueuePanelDependencies'));
23
+
24
+ add_action('wp_ajax_puc_v4_debug_check_now', array($this, 'ajaxCheckNow'));
25
+ }
26
+
27
+ /**
28
+ * Register the PUC Debug Bar panel.
29
+ *
30
+ * @param array $panels
31
+ * @return array
32
+ */
33
+ public function addDebugBarPanel($panels) {
34
+ if ( $this->updateChecker->userCanInstallUpdates() ) {
35
+ $panels[] = new $this->panelClass($this->updateChecker);
36
+ }
37
+ return $panels;
38
+ }
39
+
40
+ /**
41
+ * Enqueue our Debug Bar scripts and styles.
42
+ */
43
+ public function enqueuePanelDependencies() {
44
+ wp_enqueue_style(
45
+ 'puc-debug-bar-style-v4',
46
+ $this->getLibraryUrl("/css/puc-debug-bar.css"),
47
+ array('debug-bar'),
48
+ '20171124'
49
+ );
50
+
51
+ wp_enqueue_script(
52
+ 'puc-debug-bar-js-v4',
53
+ $this->getLibraryUrl("/js/debug-bar.js"),
54
+ array('jquery'),
55
+ '20201209'
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Run an update check and output the result. Useful for making sure that
61
+ * the update checking process works as expected.
62
+ */
63
+ public function ajaxCheckNow() {
64
+ if ( $_POST['uid'] !== $this->updateChecker->getUniqueName('uid') ) {
65
+ return;
66
+ }
67
+ $this->preAjaxRequest();
68
+ $update = $this->updateChecker->checkForUpdates();
69
+ if ( $update !== null ) {
70
+ echo "An update is available:";
71
+ echo '<pre>', htmlentities(print_r($update, true)), '</pre>';
72
+ } else {
73
+ echo 'No updates found.';
74
+ }
75
+
76
+ $errors = $this->updateChecker->getLastRequestApiErrors();
77
+ if ( !empty($errors) ) {
78
+ printf('<p>The update checker encountered %d API error%s.</p>', count($errors), (count($errors) > 1) ? 's' : '');
79
+
80
+ foreach (array_values($errors) as $num => $item) {
81
+ $wpError = $item['error'];
82
+ /** @var WP_Error $wpError */
83
+ printf('<h4>%d) %s</h4>', $num + 1, esc_html($wpError->get_error_message()));
84
+
85
+ echo '<dl>';
86
+ printf('<dt>Error code:</dt><dd><code>%s</code></dd>', esc_html($wpError->get_error_code()));
87
+
88
+ if ( isset($item['url']) ) {
89
+ printf('<dt>Requested URL:</dt><dd><code>%s</code></dd>', esc_html($item['url']));
90
+ }
91
+
92
+ if ( isset($item['httpResponse']) ) {
93
+ if ( is_wp_error($item['httpResponse']) ) {
94
+ $httpError = $item['httpResponse'];
95
+ /** @var WP_Error $httpError */
96
+ printf(
97
+ '<dt>WordPress HTTP API error:</dt><dd>%s (<code>%s</code>)</dd>',
98
+ esc_html($httpError->get_error_message()),
99
+ esc_html($httpError->get_error_code())
100
+ );
101
+ } else {
102
+ //Status code.
103
+ printf(
104
+ '<dt>HTTP status:</dt><dd><code>%d %s</code></dd>',
105
+ wp_remote_retrieve_response_code($item['httpResponse']),
106
+ wp_remote_retrieve_response_message($item['httpResponse'])
107
+ );
108
+
109
+ //Headers.
110
+ echo '<dt>Response headers:</dt><dd><pre>';
111
+ foreach (wp_remote_retrieve_headers($item['httpResponse']) as $name => $value) {
112
+ printf("%s: %s\n", esc_html($name), esc_html($value));
113
+ }
114
+ echo '</pre></dd>';
115
+
116
+ //Body.
117
+ $body = wp_remote_retrieve_body($item['httpResponse']);
118
+ if ( $body === '' ) {
119
+ $body = '(Empty response.)';
120
+ } else if ( strlen($body) > self::RESPONSE_BODY_LENGTH_LIMIT ) {
121
+ $length = strlen($body);
122
+ $body = substr($body, 0, self::RESPONSE_BODY_LENGTH_LIMIT)
123
+ . sprintf("\n(Long string truncated. Total length: %d bytes.)", $length);
124
+ }
125
+
126
+ printf('<dt>Response body:</dt><dd><pre>%s</pre></dd>', esc_html($body));
127
+ }
128
+ }
129
+ echo '<dl>';
130
+ }
131
+ }
132
+
133
+ exit;
134
+ }
135
+
136
+ /**
137
+ * Check access permissions and enable error display (for debugging).
138
+ */
139
+ protected function preAjaxRequest() {
140
+ if ( !$this->updateChecker->userCanInstallUpdates() ) {
141
+ die('Access denied');
142
+ }
143
+ check_ajax_referer('puc-ajax');
144
+
145
+ error_reporting(E_ALL);
146
+ @ini_set('display_errors', 'On');
147
+ }
148
+
149
+ /**
150
+ * Remove hooks that were added by this extension.
151
+ */
152
+ public function removeHooks() {
153
+ remove_filter('debug_bar_panels', array($this, 'addDebugBarPanel'));
154
+ remove_action('debug_bar_enqueue_scripts', array($this, 'enqueuePanelDependencies'));
155
+ remove_action('wp_ajax_puc_v4_debug_check_now', array($this, 'ajaxCheckNow'));
156
+ }
157
+
158
+ /**
159
+ * @param string $filePath
160
+ * @return string
161
+ */
162
+ private function getLibraryUrl($filePath) {
163
+ $absolutePath = realpath(dirname(__FILE__) . '/../../../' . ltrim($filePath, '/'));
164
+
165
+ //Where is the library located inside the WordPress directory structure?
166
+ $absolutePath = Puc_v4p11_Factory::normalizePath($absolutePath);
167
+
168
+ $pluginDir = Puc_v4p11_Factory::normalizePath(WP_PLUGIN_DIR);
169
+ $muPluginDir = Puc_v4p11_Factory::normalizePath(WPMU_PLUGIN_DIR);
170
+ $themeDir = Puc_v4p11_Factory::normalizePath(get_theme_root());
171
+
172
+ if ( (strpos($absolutePath, $pluginDir) === 0) || (strpos($absolutePath, $muPluginDir) === 0) ) {
173
+ //It's part of a plugin.
174
+ return plugins_url(basename($absolutePath), $absolutePath);
175
+ } else if ( strpos($absolutePath, $themeDir) === 0 ) {
176
+ //It's part of a theme.
177
+ $relativePath = substr($absolutePath, strlen($themeDir) + 1);
178
+ $template = substr($relativePath, 0, strpos($relativePath, '/'));
179
+ $baseUrl = get_theme_root_uri($template);
180
+
181
+ if ( !empty($baseUrl) && $relativePath ) {
182
+ return $baseUrl . '/' . $relativePath;
183
+ }
184
+ }
185
+
186
+ return '';
187
+ }
188
+ }
189
+
190
+ endif;
app/core/puc/Puc/v4p11/DebugBar/Panel.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_DebugBar_Panel', false) && class_exists('Debug_Bar_Panel', false) ):
4
+
5
+ class Puc_v4p11_DebugBar_Panel extends Debug_Bar_Panel {
6
+ /** @var Puc_v4p11_UpdateChecker */
7
+ protected $updateChecker;
8
+
9
+ private $responseBox = '<div class="puc-ajax-response" style="display: none;"></div>';
10
+
11
+ public function __construct($updateChecker) {
12
+ $this->updateChecker = $updateChecker;
13
+ $title = sprintf(
14
+ '<span class="puc-debug-menu-link-%s">PUC (%s)</span>',
15
+ esc_attr($this->updateChecker->getUniqueName('uid')),
16
+ $this->updateChecker->slug
17
+ );
18
+ parent::__construct($title);
19
+ }
20
+
21
+ public function render() {
22
+ printf(
23
+ '<div class="puc-debug-bar-panel-v4" id="%1$s" data-slug="%2$s" data-uid="%3$s" data-nonce="%4$s">',
24
+ esc_attr($this->updateChecker->getUniqueName('debug-bar-panel')),
25
+ esc_attr($this->updateChecker->slug),
26
+ esc_attr($this->updateChecker->getUniqueName('uid')),
27
+ esc_attr(wp_create_nonce('puc-ajax'))
28
+ );
29
+
30
+ $this->displayConfiguration();
31
+ $this->displayStatus();
32
+ $this->displayCurrentUpdate();
33
+
34
+ echo '</div>';
35
+ }
36
+
37
+ private function displayConfiguration() {
38
+ echo '<h3>Configuration</h3>';
39
+ echo '<table class="puc-debug-data">';
40
+ $this->displayConfigHeader();
41
+ $this->row('Slug', htmlentities($this->updateChecker->slug));
42
+ $this->row('DB option', htmlentities($this->updateChecker->optionName));
43
+
44
+ $requestInfoButton = $this->getMetadataButton();
45
+ $this->row('Metadata URL', htmlentities($this->updateChecker->metadataUrl) . ' ' . $requestInfoButton . $this->responseBox);
46
+
47
+ $scheduler = $this->updateChecker->scheduler;
48
+ if ( $scheduler->checkPeriod > 0 ) {
49
+ $this->row('Automatic checks', 'Every ' . $scheduler->checkPeriod . ' hours');
50
+ } else {
51
+ $this->row('Automatic checks', 'Disabled');
52
+ }
53
+
54
+ if ( isset($scheduler->throttleRedundantChecks) ) {
55
+ if ( $scheduler->throttleRedundantChecks && ($scheduler->checkPeriod > 0) ) {
56
+ $this->row(
57
+ 'Throttling',
58
+ sprintf(
59
+ 'Enabled. If an update is already available, check for updates every %1$d hours instead of every %2$d hours.',
60
+ $scheduler->throttledCheckPeriod,
61
+ $scheduler->checkPeriod
62
+ )
63
+ );
64
+ } else {
65
+ $this->row('Throttling', 'Disabled');
66
+ }
67
+ }
68
+
69
+ $this->updateChecker->onDisplayConfiguration($this);
70
+
71
+ echo '</table>';
72
+ }
73
+
74
+ protected function displayConfigHeader() {
75
+ //Do nothing. This should be implemented in subclasses.
76
+ }
77
+
78
+ protected function getMetadataButton() {
79
+ return '';
80
+ }
81
+
82
+ private function displayStatus() {
83
+ echo '<h3>Status</h3>';
84
+ echo '<table class="puc-debug-data">';
85
+ $state = $this->updateChecker->getUpdateState();
86
+ $checkNowButton = '';
87
+ if ( function_exists('get_submit_button') ) {
88
+ $checkNowButton = get_submit_button(
89
+ 'Check Now',
90
+ 'secondary',
91
+ 'puc-check-now-button',
92
+ false,
93
+ array('id' => $this->updateChecker->getUniqueName('check-now-button'))
94
+ );
95
+ }
96
+
97
+ if ( $state->getLastCheck() > 0 ) {
98
+ $this->row('Last check', $this->formatTimeWithDelta($state->getLastCheck()) . ' ' . $checkNowButton . $this->responseBox);
99
+ } else {
100
+ $this->row('Last check', 'Never');
101
+ }
102
+
103
+ $nextCheck = wp_next_scheduled($this->updateChecker->scheduler->getCronHookName());
104
+ $this->row('Next automatic check', $this->formatTimeWithDelta($nextCheck));
105
+
106
+ if ( $state->getCheckedVersion() !== '' ) {
107
+ $this->row('Checked version', htmlentities($state->getCheckedVersion()));
108
+ $this->row('Cached update', $state->getUpdate());
109
+ }
110
+ $this->row('Update checker class', htmlentities(get_class($this->updateChecker)));
111
+ echo '</table>';
112
+ }
113
+
114
+ private function displayCurrentUpdate() {
115
+ $update = $this->updateChecker->getUpdate();
116
+ if ( $update !== null ) {
117
+ echo '<h3>An Update Is Available</h3>';
118
+ echo '<table class="puc-debug-data">';
119
+ $fields = $this->getUpdateFields();
120
+ foreach($fields as $field) {
121
+ if ( property_exists($update, $field) ) {
122
+ $this->row(ucwords(str_replace('_', ' ', $field)), htmlentities($update->$field));
123
+ }
124
+ }
125
+ echo '</table>';
126
+ } else {
127
+ echo '<h3>No updates currently available</h3>';
128
+ }
129
+ }
130
+
131
+ protected function getUpdateFields() {
132
+ return array('version', 'download_url', 'slug',);
133
+ }
134
+
135
+ private function formatTimeWithDelta($unixTime) {
136
+ if ( empty($unixTime) ) {
137
+ return 'Never';
138
+ }
139
+
140
+ $delta = time() - $unixTime;
141
+ $result = human_time_diff(time(), $unixTime);
142
+ if ( $delta < 0 ) {
143
+ $result = 'after ' . $result;
144
+ } else {
145
+ $result = $result . ' ago';
146
+ }
147
+ $result .= ' (' . $this->formatTimestamp($unixTime) . ')';
148
+ return $result;
149
+ }
150
+
151
+ private function formatTimestamp($unixTime) {
152
+ return gmdate('Y-m-d H:i:s', $unixTime + (get_option('gmt_offset') * 3600));
153
+ }
154
+
155
+ public function row($name, $value) {
156
+ if ( is_object($value) || is_array($value) ) {
157
+ $value = '<pre>' . htmlentities(print_r($value, true)) . '</pre>';
158
+ } else if ($value === null) {
159
+ $value = '<code>null</code>';
160
+ }
161
+ printf('<tr><th scope="row">%1$s</th> <td>%2$s</td></tr>', $name, $value);
162
+ }
163
+ }
164
+
165
+ endif;
app/core/puc/Puc/v4p11/DebugBar/PluginExtension.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_DebugBar_PluginExtension', false) ):
3
+
4
+ class Puc_v4p11_DebugBar_PluginExtension extends Puc_v4p11_DebugBar_Extension {
5
+ /** @var Puc_v4p11_Plugin_UpdateChecker */
6
+ protected $updateChecker;
7
+
8
+ public function __construct($updateChecker) {
9
+ parent::__construct($updateChecker, 'Puc_v4p11_DebugBar_PluginPanel');
10
+
11
+ add_action('wp_ajax_puc_v4_debug_request_info', array($this, 'ajaxRequestInfo'));
12
+ }
13
+
14
+ /**
15
+ * Request plugin info and output it.
16
+ */
17
+ public function ajaxRequestInfo() {
18
+ if ( $_POST['uid'] !== $this->updateChecker->getUniqueName('uid') ) {
19
+ return;
20
+ }
21
+ $this->preAjaxRequest();
22
+ $info = $this->updateChecker->requestInfo();
23
+ if ( $info !== null ) {
24
+ echo 'Successfully retrieved plugin info from the metadata URL:';
25
+ echo '<pre>', htmlentities(print_r($info, true)), '</pre>';
26
+ } else {
27
+ echo 'Failed to retrieve plugin info from the metadata URL.';
28
+ }
29
+ exit;
30
+ }
31
+ }
32
+
33
+ endif;
app/core/puc/Puc/v4p11/DebugBar/PluginPanel.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_DebugBar_PluginPanel', false) ):
4
+
5
+ class Puc_v4p11_DebugBar_PluginPanel extends Puc_v4p11_DebugBar_Panel {
6
+ /**
7
+ * @var Puc_v4p11_Plugin_UpdateChecker
8
+ */
9
+ protected $updateChecker;
10
+
11
+ protected function displayConfigHeader() {
12
+ $this->row('Plugin file', htmlentities($this->updateChecker->pluginFile));
13
+ parent::displayConfigHeader();
14
+ }
15
+
16
+ protected function getMetadataButton() {
17
+ $requestInfoButton = '';
18
+ if ( function_exists('get_submit_button') ) {
19
+ $requestInfoButton = get_submit_button(
20
+ 'Request Info',
21
+ 'secondary',
22
+ 'puc-request-info-button',
23
+ false,
24
+ array('id' => $this->updateChecker->getUniqueName('request-info-button'))
25
+ );
26
+ }
27
+ return $requestInfoButton;
28
+ }
29
+
30
+ protected function getUpdateFields() {
31
+ return array_merge(
32
+ parent::getUpdateFields(),
33
+ array('homepage', 'upgrade_notice', 'tested',)
34
+ );
35
+ }
36
+ }
37
+
38
+ endif;
app/core/puc/Puc/v4p11/DebugBar/ThemePanel.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_DebugBar_ThemePanel', false) ):
4
+
5
+ class Puc_v4p11_DebugBar_ThemePanel extends Puc_v4p11_DebugBar_Panel {
6
+ /**
7
+ * @var Puc_v4p11_Theme_UpdateChecker
8
+ */
9
+ protected $updateChecker;
10
+
11
+ protected function displayConfigHeader() {
12
+ $this->row('Theme directory', htmlentities($this->updateChecker->directoryName));
13
+ parent::displayConfigHeader();
14
+ }
15
+
16
+ protected function getUpdateFields() {
17
+ return array_merge(parent::getUpdateFields(), array('details_url'));
18
+ }
19
+ }
20
+
21
+ endif;
app/core/puc/Puc/v4p11/Factory.php ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Factory', false) ):
3
+
4
+ /**
5
+ * A factory that builds update checker instances.
6
+ *
7
+ * When multiple versions of the same class have been loaded (e.g. PluginUpdateChecker 4.0
8
+ * and 4.1), this factory will always use the latest available minor version. Register class
9
+ * versions by calling {@link PucFactory::addVersion()}.
10
+ *
11
+ * At the moment it can only build instances of the UpdateChecker class. Other classes are
12
+ * intended mainly for internal use and refer directly to specific implementations.
13
+ */
14
+ class Puc_v4p11_Factory {
15
+ protected static $classVersions = array();
16
+ protected static $sorted = false;
17
+
18
+ protected static $myMajorVersion = '';
19
+ protected static $latestCompatibleVersion = '';
20
+
21
+ /**
22
+ * A wrapper method for buildUpdateChecker() that reads the metadata URL from the plugin or theme header.
23
+ *
24
+ * @param string $fullPath Full path to the main plugin file or the theme's style.css.
25
+ * @param array $args Optional arguments. Keys should match the argument names of the buildUpdateChecker() method.
26
+ * @return Puc_v4p11_Plugin_UpdateChecker|Puc_v4p11_Theme_UpdateChecker|Puc_v4p11_Vcs_BaseChecker
27
+ */
28
+ public static function buildFromHeader($fullPath, $args = array()) {
29
+ $fullPath = self::normalizePath($fullPath);
30
+
31
+ //Set up defaults.
32
+ $defaults = array(
33
+ 'metadataUrl' => '',
34
+ 'slug' => '',
35
+ 'checkPeriod' => 12,
36
+ 'optionName' => '',
37
+ 'muPluginFile' => '',
38
+ );
39
+ $args = array_merge($defaults, array_intersect_key($args, $defaults));
40
+ extract($args, EXTR_SKIP);
41
+
42
+ //Check for the service URI
43
+ if ( empty($metadataUrl) ) {
44
+ $metadataUrl = self::getServiceURI($fullPath);
45
+ }
46
+
47
+ /** @noinspection PhpUndefinedVariableInspection These variables are created by extract(), above. */
48
+ return self::buildUpdateChecker($metadataUrl, $fullPath, $slug, $checkPeriod, $optionName, $muPluginFile);
49
+ }
50
+
51
+ /**
52
+ * Create a new instance of the update checker.
53
+ *
54
+ * This method automatically detects if you're using it for a plugin or a theme and chooses
55
+ * the appropriate implementation for your update source (JSON file, GitHub, BitBucket, etc).
56
+ *
57
+ * @see Puc_v4p11_UpdateChecker::__construct
58
+ *
59
+ * @param string $metadataUrl The URL of the metadata file, a GitHub repository, or another supported update source.
60
+ * @param string $fullPath Full path to the main plugin file or to the theme directory.
61
+ * @param string $slug Custom slug. Defaults to the name of the main plugin file or the theme directory.
62
+ * @param int $checkPeriod How often to check for updates (in hours).
63
+ * @param string $optionName Where to store book-keeping info about update checks.
64
+ * @param string $muPluginFile The plugin filename relative to the mu-plugins directory.
65
+ * @return Puc_v4p11_Plugin_UpdateChecker|Puc_v4p11_Theme_UpdateChecker|Puc_v4p11_Vcs_BaseChecker
66
+ */
67
+ public static function buildUpdateChecker($metadataUrl, $fullPath, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
68
+ $fullPath = self::normalizePath($fullPath);
69
+ $id = null;
70
+
71
+ //Plugin or theme?
72
+ $themeDirectory = self::getThemeDirectoryName($fullPath);
73
+ if ( self::isPluginFile($fullPath) ) {
74
+ $type = 'Plugin';
75
+ $id = $fullPath;
76
+ } else if ( $themeDirectory !== null ) {
77
+ $type = 'Theme';
78
+ $id = $themeDirectory;
79
+ } else {
80
+ throw new RuntimeException(sprintf(
81
+ 'The update checker cannot determine if "%s" is a plugin or a theme. ' .
82
+ 'This is a bug. Please contact the PUC developer.',
83
+ htmlentities($fullPath)
84
+ ));
85
+ }
86
+
87
+ //Which hosting service does the URL point to?
88
+ $service = self::getVcsService($metadataUrl);
89
+
90
+ $apiClass = null;
91
+ if ( empty($service) ) {
92
+ //The default is to get update information from a remote JSON file.
93
+ $checkerClass = $type . '_UpdateChecker';
94
+ } else {
95
+ //You can also use a VCS repository like GitHub.
96
+ $checkerClass = 'Vcs_' . $type . 'UpdateChecker';
97
+ $apiClass = $service . 'Api';
98
+ }
99
+
100
+ $checkerClass = self::getCompatibleClassVersion($checkerClass);
101
+ if ( $checkerClass === null ) {
102
+ trigger_error(
103
+ sprintf(
104
+ 'PUC %s does not support updates for %ss %s',
105
+ htmlentities(self::$latestCompatibleVersion),
106
+ strtolower($type),
107
+ $service ? ('hosted on ' . htmlentities($service)) : 'using JSON metadata'
108
+ ),
109
+ E_USER_ERROR
110
+ );
111
+ return null;
112
+ }
113
+
114
+ //Add the current namespace to the class name(s).
115
+ if ( version_compare(PHP_VERSION, '5.3', '>=') ) {
116
+ $checkerClass = __NAMESPACE__ . '\\' . $checkerClass;
117
+ }
118
+
119
+ if ( !isset($apiClass) ) {
120
+ //Plain old update checker.
121
+ return new $checkerClass($metadataUrl, $id, $slug, $checkPeriod, $optionName, $muPluginFile);
122
+ } else {
123
+ //VCS checker + an API client.
124
+ $apiClass = self::getCompatibleClassVersion($apiClass);
125
+ if ( $apiClass === null ) {
126
+ trigger_error(sprintf(
127
+ 'PUC %s does not support %s',
128
+ htmlentities(self::$latestCompatibleVersion),
129
+ htmlentities($service)
130
+ ), E_USER_ERROR);
131
+ return null;
132
+ }
133
+
134
+ if ( version_compare(PHP_VERSION, '5.3', '>=') && (strpos($apiClass, '\\') === false) ) {
135
+ $apiClass = __NAMESPACE__ . '\\' . $apiClass;
136
+ }
137
+
138
+ return new $checkerClass(
139
+ new $apiClass($metadataUrl),
140
+ $id,
141
+ $slug,
142
+ $checkPeriod,
143
+ $optionName,
144
+ $muPluginFile
145
+ );
146
+ }
147
+ }
148
+
149
+ /**
150
+ *
151
+ * Normalize a filesystem path. Introduced in WP 3.9.
152
+ * Copying here allows use of the class on earlier versions.
153
+ * This version adapted from WP 4.8.2 (unchanged since 4.5.0)
154
+ *
155
+ * @param string $path Path to normalize.
156
+ * @return string Normalized path.
157
+ */
158
+ public static function normalizePath($path) {
159
+ if ( function_exists('wp_normalize_path') ) {
160
+ return wp_normalize_path($path);
161
+ }
162
+ $path = str_replace('\\', '/', $path);
163
+ $path = preg_replace('|(?<=.)/+|', '/', $path);
164
+ if ( substr($path, 1, 1) === ':' ) {
165
+ $path = ucfirst($path);
166
+ }
167
+ return $path;
168
+ }
169
+
170
+ /**
171
+ * Check if the path points to a plugin file.
172
+ *
173
+ * @param string $absolutePath Normalized path.
174
+ * @return bool
175
+ */
176
+ protected static function isPluginFile($absolutePath) {
177
+ //Is the file inside the "plugins" or "mu-plugins" directory?
178
+ $pluginDir = self::normalizePath(WP_PLUGIN_DIR);
179
+ $muPluginDir = self::normalizePath(WPMU_PLUGIN_DIR);
180
+ if ( (strpos($absolutePath, $pluginDir) === 0) || (strpos($absolutePath, $muPluginDir) === 0) ) {
181
+ return true;
182
+ }
183
+
184
+ //Is it a file at all? Caution: is_file() can fail if the parent dir. doesn't have the +x permission set.
185
+ if ( !is_file($absolutePath) ) {
186
+ return false;
187
+ }
188
+
189
+ //Does it have a valid plugin header?
190
+ //This is a last-ditch check for plugins symlinked from outside the WP root.
191
+ if ( function_exists('get_file_data') ) {
192
+ $headers = get_file_data($absolutePath, array('Name' => 'Plugin Name'), 'plugin');
193
+ return !empty($headers['Name']);
194
+ }
195
+
196
+ return false;
197
+ }
198
+
199
+ /**
200
+ * Get the name of the theme's directory from a full path to a file inside that directory.
201
+ * E.g. "/abc/public_html/wp-content/themes/foo/whatever.php" => "foo".
202
+ *
203
+ * Note that subdirectories are currently not supported. For example,
204
+ * "/xyz/wp-content/themes/my-theme/includes/whatever.php" => NULL.
205
+ *
206
+ * @param string $absolutePath Normalized path.
207
+ * @return string|null Directory name, or NULL if the path doesn't point to a theme.
208
+ */
209
+ protected static function getThemeDirectoryName($absolutePath) {
210
+ if ( is_file($absolutePath) ) {
211
+ $absolutePath = dirname($absolutePath);
212
+ }
213
+
214
+ if ( file_exists($absolutePath . '/style.css') ) {
215
+ return basename($absolutePath);
216
+ }
217
+ return null;
218
+ }
219
+
220
+ /**
221
+ * Get the service URI from the file header.
222
+ *
223
+ * @param string $fullPath
224
+ * @return string
225
+ */
226
+ private static function getServiceURI($fullPath) {
227
+ //Look for the URI
228
+ if ( is_readable($fullPath) ) {
229
+ $seek = array(
230
+ 'github' => 'GitHub URI',
231
+ 'gitlab' => 'GitLab URI',
232
+ 'bucket' => 'BitBucket URI',
233
+ );
234
+ $seek = apply_filters('puc_get_source_uri', $seek);
235
+ $data = get_file_data($fullPath, $seek);
236
+ foreach ($data as $key => $uri) {
237
+ if ( $uri ) {
238
+ return $uri;
239
+ }
240
+ }
241
+ }
242
+
243
+ //URI was not found so throw an error.
244
+ throw new RuntimeException(
245
+ sprintf('Unable to locate URI in header of "%s"', htmlentities($fullPath))
246
+ );
247
+ }
248
+
249
+ /**
250
+ * Get the name of the hosting service that the URL points to.
251
+ *
252
+ * @param string $metadataUrl
253
+ * @return string|null
254
+ */
255
+ private static function getVcsService($metadataUrl) {
256
+ $service = null;
257
+
258
+ //Which hosting service does the URL point to?
259
+ $host = parse_url($metadataUrl, PHP_URL_HOST);
260
+ $path = parse_url($metadataUrl, PHP_URL_PATH);
261
+
262
+ //Check if the path looks like "/user-name/repository".
263
+ //For GitLab.com it can also be "/user/group1/group2/.../repository".
264
+ $repoRegex = '@^/?([^/]+?)/([^/#?&]+?)/?$@';
265
+ if ( $host === 'gitlab.com' ) {
266
+ $repoRegex = '@^/?(?:[^/#?&]++/){1,20}(?:[^/#?&]++)/?$@';
267
+ }
268
+ if ( preg_match($repoRegex, $path) ) {
269
+ $knownServices = array(
270
+ 'github.com' => 'GitHub',
271
+ 'bitbucket.org' => 'BitBucket',
272
+ 'gitlab.com' => 'GitLab',
273
+ );
274
+ if ( isset($knownServices[$host]) ) {
275
+ $service = $knownServices[$host];
276
+ }
277
+ }
278
+
279
+ return apply_filters('puc_get_vcs_service', $service, $host, $path, $metadataUrl);
280
+ }
281
+
282
+ /**
283
+ * Get the latest version of the specified class that has the same major version number
284
+ * as this factory class.
285
+ *
286
+ * @param string $class Partial class name.
287
+ * @return string|null Full class name.
288
+ */
289
+ protected static function getCompatibleClassVersion($class) {
290
+ if ( isset(self::$classVersions[$class][self::$latestCompatibleVersion]) ) {
291
+ return self::$classVersions[$class][self::$latestCompatibleVersion];
292
+ }
293
+ return null;
294
+ }
295
+
296
+ /**
297
+ * Get the specific class name for the latest available version of a class.
298
+ *
299
+ * @param string $class
300
+ * @return null|string
301
+ */
302
+ public static function getLatestClassVersion($class) {
303
+ if ( !self::$sorted ) {
304
+ self::sortVersions();
305
+ }
306
+
307
+ if ( isset(self::$classVersions[$class]) ) {
308
+ return reset(self::$classVersions[$class]);
309
+ } else {
310
+ return null;
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Sort available class versions in descending order (i.e. newest first).
316
+ */
317
+ protected static function sortVersions() {
318
+ foreach ( self::$classVersions as $class => $versions ) {
319
+ uksort($versions, array(__CLASS__, 'compareVersions'));
320
+ self::$classVersions[$class] = $versions;
321
+ }
322
+ self::$sorted = true;
323
+ }
324
+
325
+ protected static function compareVersions($a, $b) {
326
+ return -version_compare($a, $b);
327
+ }
328
+
329
+ /**
330
+ * Register a version of a class.
331
+ *
332
+ * @access private This method is only for internal use by the library.
333
+ *
334
+ * @param string $generalClass Class name without version numbers, e.g. 'PluginUpdateChecker'.
335
+ * @param string $versionedClass Actual class name, e.g. 'PluginUpdateChecker_1_2'.
336
+ * @param string $version Version number, e.g. '1.2'.
337
+ */
338
+ public static function addVersion($generalClass, $versionedClass, $version) {
339
+ if ( empty(self::$myMajorVersion) ) {
340
+ $nameParts = explode('_', __CLASS__, 3);
341
+ self::$myMajorVersion = substr(ltrim($nameParts[1], 'v'), 0, 1);
342
+ }
343
+
344
+ //Store the greatest version number that matches our major version.
345
+ $components = explode('.', $version);
346
+ if ( $components[0] === self::$myMajorVersion ) {
347
+
348
+ if (
349
+ empty(self::$latestCompatibleVersion)
350
+ || version_compare($version, self::$latestCompatibleVersion, '>')
351
+ ) {
352
+ self::$latestCompatibleVersion = $version;
353
+ }
354
+
355
+ }
356
+
357
+ if ( !isset(self::$classVersions[$generalClass]) ) {
358
+ self::$classVersions[$generalClass] = array();
359
+ }
360
+ self::$classVersions[$generalClass][$version] = $versionedClass;
361
+ self::$sorted = false;
362
+ }
363
+ }
364
+
365
+ endif;
app/core/puc/Puc/v4p11/InstalledPackage.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_InstalledPackage', false) ):
3
+
4
+ /**
5
+ * This class represents a currently installed plugin or theme.
6
+ *
7
+ * Not to be confused with the "package" field in WP update API responses that contains
8
+ * the download URL of a the new version.
9
+ */
10
+ abstract class Puc_v4p11_InstalledPackage {
11
+ /**
12
+ * @var Puc_v4p11_UpdateChecker
13
+ */
14
+ protected $updateChecker;
15
+
16
+ public function __construct($updateChecker) {
17
+ $this->updateChecker = $updateChecker;
18
+ }
19
+
20
+ /**
21
+ * Get the currently installed version of the plugin or theme.
22
+ *
23
+ * @return string|null Version number.
24
+ */
25
+ abstract public function getInstalledVersion();
26
+
27
+ /**
28
+ * Get the full path of the plugin or theme directory (without a trailing slash).
29
+ *
30
+ * @return string
31
+ */
32
+ abstract public function getAbsoluteDirectoryPath();
33
+
34
+ /**
35
+ * Check whether a regular file exists in the package's directory.
36
+ *
37
+ * @param string $relativeFileName File name relative to the package directory.
38
+ * @return bool
39
+ */
40
+ public function fileExists($relativeFileName) {
41
+ return is_file(
42
+ $this->getAbsoluteDirectoryPath()
43
+ . DIRECTORY_SEPARATOR
44
+ . ltrim($relativeFileName, '/\\')
45
+ );
46
+ }
47
+
48
+ /* -------------------------------------------------------------------
49
+ * File header parsing
50
+ * -------------------------------------------------------------------
51
+ */
52
+
53
+ /**
54
+ * Parse plugin or theme metadata from the header comment.
55
+ *
56
+ * This is basically a simplified version of the get_file_data() function from /wp-includes/functions.php.
57
+ * It's intended as a utility for subclasses that detect updates by parsing files in a VCS.
58
+ *
59
+ * @param string|null $content File contents.
60
+ * @return string[]
61
+ */
62
+ public function getFileHeader($content) {
63
+ $content = (string)$content;
64
+
65
+ //WordPress only looks at the first 8 KiB of the file, so we do the same.
66
+ $content = substr($content, 0, 8192);
67
+ //Normalize line endings.
68
+ $content = str_replace("\r", "\n", $content);
69
+
70
+ $headers = $this->getHeaderNames();
71
+ $results = array();
72
+ foreach ($headers as $field => $name) {
73
+ $success = preg_match('/^[ \t\/*#@]*' . preg_quote($name, '/') . ':(.*)$/mi', $content, $matches);
74
+
75
+ if ( ($success === 1) && $matches[1] ) {
76
+ $value = $matches[1];
77
+ if ( function_exists('_cleanup_header_comment') ) {
78
+ $value = _cleanup_header_comment($value);
79
+ }
80
+ $results[$field] = $value;
81
+ } else {
82
+ $results[$field] = '';
83
+ }
84
+ }
85
+
86
+ return $results;
87
+ }
88
+
89
+ /**
90
+ * @return array Format: ['HeaderKey' => 'Header Name']
91
+ */
92
+ abstract protected function getHeaderNames();
93
+
94
+ /**
95
+ * Get the value of a specific plugin or theme header.
96
+ *
97
+ * @param string $headerName
98
+ * @return string Either the value of the header, or an empty string if the header doesn't exist.
99
+ */
100
+ abstract public function getHeaderValue($headerName);
101
+
102
+ }
103
+ endif;
app/core/puc/Puc/v4p11/Metadata.php ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Metadata', false) ):
3
+
4
+ /**
5
+ * A base container for holding information about updates and plugin metadata.
6
+ *
7
+ * @author Janis Elsts
8
+ * @copyright 2016
9
+ * @access public
10
+ */
11
+ abstract class Puc_v4p11_Metadata {
12
+
13
+ /**
14
+ * Create an instance of this class from a JSON document.
15
+ *
16
+ * @abstract
17
+ * @param string $json
18
+ * @return self
19
+ */
20
+ public static function fromJson(/** @noinspection PhpUnusedParameterInspection */ $json) {
21
+ throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
22
+ }
23
+
24
+ /**
25
+ * @param string $json
26
+ * @param self $target
27
+ * @return bool
28
+ */
29
+ protected static function createFromJson($json, $target) {
30
+ /** @var StdClass $apiResponse */
31
+ $apiResponse = json_decode($json);
32
+ if ( empty($apiResponse) || !is_object($apiResponse) ){
33
+ $errorMessage = "Failed to parse update metadata. Try validating your .json file with http://jsonlint.com/";
34
+ do_action('puc_api_error', new WP_Error('puc-invalid-json', $errorMessage));
35
+ trigger_error($errorMessage, E_USER_NOTICE);
36
+ return false;
37
+ }
38
+
39
+ $valid = $target->validateMetadata($apiResponse);
40
+ if ( is_wp_error($valid) ){
41
+ do_action('puc_api_error', $valid);
42
+ trigger_error($valid->get_error_message(), E_USER_NOTICE);
43
+ return false;
44
+ }
45
+
46
+ foreach(get_object_vars($apiResponse) as $key => $value){
47
+ $target->$key = $value;
48
+ }
49
+
50
+ return true;
51
+ }
52
+
53
+ /**
54
+ * No validation by default! Subclasses should check that the required fields are present.
55
+ *
56
+ * @param StdClass $apiResponse
57
+ * @return bool|WP_Error
58
+ */
59
+ protected function validateMetadata(/** @noinspection PhpUnusedParameterInspection */ $apiResponse) {
60
+ return true;
61
+ }
62
+
63
+ /**
64
+ * Create a new instance by copying the necessary fields from another object.
65
+ *
66
+ * @abstract
67
+ * @param StdClass|self $object The source object.
68
+ * @return self The new copy.
69
+ */
70
+ public static function fromObject(/** @noinspection PhpUnusedParameterInspection */ $object) {
71
+ throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
72
+ }
73
+
74
+ /**
75
+ * Create an instance of StdClass that can later be converted back to an
76
+ * update or info container. Useful for serialization and caching, as it
77
+ * avoids the "incomplete object" problem if the cached value is loaded
78
+ * before this class.
79
+ *
80
+ * @return StdClass
81
+ */
82
+ public function toStdClass() {
83
+ $object = new stdClass();
84
+ $this->copyFields($this, $object);
85
+ return $object;
86
+ }
87
+
88
+ /**
89
+ * Transform the metadata into the format used by WordPress core.
90
+ *
91
+ * @return object
92
+ */
93
+ abstract public function toWpFormat();
94
+
95
+ /**
96
+ * Copy known fields from one object to another.
97
+ *
98
+ * @param StdClass|self $from
99
+ * @param StdClass|self $to
100
+ */
101
+ protected function copyFields($from, $to) {
102
+ $fields = $this->getFieldNames();
103
+
104
+ if ( property_exists($from, 'slug') && !empty($from->slug) ) {
105
+ //Let plugins add extra fields without having to create subclasses.
106
+ $fields = apply_filters($this->getPrefixedFilter('retain_fields') . '-' . $from->slug, $fields);
107
+ }
108
+
109
+ foreach ($fields as $field) {
110
+ if ( property_exists($from, $field) ) {
111
+ $to->$field = $from->$field;
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * @return string[]
118
+ */
119
+ protected function getFieldNames() {
120
+ return array();
121
+ }
122
+
123
+ /**
124
+ * @param string $tag
125
+ * @return string
126
+ */
127
+ protected function getPrefixedFilter($tag) {
128
+ return 'puc_' . $tag;
129
+ }
130
+ }
131
+
132
+ endif;
app/core/puc/Puc/v4p11/OAuthSignature.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_OAuthSignature', false) ):
4
+
5
+ /**
6
+ * A basic signature generator for zero-legged OAuth 1.0.
7
+ */
8
+ class Puc_v4p11_OAuthSignature {
9
+ private $consumerKey = '';
10
+ private $consumerSecret = '';
11
+
12
+ public function __construct($consumerKey, $consumerSecret) {
13
+ $this->consumerKey = $consumerKey;
14
+ $this->consumerSecret = $consumerSecret;
15
+ }
16
+
17
+ /**
18
+ * Sign a URL using OAuth 1.0.
19
+ *
20
+ * @param string $url The URL to be signed. It may contain query parameters.
21
+ * @param string $method HTTP method such as "GET", "POST" and so on.
22
+ * @return string The signed URL.
23
+ */
24
+ public function sign($url, $method = 'GET') {
25
+ $parameters = array();
26
+
27
+ //Parse query parameters.
28
+ $query = parse_url($url, PHP_URL_QUERY);
29
+ if ( !empty($query) ) {
30
+ parse_str($query, $parsedParams);
31
+ if ( is_array($parameters) ) {
32
+ $parameters = $parsedParams;
33
+ }
34
+ //Remove the query string from the URL. We'll replace it later.
35
+ $url = substr($url, 0, strpos($url, '?'));
36
+ }
37
+
38
+ $parameters = array_merge(
39
+ $parameters,
40
+ array(
41
+ 'oauth_consumer_key' => $this->consumerKey,
42
+ 'oauth_nonce' => $this->nonce(),
43
+ 'oauth_signature_method' => 'HMAC-SHA1',
44
+ 'oauth_timestamp' => time(),
45
+ 'oauth_version' => '1.0',
46
+ )
47
+ );
48
+ unset($parameters['oauth_signature']);
49
+
50
+ //Parameters must be sorted alphabetically before signing.
51
+ ksort($parameters);
52
+
53
+ //The most complicated part of the request - generating the signature.
54
+ //The string to sign contains the HTTP method, the URL path, and all of
55
+ //our query parameters. Everything is URL encoded. Then we concatenate
56
+ //them with ampersands into a single string to hash.
57
+ $encodedVerb = urlencode($method);
58
+ $encodedUrl = urlencode($url);
59
+ $encodedParams = urlencode(http_build_query($parameters, '', '&'));
60
+
61
+ $stringToSign = $encodedVerb . '&' . $encodedUrl . '&' . $encodedParams;
62
+
63
+ //Since we only have one OAuth token (the consumer secret) we only have
64
+ //to use it as our HMAC key. However, we still have to append an & to it
65
+ //as if we were using it with additional tokens.
66
+ $secret = urlencode($this->consumerSecret) . '&';
67
+
68
+ //The signature is a hash of the consumer key and the base string. Note
69
+ //that we have to get the raw output from hash_hmac and base64 encode
70
+ //the binary data result.
71
+ $parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $stringToSign, $secret, true));
72
+
73
+ return ($url . '?' . http_build_query($parameters));
74
+ }
75
+
76
+ /**
77
+ * Generate a random nonce.
78
+ *
79
+ * @return string
80
+ */
81
+ private function nonce() {
82
+ $mt = microtime();
83
+
84
+ $rand = null;
85
+ if ( is_callable('random_bytes') ) {
86
+ try {
87
+ $rand = random_bytes(16);
88
+ } catch (Exception $ex) {
89
+ //Fall back to mt_rand (below).
90
+ }
91
+ }
92
+ if ( $rand === null ) {
93
+ $rand = mt_rand();
94
+ }
95
+
96
+ return md5($mt . '_' . $rand);
97
+ }
98
+ }
99
+
100
+ endif;
app/core/puc/Puc/v4p11/Plugin/Info.php ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Plugin_Info', false) ):
3
+
4
+ /**
5
+ * A container class for holding and transforming various plugin metadata.
6
+ *
7
+ * @author Janis Elsts
8
+ * @copyright 2016
9
+ * @access public
10
+ */
11
+ class Puc_v4p11_Plugin_Info extends Puc_v4p11_Metadata {
12
+ //Most fields map directly to the contents of the plugin's info.json file.
13
+ //See the relevant docs for a description of their meaning.
14
+ public $name;
15
+ public $slug;
16
+ public $version;
17
+ public $homepage;
18
+ public $sections = array();
19
+ public $download_url;
20
+
21
+ public $banners;
22
+ public $icons = array();
23
+ public $translations = array();
24
+
25
+ public $author;
26
+ public $author_homepage;
27
+
28
+ public $requires;
29
+ public $tested;
30
+ public $requires_php;
31
+ public $upgrade_notice;
32
+
33
+ public $rating;
34
+ public $num_ratings;
35
+ public $downloaded;
36
+ public $active_installs;
37
+ public $last_updated;
38
+
39
+ public $id = 0; //The native WP.org API returns numeric plugin IDs, but they're not used for anything.
40
+
41
+ public $filename; //Plugin filename relative to the plugins directory.
42
+
43
+ /**
44
+ * Create a new instance of Plugin Info from JSON-encoded plugin info
45
+ * returned by an external update API.
46
+ *
47
+ * @param string $json Valid JSON string representing plugin info.
48
+ * @return self|null New instance of Plugin Info, or NULL on error.
49
+ */
50
+ public static function fromJson($json){
51
+ $instance = new self();
52
+
53
+ if ( !parent::createFromJson($json, $instance) ) {
54
+ return null;
55
+ }
56
+
57
+ //json_decode decodes assoc. arrays as objects. We want them as arrays.
58
+ $instance->sections = (array)$instance->sections;
59
+ $instance->icons = (array)$instance->icons;
60
+
61
+ return $instance;
62
+ }
63
+
64
+ /**
65
+ * Very, very basic validation.
66
+ *
67
+ * @param StdClass $apiResponse
68
+ * @return bool|WP_Error
69
+ */
70
+ protected function validateMetadata($apiResponse) {
71
+ if (
72
+ !isset($apiResponse->name, $apiResponse->version)
73
+ || empty($apiResponse->name)
74
+ || empty($apiResponse->version)
75
+ ) {
76
+ return new WP_Error(
77
+ 'puc-invalid-metadata',
78
+ "The plugin metadata file does not contain the required 'name' and/or 'version' keys."
79
+ );
80
+ }
81
+ return true;
82
+ }
83
+
84
+
85
+ /**
86
+ * Transform plugin info into the format used by the native WordPress.org API
87
+ *
88
+ * @return object
89
+ */
90
+ public function toWpFormat(){
91
+ $info = new stdClass;
92
+
93
+ //The custom update API is built so that many fields have the same name and format
94
+ //as those returned by the native WordPress.org API. These can be assigned directly.
95
+ $sameFormat = array(
96
+ 'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice',
97
+ 'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated',
98
+ 'requires_php',
99
+ );
100
+ foreach($sameFormat as $field){
101
+ if ( isset($this->$field) ) {
102
+ $info->$field = $this->$field;
103
+ } else {
104
+ $info->$field = null;
105
+ }
106
+ }
107
+
108
+ //Other fields need to be renamed and/or transformed.
109
+ $info->download_link = $this->download_url;
110
+ $info->author = $this->getFormattedAuthor();
111
+ $info->sections = array_merge(array('description' => ''), $this->sections);
112
+
113
+ if ( !empty($this->banners) ) {
114
+ //WP expects an array with two keys: "high" and "low". Both are optional.
115
+ //Docs: https://wordpress.org/plugins/about/faq/#banners
116
+ $info->banners = is_object($this->banners) ? get_object_vars($this->banners) : $this->banners;
117
+ $info->banners = array_intersect_key($info->banners, array('high' => true, 'low' => true));
118
+ }
119
+
120
+ return $info;
121
+ }
122
+
123
+ protected function getFormattedAuthor() {
124
+ if ( !empty($this->author_homepage) ){
125
+ /** @noinspection HtmlUnknownTarget */
126
+ return sprintf('<a href="%s">%s</a>', $this->author_homepage, $this->author);
127
+ }
128
+ return $this->author;
129
+ }
130
+ }
131
+
132
+ endif;
app/core/puc/Puc/v4p11/Plugin/Package.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Plugin_Package', false) ):
3
+
4
+ class Puc_v4p11_Plugin_Package extends Puc_v4p11_InstalledPackage {
5
+ /**
6
+ * @var Puc_v4p11_Plugin_UpdateChecker
7
+ */
8
+ protected $updateChecker;
9
+
10
+ /**
11
+ * @var string Full path of the main plugin file.
12
+ */
13
+ protected $pluginAbsolutePath = '';
14
+
15
+ /**
16
+ * @var string Plugin basename.
17
+ */
18
+ private $pluginFile;
19
+
20
+ /**
21
+ * @var string|null
22
+ */
23
+ private $cachedInstalledVersion = null;
24
+
25
+ public function __construct($pluginAbsolutePath, $updateChecker) {
26
+ $this->pluginAbsolutePath = $pluginAbsolutePath;
27
+ $this->pluginFile = plugin_basename($this->pluginAbsolutePath);
28
+
29
+ parent::__construct($updateChecker);
30
+
31
+ //Clear the version number cache when something - anything - is upgraded or WP clears the update cache.
32
+ add_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
33
+ add_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
34
+ }
35
+
36
+ public function getInstalledVersion() {
37
+ if ( isset($this->cachedInstalledVersion) ) {
38
+ return $this->cachedInstalledVersion;
39
+ }
40
+
41
+ $pluginHeader = $this->getPluginHeader();
42
+ if ( isset($pluginHeader['Version']) ) {
43
+ $this->cachedInstalledVersion = $pluginHeader['Version'];
44
+ return $pluginHeader['Version'];
45
+ } else {
46
+ //This can happen if the filename points to something that is not a plugin.
47
+ $this->updateChecker->triggerError(
48
+ sprintf(
49
+ "Can't to read the Version header for '%s'. The filename is incorrect or is not a plugin.",
50
+ $this->updateChecker->pluginFile
51
+ ),
52
+ E_USER_WARNING
53
+ );
54
+ return null;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Clear the cached plugin version. This method can be set up as a filter (hook) and will
60
+ * return the filter argument unmodified.
61
+ *
62
+ * @param mixed $filterArgument
63
+ * @return mixed
64
+ */
65
+ public function clearCachedVersion($filterArgument = null) {
66
+ $this->cachedInstalledVersion = null;
67
+ return $filterArgument;
68
+ }
69
+
70
+ public function getAbsoluteDirectoryPath() {
71
+ return dirname($this->pluginAbsolutePath);
72
+ }
73
+
74
+ /**
75
+ * Get the value of a specific plugin or theme header.
76
+ *
77
+ * @param string $headerName
78
+ * @param string $defaultValue
79
+ * @return string Either the value of the header, or $defaultValue if the header doesn't exist or is empty.
80
+ */
81
+ public function getHeaderValue($headerName, $defaultValue = '') {
82
+ $headers = $this->getPluginHeader();
83
+ if ( isset($headers[$headerName]) && ($headers[$headerName] !== '') ) {
84
+ return $headers[$headerName];
85
+ }
86
+ return $defaultValue;
87
+ }
88
+
89
+ protected function getHeaderNames() {
90
+ return array(
91
+ 'Name' => 'Plugin Name',
92
+ 'PluginURI' => 'Plugin URI',
93
+ 'Version' => 'Version',
94
+ 'Description' => 'Description',
95
+ 'Author' => 'Author',
96
+ 'AuthorURI' => 'Author URI',
97
+ 'TextDomain' => 'Text Domain',
98
+ 'DomainPath' => 'Domain Path',
99
+ 'Network' => 'Network',
100
+
101
+ //The newest WordPress version that this plugin requires or has been tested with.
102
+ //We support several different formats for compatibility with other libraries.
103
+ 'Tested WP' => 'Tested WP',
104
+ 'Requires WP' => 'Requires WP',
105
+ 'Tested up to' => 'Tested up to',
106
+ 'Requires at least' => 'Requires at least',
107
+ );
108
+ }
109
+
110
+ /**
111
+ * Get the translated plugin title.
112
+ *
113
+ * @return string
114
+ */
115
+ public function getPluginTitle() {
116
+ $title = '';
117
+ $header = $this->getPluginHeader();
118
+ if ( $header && !empty($header['Name']) && isset($header['TextDomain']) ) {
119
+ $title = translate($header['Name'], $header['TextDomain']);
120
+ }
121
+ return $title;
122
+ }
123
+
124
+ /**
125
+ * Get plugin's metadata from its file header.
126
+ *
127
+ * @return array
128
+ */
129
+ public function getPluginHeader() {
130
+ if ( !is_file($this->pluginAbsolutePath) ) {
131
+ //This can happen if the plugin filename is wrong.
132
+ $this->updateChecker->triggerError(
133
+ sprintf(
134
+ "Can't to read the plugin header for '%s'. The file does not exist.",
135
+ $this->updateChecker->pluginFile
136
+ ),
137
+ E_USER_WARNING
138
+ );
139
+ return array();
140
+ }
141
+
142
+ if ( !function_exists('get_plugin_data') ) {
143
+ /** @noinspection PhpIncludeInspection */
144
+ require_once(ABSPATH . '/wp-admin/includes/plugin.php');
145
+ }
146
+ return get_plugin_data($this->pluginAbsolutePath, false, false);
147
+ }
148
+
149
+ public function removeHooks() {
150
+ remove_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
151
+ remove_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
152
+ }
153
+
154
+ /**
155
+ * Check if the plugin file is inside the mu-plugins directory.
156
+ *
157
+ * @return bool
158
+ */
159
+ public function isMuPlugin() {
160
+ static $cachedResult = null;
161
+
162
+ if ( $cachedResult === null ) {
163
+ if ( !defined('WPMU_PLUGIN_DIR') || !is_string(WPMU_PLUGIN_DIR) ) {
164
+ $cachedResult = false;
165
+ return $cachedResult;
166
+ }
167
+
168
+ //Convert both paths to the canonical form before comparison.
169
+ $muPluginDir = realpath(WPMU_PLUGIN_DIR);
170
+ $pluginPath = realpath($this->pluginAbsolutePath);
171
+ //If realpath() fails, just normalize the syntax instead.
172
+ if (($muPluginDir === false) || ($pluginPath === false)) {
173
+ $muPluginDir = Puc_v4p11_Factory::normalizePath(WPMU_PLUGIN_DIR);
174
+ $pluginPath = Puc_v4p11_Factory::normalizePath($this->pluginAbsolutePath);
175
+ }
176
+
177
+ $cachedResult = (strpos($pluginPath, $muPluginDir) === 0);
178
+ }
179
+
180
+ return $cachedResult;
181
+ }
182
+ }
183
+
184
+ endif;
app/core/puc/Puc/v4p11/Plugin/Ui.php ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Plugin_Ui', false) ):
3
+ /**
4
+ * Additional UI elements for plugins.
5
+ */
6
+ class Puc_v4p11_Plugin_Ui {
7
+ private $updateChecker;
8
+ private $manualCheckErrorTransient = '';
9
+
10
+ /**
11
+ * @param Puc_v4p11_Plugin_UpdateChecker $updateChecker
12
+ */
13
+ public function __construct($updateChecker) {
14
+ $this->updateChecker = $updateChecker;
15
+ $this->manualCheckErrorTransient = $this->updateChecker->getUniqueName('manual_check_errors');
16
+
17
+ add_action('admin_init', array($this, 'onAdminInit'));
18
+ }
19
+
20
+ public function onAdminInit() {
21
+ if ( $this->updateChecker->userCanInstallUpdates() ) {
22
+ $this->handleManualCheck();
23
+
24
+ add_filter('plugin_row_meta', array($this, 'addViewDetailsLink'), 10, 3);
25
+ add_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10, 2);
26
+ add_action('all_admin_notices', array($this, 'displayManualCheckResult'));
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Add a "View Details" link to the plugin row in the "Plugins" page. By default,
32
+ * the new link will appear before the "Visit plugin site" link (if present).
33
+ *
34
+ * You can change the link text by using the "puc_view_details_link-$slug" filter.
35
+ * Returning an empty string from the filter will disable the link.
36
+ *
37
+ * You can change the position of the link using the
38
+ * "puc_view_details_link_position-$slug" filter.
39
+ * Returning 'before' or 'after' will place the link immediately before/after
40
+ * the "Visit plugin site" link.
41
+ * Returning 'append' places the link after any existing links at the time of the hook.
42
+ * Returning 'replace' replaces the "Visit plugin site" link.
43
+ * Returning anything else disables the link when there is a "Visit plugin site" link.
44
+ *
45
+ * If there is no "Visit plugin site" link 'append' is always used!
46
+ *
47
+ * @param array $pluginMeta Array of meta links.
48
+ * @param string $pluginFile
49
+ * @param array $pluginData Array of plugin header data.
50
+ * @return array
51
+ */
52
+ public function addViewDetailsLink($pluginMeta, $pluginFile, $pluginData = array()) {
53
+ if ( $this->isMyPluginFile($pluginFile) && !isset($pluginData['slug']) ) {
54
+ $linkText = apply_filters($this->updateChecker->getUniqueName('view_details_link'), __('View details'));
55
+ if ( !empty($linkText) ) {
56
+ $viewDetailsLinkPosition = 'append';
57
+
58
+ //Find the "Visit plugin site" link (if present).
59
+ $visitPluginSiteLinkIndex = count($pluginMeta) - 1;
60
+ if ( $pluginData['PluginURI'] ) {
61
+ $escapedPluginUri = esc_url($pluginData['PluginURI']);
62
+ foreach ($pluginMeta as $linkIndex => $existingLink) {
63
+ if ( strpos($existingLink, $escapedPluginUri) !== false ) {
64
+ $visitPluginSiteLinkIndex = $linkIndex;
65
+ $viewDetailsLinkPosition = apply_filters(
66
+ $this->updateChecker->getUniqueName('view_details_link_position'),
67
+ 'before'
68
+ );
69
+ break;
70
+ }
71
+ }
72
+ }
73
+
74
+ $viewDetailsLink = sprintf('<a href="%s" class="thickbox open-plugin-details-modal" aria-label="%s" data-title="%s">%s</a>',
75
+ esc_url(network_admin_url('plugin-install.php?tab=plugin-information&plugin=' . urlencode($this->updateChecker->slug) .
76
+ '&TB_iframe=true&width=600&height=550')),
77
+ esc_attr(sprintf(__('More information about %s'), $pluginData['Name'])),
78
+ esc_attr($pluginData['Name']),
79
+ $linkText
80
+ );
81
+ switch ($viewDetailsLinkPosition) {
82
+ case 'before':
83
+ array_splice($pluginMeta, $visitPluginSiteLinkIndex, 0, $viewDetailsLink);
84
+ break;
85
+ case 'after':
86
+ array_splice($pluginMeta, $visitPluginSiteLinkIndex + 1, 0, $viewDetailsLink);
87
+ break;
88
+ case 'replace':
89
+ $pluginMeta[$visitPluginSiteLinkIndex] = $viewDetailsLink;
90
+ break;
91
+ case 'append':
92
+ default:
93
+ $pluginMeta[] = $viewDetailsLink;
94
+ break;
95
+ }
96
+ }
97
+ }
98
+ return $pluginMeta;
99
+ }
100
+
101
+ /**
102
+ * Add a "Check for updates" link to the plugin row in the "Plugins" page. By default,
103
+ * the new link will appear after the "Visit plugin site" link if present, otherwise
104
+ * after the "View plugin details" link.
105
+ *
106
+ * You can change the link text by using the "puc_manual_check_link-$slug" filter.
107
+ * Returning an empty string from the filter will disable the link.
108
+ *
109
+ * @param array $pluginMeta Array of meta links.
110
+ * @param string $pluginFile
111
+ * @return array
112
+ */
113
+ public function addCheckForUpdatesLink($pluginMeta, $pluginFile) {
114
+ if ( $this->isMyPluginFile($pluginFile) ) {
115
+ $linkUrl = wp_nonce_url(
116
+ add_query_arg(
117
+ array(
118
+ 'puc_check_for_updates' => 1,
119
+ 'puc_slug' => $this->updateChecker->slug,
120
+ ),
121
+ self_admin_url('plugins.php')
122
+ ),
123
+ 'puc_check_for_updates'
124
+ );
125
+
126
+ $linkText = apply_filters(
127
+ $this->updateChecker->getUniqueName('manual_check_link'),
128
+ __('Check for updates', 'plugin-update-checker')
129
+ );
130
+ if ( !empty($linkText) ) {
131
+ /** @noinspection HtmlUnknownTarget */
132
+ $pluginMeta[] = sprintf('<a href="%s">%s</a>', esc_attr($linkUrl), $linkText);
133
+ }
134
+ }
135
+ return $pluginMeta;
136
+ }
137
+
138
+ protected function isMyPluginFile($pluginFile) {
139
+ return ($pluginFile == $this->updateChecker->pluginFile)
140
+ || (!empty($this->updateChecker->muPluginFile) && ($pluginFile == $this->updateChecker->muPluginFile));
141
+ }
142
+
143
+ /**
144
+ * Check for updates when the user clicks the "Check for updates" link.
145
+ *
146
+ * @see self::addCheckForUpdatesLink()
147
+ *
148
+ * @return void
149
+ */
150
+ public function handleManualCheck() {
151
+ $shouldCheck =
152
+ isset($_GET['puc_check_for_updates'], $_GET['puc_slug'])
153
+ && $_GET['puc_slug'] == $this->updateChecker->slug
154
+ && check_admin_referer('puc_check_for_updates');
155
+
156
+ if ( $shouldCheck ) {
157
+ $update = $this->updateChecker->checkForUpdates();
158
+ $status = ($update === null) ? 'no_update' : 'update_available';
159
+ $lastRequestApiErrors = $this->updateChecker->getLastRequestApiErrors();
160
+
161
+ if ( ($update === null) && !empty($lastRequestApiErrors) ) {
162
+ //Some errors are not critical. For example, if PUC tries to retrieve the readme.txt
163
+ //file from GitHub and gets a 404, that's an API error, but it doesn't prevent updates
164
+ //from working. Maybe the plugin simply doesn't have a readme.
165
+ //Let's only show important errors.
166
+ $foundCriticalErrors = false;
167
+ $questionableErrorCodes = array(
168
+ 'puc-github-http-error',
169
+ 'puc-gitlab-http-error',
170
+ 'puc-bitbucket-http-error',
171
+ );
172
+
173
+ foreach ($lastRequestApiErrors as $item) {
174
+ $wpError = $item['error'];
175
+ /** @var WP_Error $wpError */
176
+ if ( !in_array($wpError->get_error_code(), $questionableErrorCodes) ) {
177
+ $foundCriticalErrors = true;
178
+ break;
179
+ }
180
+ }
181
+
182
+ if ( $foundCriticalErrors ) {
183
+ $status = 'error';
184
+ set_site_transient($this->manualCheckErrorTransient, $lastRequestApiErrors, 60);
185
+ }
186
+ }
187
+
188
+ wp_redirect(add_query_arg(
189
+ array(
190
+ 'puc_update_check_result' => $status,
191
+ 'puc_slug' => $this->updateChecker->slug,
192
+ ),
193
+ self_admin_url('plugins.php')
194
+ ));
195
+ exit;
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Display the results of a manual update check.
201
+ *
202
+ * @see self::handleManualCheck()
203
+ *
204
+ * You can change the result message by using the "puc_manual_check_message-$slug" filter.
205
+ */
206
+ public function displayManualCheckResult() {
207
+ if ( isset($_GET['puc_update_check_result'], $_GET['puc_slug']) && ($_GET['puc_slug'] == $this->updateChecker->slug) ) {
208
+ $status = strval($_GET['puc_update_check_result']);
209
+ $title = $this->updateChecker->getInstalledPackage()->getPluginTitle();
210
+ $noticeClass = 'updated notice-success';
211
+ $details = '';
212
+
213
+ if ( $status == 'no_update' ) {
214
+ $message = sprintf(_x('The %s plugin is up to date.', 'the plugin title', 'plugin-update-checker'), $title);
215
+ } else if ( $status == 'update_available' ) {
216
+ $message = sprintf(_x('A new version of the %s plugin is available.', 'the plugin title', 'plugin-update-checker'), $title);
217
+ } else if ( $status === 'error' ) {
218
+ $message = sprintf(_x('Could not determine if updates are available for %s.', 'the plugin title', 'plugin-update-checker'), $title);
219
+ $noticeClass = 'error notice-error';
220
+
221
+ $details = $this->formatManualCheckErrors(get_site_transient($this->manualCheckErrorTransient));
222
+ delete_site_transient($this->manualCheckErrorTransient);
223
+ } else {
224
+ $message = sprintf(__('Unknown update checker status "%s"', 'plugin-update-checker'), htmlentities($status));
225
+ $noticeClass = 'error notice-error';
226
+ }
227
+ printf(
228
+ '<div class="notice %s is-dismissible"><p>%s</p>%s</div>',
229
+ $noticeClass,
230
+ apply_filters($this->updateChecker->getUniqueName('manual_check_message'), $message, $status),
231
+ $details
232
+ );
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Format the list of errors that were thrown during an update check.
238
+ *
239
+ * @param array $errors
240
+ * @return string
241
+ */
242
+ protected function formatManualCheckErrors($errors) {
243
+ if ( empty($errors) ) {
244
+ return '';
245
+ }
246
+ $output = '';
247
+
248
+ $showAsList = count($errors) > 1;
249
+ if ( $showAsList ) {
250
+ $output .= '<ol>';
251
+ $formatString = '<li>%1$s <code>%2$s</code></li>';
252
+ } else {
253
+ $formatString = '<p>%1$s <code>%2$s</code></p>';
254
+ }
255
+ foreach ($errors as $item) {
256
+ $wpError = $item['error'];
257
+ /** @var WP_Error $wpError */
258
+ $output .= sprintf(
259
+ $formatString,
260
+ $wpError->get_error_message(),
261
+ $wpError->get_error_code()
262
+ );
263
+ }
264
+ if ( $showAsList ) {
265
+ $output .= '</ol>';
266
+ }
267
+
268
+ return $output;
269
+ }
270
+
271
+ public function removeHooks() {
272
+ remove_action('admin_init', array($this, 'onAdminInit'));
273
+ remove_filter('plugin_row_meta', array($this, 'addViewDetailsLink'), 10);
274
+ remove_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10);
275
+ remove_action('all_admin_notices', array($this, 'displayManualCheckResult'));
276
+ }
277
+ }
278
+ endif;
app/core/puc/Puc/v4p11/Plugin/Update.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Plugin_Update', false) ):
3
+
4
+ /**
5
+ * A simple container class for holding information about an available update.
6
+ *
7
+ * @author Janis Elsts
8
+ * @copyright 2016
9
+ * @access public
10
+ */
11
+ class Puc_v4p11_Plugin_Update extends Puc_v4p11_Update {
12
+ public $id = 0;
13
+ public $homepage;
14
+ public $upgrade_notice;
15
+ public $tested;
16
+ public $requires_php = false;
17
+ public $icons = array();
18
+ public $filename; //Plugin filename relative to the plugins directory.
19
+
20
+ protected static $extraFields = array(
21
+ 'id', 'homepage', 'tested', 'requires_php', 'upgrade_notice', 'icons', 'filename',
22
+ );
23
+
24
+ /**
25
+ * Create a new instance of PluginUpdate from its JSON-encoded representation.
26
+ *
27
+ * @param string $json
28
+ * @return Puc_v4p11_Plugin_Update|null
29
+ */
30
+ public static function fromJson($json){
31
+ //Since update-related information is simply a subset of the full plugin info,
32
+ //we can parse the update JSON as if it was a plugin info string, then copy over
33
+ //the parts that we care about.
34
+ $pluginInfo = Puc_v4p11_Plugin_Info::fromJson($json);
35
+ if ( $pluginInfo !== null ) {
36
+ return self::fromPluginInfo($pluginInfo);
37
+ } else {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Create a new instance of PluginUpdate based on an instance of PluginInfo.
44
+ * Basically, this just copies a subset of fields from one object to another.
45
+ *
46
+ * @param Puc_v4p11_Plugin_Info $info
47
+ * @return Puc_v4p11_Plugin_Update
48
+ */
49
+ public static function fromPluginInfo($info){
50
+ return self::fromObject($info);
51
+ }
52
+
53
+ /**
54
+ * Create a new instance by copying the necessary fields from another object.
55
+ *
56
+ * @param StdClass|Puc_v4p11_Plugin_Info|Puc_v4p11_Plugin_Update $object The source object.
57
+ * @return Puc_v4p11_Plugin_Update The new copy.
58
+ */
59
+ public static function fromObject($object) {
60
+ $update = new self();
61
+ $update->copyFields($object, $update);
62
+ return $update;
63
+ }
64
+
65
+ /**
66
+ * @return string[]
67
+ */
68
+ protected function getFieldNames() {
69
+ return array_merge(parent::getFieldNames(), self::$extraFields);
70
+ }
71
+
72
+ /**
73
+ * Transform the update into the format used by WordPress native plugin API.
74
+ *
75
+ * @return object
76
+ */
77
+ public function toWpFormat() {
78
+ $update = parent::toWpFormat();
79
+
80
+ $update->id = $this->id;
81
+ $update->url = $this->homepage;
82
+ $update->tested = $this->tested;
83
+ $update->requires_php = $this->requires_php;
84
+ $update->plugin = $this->filename;
85
+
86
+ if ( !empty($this->upgrade_notice) ) {
87
+ $update->upgrade_notice = $this->upgrade_notice;
88
+ }
89
+
90
+ if ( !empty($this->icons) && is_array($this->icons) ) {
91
+ //This should be an array with up to 4 keys: 'svg', '1x', '2x' and 'default'.
92
+ //Docs: https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-icons
93
+ $icons = array_intersect_key(
94
+ $this->icons,
95
+ array('svg' => true, '1x' => true, '2x' => true, 'default' => true)
96
+ );
97
+ if ( !empty($icons) ) {
98
+ $update->icons = $icons;
99
+
100
+ //It appears that the 'default' icon isn't used anywhere in WordPress 4.9,
101
+ //but lets set it just in case a future release needs it.
102
+ if ( !isset($update->icons['default']) ) {
103
+ $update->icons['default'] = current($update->icons);
104
+ }
105
+ }
106
+ }
107
+
108
+ return $update;
109
+ }
110
+ }
111
+
112
+ endif;
app/core/puc/Puc/v4p11/Plugin/UpdateChecker.php ADDED
@@ -0,0 +1,414 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Plugin_UpdateChecker', false) ):
3
+
4
+ /**
5
+ * A custom plugin update checker.
6
+ *
7
+ * @author Janis Elsts
8
+ * @copyright 2018
9
+ * @access public
10
+ */
11
+ class Puc_v4p11_Plugin_UpdateChecker extends Puc_v4p11_UpdateChecker {
12
+ protected $updateTransient = 'update_plugins';
13
+ protected $translationType = 'plugin';
14
+
15
+ public $pluginAbsolutePath = ''; //Full path of the main plugin file.
16
+ public $pluginFile = ''; //Plugin filename relative to the plugins directory. Many WP APIs use this to identify plugins.
17
+ public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
18
+
19
+ /**
20
+ * @var Puc_v4p11_Plugin_Package
21
+ */
22
+ protected $package;
23
+
24
+ private $extraUi = null;
25
+
26
+ /**
27
+ * Class constructor.
28
+ *
29
+ * @param string $metadataUrl The URL of the plugin's metadata file.
30
+ * @param string $pluginFile Fully qualified path to the main plugin file.
31
+ * @param string $slug The plugin's 'slug'. If not specified, the filename part of $pluginFile sans '.php' will be used as the slug.
32
+ * @param integer $checkPeriod How often to check for updates (in hours). Defaults to checking every 12 hours. Set to 0 to disable automatic update checks.
33
+ * @param string $optionName Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'.
34
+ * @param string $muPluginFile Optional. The plugin filename relative to the mu-plugins directory.
35
+ */
36
+ public function __construct($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = ''){
37
+ $this->pluginAbsolutePath = $pluginFile;
38
+ $this->pluginFile = plugin_basename($this->pluginAbsolutePath);
39
+ $this->muPluginFile = $muPluginFile;
40
+
41
+ //If no slug is specified, use the name of the main plugin file as the slug.
42
+ //For example, 'my-cool-plugin/cool-plugin.php' becomes 'cool-plugin'.
43
+ if ( empty($slug) ){
44
+ $slug = basename($this->pluginFile, '.php');
45
+ }
46
+
47
+ //Plugin slugs must be unique.
48
+ $slugCheckFilter = 'puc_is_slug_in_use-' . $slug;
49
+ $slugUsedBy = apply_filters($slugCheckFilter, false);
50
+ if ( $slugUsedBy ) {
51
+ $this->triggerError(sprintf(
52
+ 'Plugin slug "%s" is already in use by %s. Slugs must be unique.',
53
+ htmlentities($slug),
54
+ htmlentities($slugUsedBy)
55
+ ), E_USER_ERROR);
56
+ }
57
+ add_filter($slugCheckFilter, array($this, 'getAbsolutePath'));
58
+
59
+ parent::__construct($metadataUrl, dirname($this->pluginFile), $slug, $checkPeriod, $optionName);
60
+
61
+ //Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume
62
+ //it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir).
63
+ if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) {
64
+ $this->muPluginFile = $this->pluginFile;
65
+ }
66
+
67
+ //To prevent a crash during plugin uninstallation, remove updater hooks when the user removes the plugin.
68
+ //Details: https://github.com/YahnisElsts/plugin-update-checker/issues/138#issuecomment-335590964
69
+ add_action('uninstall_' . $this->pluginFile, array($this, 'removeHooks'));
70
+
71
+ $this->extraUi = new Puc_v4p11_Plugin_Ui($this);
72
+ }
73
+
74
+ /**
75
+ * Create an instance of the scheduler.
76
+ *
77
+ * @param int $checkPeriod
78
+ * @return Puc_v4p11_Scheduler
79
+ */
80
+ protected function createScheduler($checkPeriod) {
81
+ $scheduler = new Puc_v4p11_Scheduler($this, $checkPeriod, array('load-plugins.php'));
82
+ register_deactivation_hook($this->pluginFile, array($scheduler, 'removeUpdaterCron'));
83
+ return $scheduler;
84
+ }
85
+
86
+ /**
87
+ * Install the hooks required to run periodic update checks and inject update info
88
+ * into WP data structures.
89
+ *
90
+ * @return void
91
+ */
92
+ protected function installHooks(){
93
+ //Override requests for plugin information
94
+ add_filter('plugins_api', array($this, 'injectInfo'), 20, 3);
95
+
96
+ parent::installHooks();
97
+ }
98
+
99
+ /**
100
+ * Remove update checker hooks.
101
+ *
102
+ * The intent is to prevent a fatal error that can happen if the plugin has an uninstall
103
+ * hook. During uninstallation, WP includes the main plugin file (which creates a PUC instance),
104
+ * the uninstall hook runs, WP deletes the plugin files and then updates some transients.
105
+ * If PUC hooks are still around at this time, they could throw an error while trying to
106
+ * autoload classes from files that no longer exist.
107
+ *
108
+ * The "site_transient_{$transient}" filter is the main problem here, but let's also remove
109
+ * most other PUC hooks to be safe.
110
+ *
111
+ * @internal
112
+ */
113
+ public function removeHooks() {
114
+ parent::removeHooks();
115
+ $this->extraUi->removeHooks();
116
+ $this->package->removeHooks();
117
+
118
+ remove_filter('plugins_api', array($this, 'injectInfo'), 20);
119
+ }
120
+
121
+ /**
122
+ * Retrieve plugin info from the configured API endpoint.
123
+ *
124
+ * @uses wp_remote_get()
125
+ *
126
+ * @param array $queryArgs Additional query arguments to append to the request. Optional.
127
+ * @return Puc_v4p11_Plugin_Info
128
+ */
129
+ public function requestInfo($queryArgs = array()) {
130
+ list($pluginInfo, $result) = $this->requestMetadata('Puc_v4p11_Plugin_Info', 'request_info', $queryArgs);
131
+
132
+ if ( $pluginInfo !== null ) {
133
+ /** @var Puc_v4p11_Plugin_Info $pluginInfo */
134
+ $pluginInfo->filename = $this->pluginFile;
135
+ $pluginInfo->slug = $this->slug;
136
+ }
137
+
138
+ $pluginInfo = apply_filters($this->getUniqueName('request_info_result'), $pluginInfo, $result);
139
+ return $pluginInfo;
140
+ }
141
+
142
+ /**
143
+ * Retrieve the latest update (if any) from the configured API endpoint.
144
+ *
145
+ * @uses PluginUpdateChecker::requestInfo()
146
+ *
147
+ * @return Puc_v4p11_Update|null An instance of Plugin_Update, or NULL when no updates are available.
148
+ */
149
+ public function requestUpdate() {
150
+ //For the sake of simplicity, this function just calls requestInfo()
151
+ //and transforms the result accordingly.
152
+ $pluginInfo = $this->requestInfo(array('checking_for_updates' => '1'));
153
+ if ( $pluginInfo === null ){
154
+ return null;
155
+ }
156
+ $update = Puc_v4p11_Plugin_Update::fromPluginInfo($pluginInfo);
157
+
158
+ $update = $this->filterUpdateResult($update);
159
+
160
+ return $update;
161
+ }
162
+
163
+ /**
164
+ * Intercept plugins_api() calls that request information about our plugin and
165
+ * use the configured API endpoint to satisfy them.
166
+ *
167
+ * @see plugins_api()
168
+ *
169
+ * @param mixed $result
170
+ * @param string $action
171
+ * @param array|object $args
172
+ * @return mixed
173
+ */
174
+ public function injectInfo($result, $action = null, $args = null){
175
+ $relevant = ($action == 'plugin_information') && isset($args->slug) && (
176
+ ($args->slug == $this->slug) || ($args->slug == dirname($this->pluginFile))
177
+ );
178
+ if ( !$relevant ) {
179
+ return $result;
180
+ }
181
+
182
+ $pluginInfo = $this->requestInfo();
183
+ $this->fixSupportedWordpressVersion($pluginInfo);
184
+
185
+ $pluginInfo = apply_filters($this->getUniqueName('pre_inject_info'), $pluginInfo);
186
+ if ( $pluginInfo ) {
187
+ return $pluginInfo->toWpFormat();
188
+ }
189
+
190
+ return $result;
191
+ }
192
+
193
+ protected function shouldShowUpdates() {
194
+ //No update notifications for mu-plugins unless explicitly enabled. The MU plugin file
195
+ //is usually different from the main plugin file so the update wouldn't show up properly anyway.
196
+ return !$this->isUnknownMuPlugin();
197
+ }
198
+
199
+ /**
200
+ * @param stdClass|null $updates
201
+ * @param stdClass $updateToAdd
202
+ * @return stdClass
203
+ */
204
+ protected function addUpdateToList($updates, $updateToAdd) {
205
+ if ( $this->package->isMuPlugin() ) {
206
+ //WP does not support automatic update installation for mu-plugins, but we can
207
+ //still display a notice.
208
+ $updateToAdd->package = null;
209
+ }
210
+ return parent::addUpdateToList($updates, $updateToAdd);
211
+ }
212
+
213
+ /**
214
+ * @param stdClass|null $updates
215
+ * @return stdClass|null
216
+ */
217
+ protected function removeUpdateFromList($updates) {
218
+ $updates = parent::removeUpdateFromList($updates);
219
+ if ( !empty($this->muPluginFile) && isset($updates, $updates->response) ) {
220
+ unset($updates->response[$this->muPluginFile]);
221
+ }
222
+ return $updates;
223
+ }
224
+
225
+ /**
226
+ * For plugins, the update array is indexed by the plugin filename relative to the "plugins"
227
+ * directory. Example: "plugin-name/plugin.php".
228
+ *
229
+ * @return string
230
+ */
231
+ protected function getUpdateListKey() {
232
+ if ( $this->package->isMuPlugin() ) {
233
+ return $this->muPluginFile;
234
+ }
235
+ return $this->pluginFile;
236
+ }
237
+
238
+ protected function getNoUpdateItemFields() {
239
+ return array_merge(
240
+ parent::getNoUpdateItemFields(),
241
+ array(
242
+ 'id' => $this->pluginFile,
243
+ 'slug' => $this->slug,
244
+ 'plugin' => $this->pluginFile,
245
+ 'icons' => array(),
246
+ 'banners' => array(),
247
+ 'banners_rtl' => array(),
248
+ 'tested' => '',
249
+ 'compatibility' => new stdClass(),
250
+ )
251
+ );
252
+ }
253
+
254
+ /**
255
+ * Alias for isBeingUpgraded().
256
+ *
257
+ * @deprecated
258
+ * @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
259
+ * @return bool
260
+ */
261
+ public function isPluginBeingUpgraded($upgrader = null) {
262
+ return $this->isBeingUpgraded($upgrader);
263
+ }
264
+
265
+ /**
266
+ * Is there an update being installed for this plugin, right now?
267
+ *
268
+ * @param WP_Upgrader|null $upgrader
269
+ * @return bool
270
+ */
271
+ public function isBeingUpgraded($upgrader = null) {
272
+ return $this->upgraderStatus->isPluginBeingUpgraded($this->pluginFile, $upgrader);
273
+ }
274
+
275
+ /**
276
+ * Get the details of the currently available update, if any.
277
+ *
278
+ * If no updates are available, or if the last known update version is below or equal
279
+ * to the currently installed version, this method will return NULL.
280
+ *
281
+ * Uses cached update data. To retrieve update information straight from
282
+ * the metadata URL, call requestUpdate() instead.
283
+ *
284
+ * @return Puc_v4p11_Plugin_Update|null
285
+ */
286
+ public function getUpdate() {
287
+ $update = parent::getUpdate();
288
+ if ( isset($update) ) {
289
+ /** @var Puc_v4p11_Plugin_Update $update */
290
+ $update->filename = $this->pluginFile;
291
+ }
292
+ return $update;
293
+ }
294
+
295
+ /**
296
+ * Get the translated plugin title.
297
+ *
298
+ * @deprecated
299
+ * @return string
300
+ */
301
+ public function getPluginTitle() {
302
+ return $this->package->getPluginTitle();
303
+ }
304
+
305
+ /**
306
+ * Check if the current user has the required permissions to install updates.
307
+ *
308
+ * @return bool
309
+ */
310
+ public function userCanInstallUpdates() {
311
+ return current_user_can('update_plugins');
312
+ }
313
+
314
+ /**
315
+ * Check if the plugin file is inside the mu-plugins directory.
316
+ *
317
+ * @deprecated
318
+ * @return bool
319
+ */
320
+ protected function isMuPlugin() {
321
+ return $this->package->isMuPlugin();
322
+ }
323
+
324
+ /**
325
+ * MU plugins are partially supported, but only when we know which file in mu-plugins
326
+ * corresponds to this plugin.
327
+ *
328
+ * @return bool
329
+ */
330
+ protected function isUnknownMuPlugin() {
331
+ return empty($this->muPluginFile) && $this->package->isMuPlugin();
332
+ }
333
+
334
+ /**
335
+ * Get absolute path to the main plugin file.
336
+ *
337
+ * @return string
338
+ */
339
+ public function getAbsolutePath() {
340
+ return $this->pluginAbsolutePath;
341
+ }
342
+
343
+ /**
344
+ * Register a callback for filtering query arguments.
345
+ *
346
+ * The callback function should take one argument - an associative array of query arguments.
347
+ * It should return a modified array of query arguments.
348
+ *
349
+ * @uses add_filter() This method is a convenience wrapper for add_filter().
350
+ *
351
+ * @param callable $callback
352
+ * @return void
353
+ */
354
+ public function addQueryArgFilter($callback){
355
+ $this->addFilter('request_info_query_args', $callback);
356
+ }
357
+
358
+ /**
359
+ * Register a callback for filtering arguments passed to wp_remote_get().
360
+ *
361
+ * The callback function should take one argument - an associative array of arguments -
362
+ * and return a modified array or arguments. See the WP documentation on wp_remote_get()
363
+ * for details on what arguments are available and how they work.
364
+ *
365
+ * @uses add_filter() This method is a convenience wrapper for add_filter().
366
+ *
367
+ * @param callable $callback
368
+ * @return void
369
+ */
370
+ public function addHttpRequestArgFilter($callback) {
371
+ $this->addFilter('request_info_options', $callback);
372
+ }
373
+
374
+ /**
375
+ * Register a callback for filtering the plugin info retrieved from the external API.
376
+ *
377
+ * The callback function should take two arguments. If the plugin info was retrieved
378
+ * successfully, the first argument passed will be an instance of PluginInfo. Otherwise,
379
+ * it will be NULL. The second argument will be the corresponding return value of
380
+ * wp_remote_get (see WP docs for details).
381
+ *
382
+ * The callback function should return a new or modified instance of PluginInfo or NULL.
383
+ *
384
+ * @uses add_filter() This method is a convenience wrapper for add_filter().
385
+ *
386
+ * @param callable $callback
387
+ * @return void
388
+ */
389
+ public function addResultFilter($callback) {
390
+ $this->addFilter('request_info_result', $callback, 10, 2);
391
+ }
392
+
393
+ protected function createDebugBarExtension() {
394
+ return new Puc_v4p11_DebugBar_PluginExtension($this);
395
+ }
396
+
397
+ /**
398
+ * Create a package instance that represents this plugin or theme.
399
+ *
400
+ * @return Puc_v4p11_InstalledPackage
401
+ */
402
+ protected function createInstalledPackage() {
403
+ return new Puc_v4p11_Plugin_Package($this->pluginAbsolutePath, $this);
404
+ }
405
+
406
+ /**
407
+ * @return Puc_v4p11_Plugin_Package
408
+ */
409
+ public function getInstalledPackage() {
410
+ return $this->package;
411
+ }
412
+ }
413
+
414
+ endif;
app/core/puc/Puc/v4p11/Scheduler.php ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Scheduler', false) ):
3
+
4
+ /**
5
+ * The scheduler decides when and how often to check for updates.
6
+ * It calls @see Puc_v4p11_UpdateChecker::checkForUpdates() to perform the actual checks.
7
+ */
8
+ class Puc_v4p11_Scheduler {
9
+ public $checkPeriod = 12; //How often to check for updates (in hours).
10
+ public $throttleRedundantChecks = false; //Check less often if we already know that an update is available.
11
+ public $throttledCheckPeriod = 72;
12
+
13
+ protected $hourlyCheckHooks = array('load-update.php');
14
+
15
+ /**
16
+ * @var Puc_v4p11_UpdateChecker
17
+ */
18
+ protected $updateChecker;
19
+
20
+ private $cronHook = null;
21
+
22
+ /**
23
+ * Scheduler constructor.
24
+ *
25
+ * @param Puc_v4p11_UpdateChecker $updateChecker
26
+ * @param int $checkPeriod How often to check for updates (in hours).
27
+ * @param array $hourlyHooks
28
+ */
29
+ public function __construct($updateChecker, $checkPeriod, $hourlyHooks = array('load-plugins.php')) {
30
+ $this->updateChecker = $updateChecker;
31
+ $this->checkPeriod = $checkPeriod;
32
+
33
+ //Set up the periodic update checks
34
+ $this->cronHook = $this->updateChecker->getUniqueName('cron_check_updates');
35
+ if ( $this->checkPeriod > 0 ){
36
+
37
+ //Trigger the check via Cron.
38
+ //Try to use one of the default schedules if possible as it's less likely to conflict
39
+ //with other plugins and their custom schedules.
40
+ $defaultSchedules = array(
41
+ 1 => 'hourly',
42
+ 12 => 'twicedaily',
43
+ 24 => 'daily',
44
+ );
45
+ if ( array_key_exists($this->checkPeriod, $defaultSchedules) ) {
46
+ $scheduleName = $defaultSchedules[$this->checkPeriod];
47
+ } else {
48
+ //Use a custom cron schedule.
49
+ $scheduleName = 'every' . $this->checkPeriod . 'hours';
50
+ add_filter('cron_schedules', array($this, '_addCustomSchedule'));
51
+ }
52
+
53
+ if ( !wp_next_scheduled($this->cronHook) && !defined('WP_INSTALLING') ) {
54
+ //Randomly offset the schedule to help prevent update server traffic spikes. Without this
55
+ //most checks may happen during times of day when people are most likely to install new plugins.
56
+ $firstCheckTime = time() - rand(0, max($this->checkPeriod * 3600 - 15 * 60, 1));
57
+ $firstCheckTime = apply_filters(
58
+ $this->updateChecker->getUniqueName('first_check_time'),
59
+ $firstCheckTime
60
+ );
61
+ wp_schedule_event($firstCheckTime, $scheduleName, $this->cronHook);
62
+ }
63
+ add_action($this->cronHook, array($this, 'maybeCheckForUpdates'));
64
+
65
+ //In case Cron is disabled or unreliable, we also manually trigger
66
+ //the periodic checks while the user is browsing the Dashboard.
67
+ add_action( 'admin_init', array($this, 'maybeCheckForUpdates') );
68
+
69
+ //Like WordPress itself, we check more often on certain pages.
70
+ /** @see wp_update_plugins */
71
+ add_action('load-update-core.php', array($this, 'maybeCheckForUpdates'));
72
+ //"load-update.php" and "load-plugins.php" or "load-themes.php".
73
+ $this->hourlyCheckHooks = array_merge($this->hourlyCheckHooks, $hourlyHooks);
74
+ foreach($this->hourlyCheckHooks as $hook) {
75
+ add_action($hook, array($this, 'maybeCheckForUpdates'));
76
+ }
77
+ //This hook fires after a bulk update is complete.
78
+ add_action('upgrader_process_complete', array($this, 'upgraderProcessComplete'), 11, 2);
79
+
80
+ } else {
81
+ //Periodic checks are disabled.
82
+ wp_clear_scheduled_hook($this->cronHook);
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Runs upon the WP action upgrader_process_complete.
88
+ *
89
+ * We look at the parameters to decide whether to call maybeCheckForUpdates() or not.
90
+ * We also check if the update checker has been removed by the update.
91
+ *
92
+ * @param WP_Upgrader $upgrader WP_Upgrader instance
93
+ * @param array $upgradeInfo extra information about the upgrade
94
+ */
95
+ public function upgraderProcessComplete(
96
+ /** @noinspection PhpUnusedParameterInspection */
97
+ $upgrader, $upgradeInfo
98
+ ) {
99
+ //Cancel all further actions if the current version of PUC has been deleted or overwritten
100
+ //by a different version during the upgrade. If we try to do anything more in that situation,
101
+ //we could trigger a fatal error by trying to autoload a deleted class.
102
+ clearstatcache();
103
+ if ( !file_exists(__FILE__) ) {
104
+ $this->removeHooks();
105
+ $this->updateChecker->removeHooks();
106
+ return;
107
+ }
108
+
109
+ //Sanity check and limitation to relevant types.
110
+ if (
111
+ !is_array($upgradeInfo) || !isset($upgradeInfo['type'], $upgradeInfo['action'])
112
+ || 'update' !== $upgradeInfo['action'] || !in_array($upgradeInfo['type'], array('plugin', 'theme'))
113
+ ) {
114
+ return;
115
+ }
116
+
117
+ //Filter out notifications of upgrades that should have no bearing upon whether or not our
118
+ //current info is up-to-date.
119
+ if ( is_a($this->updateChecker, 'Puc_v4p11_Theme_UpdateChecker') ) {
120
+ if ( 'theme' !== $upgradeInfo['type'] || !isset($upgradeInfo['themes']) ) {
121
+ return;
122
+ }
123
+
124
+ //Letting too many things going through for checks is not a real problem, so we compare widely.
125
+ if ( !in_array(
126
+ strtolower($this->updateChecker->directoryName),
127
+ array_map('strtolower', $upgradeInfo['themes'])
128
+ ) ) {
129
+ return;
130
+ }
131
+ }
132
+
133
+ if ( is_a($this->updateChecker, 'Puc_v4p11_Plugin_UpdateChecker') ) {
134
+ if ( 'plugin' !== $upgradeInfo['type'] || !isset($upgradeInfo['plugins']) ) {
135
+ return;
136
+ }
137
+
138
+ //Themes pass in directory names in the information array, but plugins use the relative plugin path.
139
+ if ( !in_array(
140
+ strtolower($this->updateChecker->directoryName),
141
+ array_map('dirname', array_map('strtolower', $upgradeInfo['plugins']))
142
+ ) ) {
143
+ return;
144
+ }
145
+ }
146
+
147
+ $this->maybeCheckForUpdates();
148
+ }
149
+
150
+ /**
151
+ * Check for updates if the configured check interval has already elapsed.
152
+ * Will use a shorter check interval on certain admin pages like "Dashboard -> Updates" or when doing cron.
153
+ *
154
+ * You can override the default behaviour by using the "puc_check_now-$slug" filter.
155
+ * The filter callback will be passed three parameters:
156
+ * - Current decision. TRUE = check updates now, FALSE = don't check now.
157
+ * - Last check time as a Unix timestamp.
158
+ * - Configured check period in hours.
159
+ * Return TRUE to check for updates immediately, or FALSE to cancel.
160
+ *
161
+ * This method is declared public because it's a hook callback. Calling it directly is not recommended.
162
+ */
163
+ public function maybeCheckForUpdates() {
164
+ if ( empty($this->checkPeriod) ){
165
+ return;
166
+ }
167
+
168
+ $state = $this->updateChecker->getUpdateState();
169
+ $shouldCheck = ($state->timeSinceLastCheck() >= $this->getEffectiveCheckPeriod());
170
+
171
+ //Let plugin authors substitute their own algorithm.
172
+ $shouldCheck = apply_filters(
173
+ $this->updateChecker->getUniqueName('check_now'),
174
+ $shouldCheck,
175
+ $state->getLastCheck(),
176
+ $this->checkPeriod
177
+ );
178
+
179
+ if ( $shouldCheck ) {
180
+ $this->updateChecker->checkForUpdates();
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Calculate the actual check period based on the current status and environment.
186
+ *
187
+ * @return int Check period in seconds.
188
+ */
189
+ protected function getEffectiveCheckPeriod() {
190
+ $currentFilter = current_filter();
191
+ if ( in_array($currentFilter, array('load-update-core.php', 'upgrader_process_complete')) ) {
192
+ //Check more often when the user visits "Dashboard -> Updates" or does a bulk update.
193
+ $period = 60;
194
+ } else if ( in_array($currentFilter, $this->hourlyCheckHooks) ) {
195
+ //Also check more often on /wp-admin/update.php and the "Plugins" or "Themes" page.
196
+ $period = 3600;
197
+ } else if ( $this->throttleRedundantChecks && ($this->updateChecker->getUpdate() !== null) ) {
198
+ //Check less frequently if it's already known that an update is available.
199
+ $period = $this->throttledCheckPeriod * 3600;
200
+ } else if ( defined('DOING_CRON') && constant('DOING_CRON') ) {
201
+ //WordPress cron schedules are not exact, so lets do an update check even
202
+ //if slightly less than $checkPeriod hours have elapsed since the last check.
203
+ $cronFuzziness = 20 * 60;
204
+ $period = $this->checkPeriod * 3600 - $cronFuzziness;
205
+ } else {
206
+ $period = $this->checkPeriod * 3600;
207
+ }
208
+
209
+ return $period;
210
+ }
211
+
212
+ /**
213
+ * Add our custom schedule to the array of Cron schedules used by WP.
214
+ *
215
+ * @param array $schedules
216
+ * @return array
217
+ */
218
+ public function _addCustomSchedule($schedules) {
219
+ if ( $this->checkPeriod && ($this->checkPeriod > 0) ){
220
+ $scheduleName = 'every' . $this->checkPeriod . 'hours';
221
+ $schedules[$scheduleName] = array(
222
+ 'interval' => $this->checkPeriod * 3600,
223
+ 'display' => sprintf('Every %d hours', $this->checkPeriod),
224
+ );
225
+ }
226
+ return $schedules;
227
+ }
228
+
229
+ /**
230
+ * Remove the scheduled cron event that the library uses to check for updates.
231
+ *
232
+ * @return void
233
+ */
234
+ public function removeUpdaterCron() {
235
+ wp_clear_scheduled_hook($this->cronHook);
236
+ }
237
+
238
+ /**
239
+ * Get the name of the update checker's WP-cron hook. Mostly useful for debugging.
240
+ *
241
+ * @return string
242
+ */
243
+ public function getCronHookName() {
244
+ return $this->cronHook;
245
+ }
246
+
247
+ /**
248
+ * Remove most hooks added by the scheduler.
249
+ */
250
+ public function removeHooks() {
251
+ remove_filter('cron_schedules', array($this, '_addCustomSchedule'));
252
+ remove_action('admin_init', array($this, 'maybeCheckForUpdates'));
253
+ remove_action('load-update-core.php', array($this, 'maybeCheckForUpdates'));
254
+
255
+ if ( $this->cronHook !== null ) {
256
+ remove_action($this->cronHook, array($this, 'maybeCheckForUpdates'));
257
+ }
258
+ if ( !empty($this->hourlyCheckHooks) ) {
259
+ foreach ($this->hourlyCheckHooks as $hook) {
260
+ remove_action($hook, array($this, 'maybeCheckForUpdates'));
261
+ }
262
+ }
263
+ }
264
+ }
265
+
266
+ endif;
app/core/puc/Puc/v4p11/StateStore.php ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_StateStore', false) ):
4
+
5
+ class Puc_v4p11_StateStore {
6
+ /**
7
+ * @var int Last update check timestamp.
8
+ */
9
+ protected $lastCheck = 0;
10
+
11
+ /**
12
+ * @var string Version number.
13
+ */
14
+ protected $checkedVersion = '';
15
+
16
+ /**
17
+ * @var Puc_v4p11_Update|null Cached update.
18
+ */
19
+ protected $update = null;
20
+
21
+ /**
22
+ * @var string Site option name.
23
+ */
24
+ private $optionName = '';
25
+
26
+ /**
27
+ * @var bool Whether we've already tried to load the state from the database.
28
+ */
29
+ private $isLoaded = false;
30
+
31
+ public function __construct($optionName) {
32
+ $this->optionName = $optionName;
33
+ }
34
+
35
+ /**
36
+ * Get time elapsed since the last update check.
37
+ *
38
+ * If there are no recorded update checks, this method returns a large arbitrary number
39
+ * (i.e. time since the Unix epoch).
40
+ *
41
+ * @return int Elapsed time in seconds.
42
+ */
43
+ public function timeSinceLastCheck() {
44
+ $this->lazyLoad();
45
+ return time() - $this->lastCheck;
46
+ }
47
+
48
+ /**
49
+ * @return int
50
+ */
51
+ public function getLastCheck() {
52
+ $this->lazyLoad();
53
+ return $this->lastCheck;
54
+ }
55
+
56
+ /**
57
+ * Set the time of the last update check to the current timestamp.
58
+ *
59
+ * @return $this
60
+ */
61
+ public function setLastCheckToNow() {
62
+ $this->lazyLoad();
63
+ $this->lastCheck = time();
64
+ return $this;
65
+ }
66
+
67
+ /**
68
+ * @return null|Puc_v4p11_Update
69
+ */
70
+ public function getUpdate() {
71
+ $this->lazyLoad();
72
+ return $this->update;
73
+ }
74
+
75
+ /**
76
+ * @param Puc_v4p11_Update|null $update
77
+ * @return $this
78
+ */
79
+ public function setUpdate(Puc_v4p11_Update $update = null) {
80
+ $this->lazyLoad();
81
+ $this->update = $update;
82
+ return $this;
83
+ }
84
+
85
+ /**
86
+ * @return string
87
+ */
88
+ public function getCheckedVersion() {
89
+ $this->lazyLoad();
90
+ return $this->checkedVersion;
91
+ }
92
+
93
+ /**
94
+ * @param string $version
95
+ * @return $this
96
+ */
97
+ public function setCheckedVersion($version) {
98
+ $this->lazyLoad();
99
+ $this->checkedVersion = strval($version);
100
+ return $this;
101
+ }
102
+
103
+ /**
104
+ * Get translation updates.
105
+ *
106
+ * @return array
107
+ */
108
+ public function getTranslations() {
109
+ $this->lazyLoad();
110
+ if ( isset($this->update, $this->update->translations) ) {
111
+ return $this->update->translations;
112
+ }
113
+ return array();
114
+ }
115
+
116
+ /**
117
+ * Set translation updates.
118
+ *
119
+ * @param array $translationUpdates
120
+ */
121
+ public function setTranslations($translationUpdates) {
122
+ $this->lazyLoad();
123
+ if ( isset($this->update) ) {
124
+ $this->update->translations = $translationUpdates;
125
+ $this->save();
126
+ }
127
+ }
128
+
129
+ public function save() {
130
+ $state = new stdClass();
131
+
132
+ $state->lastCheck = $this->lastCheck;
133
+ $state->checkedVersion = $this->checkedVersion;
134
+
135
+ if ( isset($this->update)) {
136
+ $state->update = $this->update->toStdClass();
137
+
138
+ $updateClass = get_class($this->update);
139
+ $state->updateClass = $updateClass;
140
+ $prefix = $this->getLibPrefix();
141
+ if ( Puc_v4p11_Utils::startsWith($updateClass, $prefix) ) {
142
+ $state->updateBaseClass = substr($updateClass, strlen($prefix));
143
+ }
144
+ }
145
+
146
+ update_site_option($this->optionName, $state);
147
+ $this->isLoaded = true;
148
+ }
149
+
150
+ /**
151
+ * @return $this
152
+ */
153
+ public function lazyLoad() {
154
+ if ( !$this->isLoaded ) {
155
+ $this->load();
156
+ }
157
+ return $this;
158
+ }
159
+
160
+ protected function load() {
161
+ $this->isLoaded = true;
162
+
163
+ $state = get_site_option($this->optionName, null);
164
+
165
+ if ( !is_object($state) ) {
166
+ $this->lastCheck = 0;
167
+ $this->checkedVersion = '';
168
+ $this->update = null;
169
+ return;
170
+ }
171
+
172
+ $this->lastCheck = intval(Puc_v4p11_Utils::get($state, 'lastCheck', 0));
173
+ $this->checkedVersion = Puc_v4p11_Utils::get($state, 'checkedVersion', '');
174
+ $this->update = null;
175
+
176
+ if ( isset($state->update) ) {
177
+ //This mess is due to the fact that the want the update class from this version
178
+ //of the library, not the version that saved the update.
179
+
180
+ $updateClass = null;
181
+ if ( isset($state->updateBaseClass) ) {
182
+ $updateClass = $this->getLibPrefix() . $state->updateBaseClass;
183
+ } else if ( isset($state->updateClass) && class_exists($state->updateClass) ) {
184
+ $updateClass = $state->updateClass;
185
+ }
186
+
187
+ if ( $updateClass !== null ) {
188
+ $this->update = call_user_func(array($updateClass, 'fromObject'), $state->update);
189
+ }
190
+ }
191
+ }
192
+
193
+ public function delete() {
194
+ delete_site_option($this->optionName);
195
+
196
+ $this->lastCheck = 0;
197
+ $this->checkedVersion = '';
198
+ $this->update = null;
199
+ }
200
+
201
+ private function getLibPrefix() {
202
+ $parts = explode('_', __CLASS__, 3);
203
+ return $parts[0] . '_' . $parts[1] . '_';
204
+ }
205
+ }
206
+
207
+ endif;
app/core/puc/Puc/v4p11/Theme/Package.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Theme_Package', false) ):
3
+
4
+ class Puc_v4p11_Theme_Package extends Puc_v4p11_InstalledPackage {
5
+ /**
6
+ * @var string Theme directory name.
7
+ */
8
+ protected $stylesheet;
9
+
10
+ /**
11
+ * @var WP_Theme Theme object.
12
+ */
13
+ protected $theme;
14
+
15
+ public function __construct($stylesheet, $updateChecker) {
16
+ $this->stylesheet = $stylesheet;
17
+ $this->theme = wp_get_theme($this->stylesheet);
18
+
19
+ parent::__construct($updateChecker);
20
+ }
21
+
22
+ public function getInstalledVersion() {
23
+ return $this->theme->get('Version');
24
+ }
25
+
26
+ public function getAbsoluteDirectoryPath() {
27
+ if ( method_exists($this->theme, 'get_stylesheet_directory') ) {
28
+ return $this->theme->get_stylesheet_directory(); //Available since WP 3.4.
29
+ }
30
+ return get_theme_root($this->stylesheet) . '/' . $this->stylesheet;
31
+ }
32
+
33
+ /**
34
+ * Get the value of a specific plugin or theme header.
35
+ *
36
+ * @param string $headerName
37
+ * @param string $defaultValue
38
+ * @return string Either the value of the header, or $defaultValue if the header doesn't exist or is empty.
39
+ */
40
+ public function getHeaderValue($headerName, $defaultValue = '') {
41
+ $value = $this->theme->get($headerName);
42
+ if ( ($headerName === false) || ($headerName === '') ) {
43
+ return $defaultValue;
44
+ }
45
+ return $value;
46
+ }
47
+
48
+ protected function getHeaderNames() {
49
+ return array(
50
+ 'Name' => 'Theme Name',
51
+ 'ThemeURI' => 'Theme URI',
52
+ 'Description' => 'Description',
53
+ 'Author' => 'Author',
54
+ 'AuthorURI' => 'Author URI',
55
+ 'Version' => 'Version',
56
+ 'Template' => 'Template',
57
+ 'Status' => 'Status',
58
+ 'Tags' => 'Tags',
59
+ 'TextDomain' => 'Text Domain',
60
+ 'DomainPath' => 'Domain Path',
61
+ );
62
+ }
63
+ }
64
+
65
+ endif;
app/core/puc/Puc/v4p11/Theme/Update.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_Theme_Update', false) ):
4
+
5
+ class Puc_v4p11_Theme_Update extends Puc_v4p11_Update {
6
+ public $details_url = '';
7
+
8
+ protected static $extraFields = array('details_url');
9
+
10
+ /**
11
+ * Transform the metadata into the format used by WordPress core.
12
+ * Note the inconsistency: WP stores plugin updates as objects and theme updates as arrays.
13
+ *
14
+ * @return array
15
+ */
16
+ public function toWpFormat() {
17
+ $update = array(
18
+ 'theme' => $this->slug,
19
+ 'new_version' => $this->version,
20
+ 'url' => $this->details_url,
21
+ );
22
+
23
+ if ( !empty($this->download_url) ) {
24
+ $update['package'] = $this->download_url;
25
+ }
26
+
27
+ return $update;
28
+ }
29
+
30
+ /**
31
+ * Create a new instance of Theme_Update from its JSON-encoded representation.
32
+ *
33
+ * @param string $json Valid JSON string representing a theme information object.
34
+ * @return self New instance of ThemeUpdate, or NULL on error.
35
+ */
36
+ public static function fromJson($json) {
37
+ $instance = new self();
38
+ if ( !parent::createFromJson($json, $instance) ) {
39
+ return null;
40
+ }
41
+ return $instance;
42
+ }
43
+
44
+ /**
45
+ * Create a new instance by copying the necessary fields from another object.
46
+ *
47
+ * @param StdClass|Puc_v4p11_Theme_Update $object The source object.
48
+ * @return Puc_v4p11_Theme_Update The new copy.
49
+ */
50
+ public static function fromObject($object) {
51
+ $update = new self();
52
+ $update->copyFields($object, $update);
53
+ return $update;
54
+ }
55
+
56
+ /**
57
+ * Basic validation.
58
+ *
59
+ * @param StdClass $apiResponse
60
+ * @return bool|WP_Error
61
+ */
62
+ protected function validateMetadata($apiResponse) {
63
+ $required = array('version', 'details_url');
64
+ foreach($required as $key) {
65
+ if ( !isset($apiResponse->$key) || empty($apiResponse->$key) ) {
66
+ return new WP_Error(
67
+ 'tuc-invalid-metadata',
68
+ sprintf('The theme metadata is missing the required "%s" key.', $key)
69
+ );
70
+ }
71
+ }
72
+ return true;
73
+ }
74
+
75
+ protected function getFieldNames() {
76
+ return array_merge(parent::getFieldNames(), self::$extraFields);
77
+ }
78
+
79
+ protected function getPrefixedFilter($tag) {
80
+ return parent::getPrefixedFilter($tag) . '_theme';
81
+ }
82
+ }
83
+
84
+ endif;
app/core/puc/Puc/v4p11/Theme/UpdateChecker.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_Theme_UpdateChecker', false) ):
4
+
5
+ class Puc_v4p11_Theme_UpdateChecker extends Puc_v4p11_UpdateChecker {
6
+ protected $filterSuffix = 'theme';
7
+ protected $updateTransient = 'update_themes';
8
+ protected $translationType = 'theme';
9
+
10
+ /**
11
+ * @var string Theme directory name.
12
+ */
13
+ protected $stylesheet;
14
+
15
+ public function __construct($metadataUrl, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') {
16
+ if ( $stylesheet === null ) {
17
+ $stylesheet = get_stylesheet();
18
+ }
19
+ $this->stylesheet = $stylesheet;
20
+
21
+ parent::__construct(
22
+ $metadataUrl,
23
+ $stylesheet,
24
+ $customSlug ? $customSlug : $stylesheet,
25
+ $checkPeriod,
26
+ $optionName
27
+ );
28
+ }
29
+
30
+ /**
31
+ * For themes, the update array is indexed by theme directory name.
32
+ *
33
+ * @return string
34
+ */
35
+ protected function getUpdateListKey() {
36
+ return $this->directoryName;
37
+ }
38
+
39
+ /**
40
+ * Retrieve the latest update (if any) from the configured API endpoint.
41
+ *
42
+ * @return Puc_v4p11_Update|null An instance of Update, or NULL when no updates are available.
43
+ */
44
+ public function requestUpdate() {
45
+ list($themeUpdate, $result) = $this->requestMetadata('Puc_v4p11_Theme_Update', 'request_update');
46
+
47
+ if ( $themeUpdate !== null ) {
48
+ /** @var Puc_v4p11_Theme_Update $themeUpdate */
49
+ $themeUpdate->slug = $this->slug;
50
+ }
51
+
52
+ $themeUpdate = $this->filterUpdateResult($themeUpdate, $result);
53
+ return $themeUpdate;
54
+ }
55
+
56
+ protected function getNoUpdateItemFields() {
57
+ return array_merge(
58
+ parent::getNoUpdateItemFields(),
59
+ array(
60
+ 'theme' => $this->directoryName,
61
+ 'requires' => '',
62
+ )
63
+ );
64
+ }
65
+
66
+ public function userCanInstallUpdates() {
67
+ return current_user_can('update_themes');
68
+ }
69
+
70
+ /**
71
+ * Create an instance of the scheduler.
72
+ *
73
+ * @param int $checkPeriod
74
+ * @return Puc_v4p11_Scheduler
75
+ */
76
+ protected function createScheduler($checkPeriod) {
77
+ return new Puc_v4p11_Scheduler($this, $checkPeriod, array('load-themes.php'));
78
+ }
79
+
80
+ /**
81
+ * Is there an update being installed right now for this theme?
82
+ *
83
+ * @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
84
+ * @return bool
85
+ */
86
+ public function isBeingUpgraded($upgrader = null) {
87
+ return $this->upgraderStatus->isThemeBeingUpgraded($this->stylesheet, $upgrader);
88
+ }
89
+
90
+ protected function createDebugBarExtension() {
91
+ return new Puc_v4p11_DebugBar_Extension($this, 'Puc_v4p11_DebugBar_ThemePanel');
92
+ }
93
+
94
+ /**
95
+ * Register a callback for filtering query arguments.
96
+ *
97
+ * The callback function should take one argument - an associative array of query arguments.
98
+ * It should return a modified array of query arguments.
99
+ *
100
+ * @param callable $callback
101
+ * @return void
102
+ */
103
+ public function addQueryArgFilter($callback){
104
+ $this->addFilter('request_update_query_args', $callback);
105
+ }
106
+
107
+ /**
108
+ * Register a callback for filtering arguments passed to wp_remote_get().
109
+ *
110
+ * The callback function should take one argument - an associative array of arguments -
111
+ * and return a modified array or arguments. See the WP documentation on wp_remote_get()
112
+ * for details on what arguments are available and how they work.
113
+ *
114
+ * @uses add_filter() This method is a convenience wrapper for add_filter().
115
+ *
116
+ * @param callable $callback
117
+ * @return void
118
+ */
119
+ public function addHttpRequestArgFilter($callback) {
120
+ $this->addFilter('request_update_options', $callback);
121
+ }
122
+
123
+ /**
124
+ * Register a callback for filtering theme updates retrieved from the external API.
125
+ *
126
+ * The callback function should take two arguments. If the theme update was retrieved
127
+ * successfully, the first argument passed will be an instance of Theme_Update. Otherwise,
128
+ * it will be NULL. The second argument will be the corresponding return value of
129
+ * wp_remote_get (see WP docs for details).
130
+ *
131
+ * The callback function should return a new or modified instance of Theme_Update or NULL.
132
+ *
133
+ * @uses add_filter() This method is a convenience wrapper for add_filter().
134
+ *
135
+ * @param callable $callback
136
+ * @return void
137
+ */
138
+ public function addResultFilter($callback) {
139
+ $this->addFilter('request_update_result', $callback, 10, 2);
140
+ }
141
+
142
+ /**
143
+ * Create a package instance that represents this plugin or theme.
144
+ *
145
+ * @return Puc_v4p11_InstalledPackage
146
+ */
147
+ protected function createInstalledPackage() {
148
+ return new Puc_v4p11_Theme_Package($this->stylesheet, $this);
149
+ }
150
+ }
151
+
152
+ endif;
app/core/puc/Puc/v4p11/Update.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Update', false) ):
3
+
4
+ /**
5
+ * A simple container class for holding information about an available update.
6
+ *
7
+ * @author Janis Elsts
8
+ * @access public
9
+ */
10
+ abstract class Puc_v4p11_Update extends Puc_v4p11_Metadata {
11
+ public $slug;
12
+ public $version;
13
+ public $download_url;
14
+ public $translations = array();
15
+
16
+ /**
17
+ * @return string[]
18
+ */
19
+ protected function getFieldNames() {
20
+ return array('slug', 'version', 'download_url', 'translations');
21
+ }
22
+
23
+ public function toWpFormat() {
24
+ $update = new stdClass();
25
+
26
+ $update->slug = $this->slug;
27
+ $update->new_version = $this->version;
28
+ $update->package = $this->download_url;
29
+
30
+ return $update;
31
+ }
32
+ }
33
+
34
+ endif;
app/core/puc/Puc/v4p11/UpdateChecker.php ADDED
@@ -0,0 +1,999 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_UpdateChecker', false) ):
4
+
5
+ abstract class Puc_v4p11_UpdateChecker {
6
+ protected $filterSuffix = '';
7
+ protected $updateTransient = '';
8
+ protected $translationType = ''; //"plugin" or "theme".
9
+
10
+ /**
11
+ * Set to TRUE to enable error reporting. Errors are raised using trigger_error()
12
+ * and should be logged to the standard PHP error log.
13
+ * @var bool
14
+ */
15
+ public $debugMode = null;
16
+
17
+ /**
18
+ * @var string Where to store the update info.
19
+ */
20
+ public $optionName = '';
21
+
22
+ /**
23
+ * @var string The URL of the metadata file.
24
+ */
25
+ public $metadataUrl = '';
26
+
27
+ /**
28
+ * @var string Plugin or theme directory name.
29
+ */
30
+ public $directoryName = '';
31
+
32
+ /**
33
+ * @var string The slug that will be used in update checker hooks and remote API requests.
34
+ * Usually matches the directory name unless the plugin/theme directory has been renamed.
35
+ */
36
+ public $slug = '';
37
+
38
+ /**
39
+ * @var Puc_v4p11_InstalledPackage
40
+ */
41
+ protected $package;
42
+
43
+ /**
44
+ * @var Puc_v4p11_Scheduler
45
+ */
46
+ public $scheduler;
47
+
48
+ /**
49
+ * @var Puc_v4p11_UpgraderStatus
50
+ */
51
+ protected $upgraderStatus;
52
+
53
+ /**
54
+ * @var Puc_v4p11_StateStore
55
+ */
56
+ protected $updateState;
57
+
58
+ /**
59
+ * @var array List of API errors triggered during the last checkForUpdates() call.
60
+ */
61
+ protected $lastRequestApiErrors = array();
62
+
63
+ /**
64
+ * @var string|mixed The default is 0 because parse_url() can return NULL or FALSE.
65
+ */
66
+ protected $cachedMetadataHost = 0;
67
+
68
+ /**
69
+ * @var Puc_v4p11_DebugBar_Extension|null
70
+ */
71
+ protected $debugBarExtension = null;
72
+
73
+ public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
74
+ $this->debugMode = (bool)(constant('WP_DEBUG'));
75
+ $this->metadataUrl = $metadataUrl;
76
+ $this->directoryName = $directoryName;
77
+ $this->slug = !empty($slug) ? $slug : $this->directoryName;
78
+
79
+ $this->optionName = $optionName;
80
+ if ( empty($this->optionName) ) {
81
+ //BC: Initially the library only supported plugin updates and didn't use type prefixes
82
+ //in the option name. Lets use the same prefix-less name when possible.
83
+ if ( $this->filterSuffix === '' ) {
84
+ $this->optionName = 'external_updates-' . $this->slug;
85
+ } else {
86
+ $this->optionName = $this->getUniqueName('external_updates');
87
+ }
88
+ }
89
+
90
+ $this->package = $this->createInstalledPackage();
91
+ $this->scheduler = $this->createScheduler($checkPeriod);
92
+ $this->upgraderStatus = new Puc_v4p11_UpgraderStatus();
93
+ $this->updateState = new Puc_v4p11_StateStore($this->optionName);
94
+
95
+ if ( did_action('init') ) {
96
+ $this->loadTextDomain();
97
+ } else {
98
+ add_action('init', array($this, 'loadTextDomain'));
99
+ }
100
+
101
+ $this->installHooks();
102
+ }
103
+
104
+ /**
105
+ * @internal
106
+ */
107
+ public function loadTextDomain() {
108
+ //We're not using load_plugin_textdomain() or its siblings because figuring out where
109
+ //the library is located (plugin, mu-plugin, theme, custom wp-content paths) is messy.
110
+ $domain = 'plugin-update-checker';
111
+ $locale = apply_filters(
112
+ 'plugin_locale',
113
+ (is_admin() && function_exists('get_user_locale')) ? get_user_locale() : get_locale(),
114
+ $domain
115
+ );
116
+
117
+ $moFile = $domain . '-' . $locale . '.mo';
118
+ $path = realpath(dirname(__FILE__) . '/../../languages');
119
+
120
+ if ($path && file_exists($path)) {
121
+ load_textdomain($domain, $path . '/' . $moFile);
122
+ }
123
+ }
124
+
125
+ protected function installHooks() {
126
+ //Insert our update info into the update array maintained by WP.
127
+ add_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
128
+
129
+ //Insert translation updates into the update list.
130
+ add_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
131
+
132
+ //Clear translation updates when WP clears the update cache.
133
+ //This needs to be done directly because the library doesn't actually remove obsolete plugin updates,
134
+ //it just hides them (see getUpdate()). We can't do that with translations - too much disk I/O.
135
+ add_action(
136
+ 'delete_site_transient_' . $this->updateTransient,
137
+ array($this, 'clearCachedTranslationUpdates')
138
+ );
139
+
140
+ //Rename the update directory to be the same as the existing directory.
141
+ if ( $this->directoryName !== '.' ) {
142
+ add_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10, 3);
143
+ }
144
+
145
+ //Allow HTTP requests to the metadata URL even if it's on a local host.
146
+ add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
147
+
148
+ //DebugBar integration.
149
+ if ( did_action('plugins_loaded') ) {
150
+ $this->maybeInitDebugBar();
151
+ } else {
152
+ add_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Remove hooks that were added by this update checker instance.
158
+ */
159
+ public function removeHooks() {
160
+ remove_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
161
+ remove_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
162
+ remove_action(
163
+ 'delete_site_transient_' . $this->updateTransient,
164
+ array($this, 'clearCachedTranslationUpdates')
165
+ );
166
+
167
+ remove_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10);
168
+ remove_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10);
169
+ remove_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
170
+
171
+ remove_action('init', array($this, 'loadTextDomain'));
172
+
173
+ if ( $this->scheduler ) {
174
+ $this->scheduler->removeHooks();
175
+ }
176
+
177
+ if ( $this->debugBarExtension ) {
178
+ $this->debugBarExtension->removeHooks();
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Check if the current user has the required permissions to install updates.
184
+ *
185
+ * @return bool
186
+ */
187
+ abstract public function userCanInstallUpdates();
188
+
189
+ /**
190
+ * Explicitly allow HTTP requests to the metadata URL.
191
+ *
192
+ * WordPress has a security feature where the HTTP API will reject all requests that are sent to
193
+ * another site hosted on the same server as the current site (IP match), a local host, or a local
194
+ * IP, unless the host exactly matches the current site.
195
+ *
196
+ * This feature is opt-in (at least in WP 4.4). Apparently some people enable it.
197
+ *
198
+ * That can be a problem when you're developing your plugin and you decide to host the update information
199
+ * on the same server as your test site. Update requests will mysteriously fail.
200
+ *
201
+ * We fix that by adding an exception for the metadata host.
202
+ *
203
+ * @param bool $allow
204
+ * @param string $host
205
+ * @return bool
206
+ */
207
+ public function allowMetadataHost($allow, $host) {
208
+ if ( $this->cachedMetadataHost === 0 ) {
209
+ $this->cachedMetadataHost = parse_url($this->metadataUrl, PHP_URL_HOST);
210
+ }
211
+
212
+ if ( is_string($this->cachedMetadataHost) && (strtolower($host) === strtolower($this->cachedMetadataHost)) ) {
213
+ return true;
214
+ }
215
+ return $allow;
216
+ }
217
+
218
+ /**
219
+ * Create a package instance that represents this plugin or theme.
220
+ *
221
+ * @return Puc_v4p11_InstalledPackage
222
+ */
223
+ abstract protected function createInstalledPackage();
224
+
225
+ /**
226
+ * @return Puc_v4p11_InstalledPackage
227
+ */
228
+ public function getInstalledPackage() {
229
+ return $this->package;
230
+ }
231
+
232
+ /**
233
+ * Create an instance of the scheduler.
234
+ *
235
+ * This is implemented as a method to make it possible for plugins to subclass the update checker
236
+ * and substitute their own scheduler.
237
+ *
238
+ * @param int $checkPeriod
239
+ * @return Puc_v4p11_Scheduler
240
+ */
241
+ abstract protected function createScheduler($checkPeriod);
242
+
243
+ /**
244
+ * Check for updates. The results are stored in the DB option specified in $optionName.
245
+ *
246
+ * @return Puc_v4p11_Update|null
247
+ */
248
+ public function checkForUpdates() {
249
+ $installedVersion = $this->getInstalledVersion();
250
+ //Fail silently if we can't find the plugin/theme or read its header.
251
+ if ( $installedVersion === null ) {
252
+ $this->triggerError(
253
+ sprintf('Skipping update check for %s - installed version unknown.', $this->slug),
254
+ E_USER_WARNING
255
+ );
256
+ return null;
257
+ }
258
+
259
+ //Start collecting API errors.
260
+ $this->lastRequestApiErrors = array();
261
+ add_action('puc_api_error', array($this, 'collectApiErrors'), 10, 4);
262
+
263
+ $state = $this->updateState;
264
+ $state->setLastCheckToNow()
265
+ ->setCheckedVersion($installedVersion)
266
+ ->save(); //Save before checking in case something goes wrong
267
+
268
+ $state->setUpdate($this->requestUpdate());
269
+ $state->save();
270
+
271
+ //Stop collecting API errors.
272
+ remove_action('puc_api_error', array($this, 'collectApiErrors'), 10);
273
+
274
+ return $this->getUpdate();
275
+ }
276
+
277
+ /**
278
+ * Load the update checker state from the DB.
279
+ *
280
+ * @return Puc_v4p11_StateStore
281
+ */
282
+ public function getUpdateState() {
283
+ return $this->updateState->lazyLoad();
284
+ }
285
+
286
+ /**
287
+ * Reset update checker state - i.e. last check time, cached update data and so on.
288
+ *
289
+ * Call this when your plugin is being uninstalled, or if you want to
290
+ * clear the update cache.
291
+ */
292
+ public function resetUpdateState() {
293
+ $this->updateState->delete();
294
+ }
295
+
296
+ /**
297
+ * Get the details of the currently available update, if any.
298
+ *
299
+ * If no updates are available, or if the last known update version is below or equal
300
+ * to the currently installed version, this method will return NULL.
301
+ *
302
+ * Uses cached update data. To retrieve update information straight from
303
+ * the metadata URL, call requestUpdate() instead.
304
+ *
305
+ * @return Puc_v4p11_Update|null
306
+ */
307
+ public function getUpdate() {
308
+ $update = $this->updateState->getUpdate();
309
+
310
+ //Is there an update available?
311
+ if ( isset($update) ) {
312
+ //Check if the update is actually newer than the currently installed version.
313
+ $installedVersion = $this->getInstalledVersion();
314
+ if ( ($installedVersion !== null) && version_compare($update->version, $installedVersion, '>') ){
315
+ return $update;
316
+ }
317
+ }
318
+ return null;
319
+ }
320
+
321
+ /**
322
+ * Retrieve the latest update (if any) from the configured API endpoint.
323
+ *
324
+ * Subclasses should run the update through filterUpdateResult before returning it.
325
+ *
326
+ * @return Puc_v4p11_Update An instance of Update, or NULL when no updates are available.
327
+ */
328
+ abstract public function requestUpdate();
329
+
330
+ /**
331
+ * Filter the result of a requestUpdate() call.
332
+ *
333
+ * @param Puc_v4p11_Update|null $update
334
+ * @param array|WP_Error|null $httpResult The value returned by wp_remote_get(), if any.
335
+ * @return Puc_v4p11_Update
336
+ */
337
+ protected function filterUpdateResult($update, $httpResult = null) {
338
+ //Let plugins/themes modify the update.
339
+ $update = apply_filters($this->getUniqueName('request_update_result'), $update, $httpResult);
340
+
341
+ $this->fixSupportedWordpressVersion($update);
342
+
343
+ if ( isset($update, $update->translations) ) {
344
+ //Keep only those translation updates that apply to this site.
345
+ $update->translations = $this->filterApplicableTranslations($update->translations);
346
+ }
347
+
348
+ return $update;
349
+ }
350
+
351
+ /**
352
+ * The "Tested up to" field in the plugin metadata is supposed to be in the form of "major.minor",
353
+ * while WordPress core's list_plugin_updates() expects the $update->tested field to be an exact
354
+ * version, e.g. "major.minor.patch", to say it's compatible. In other case it shows
355
+ * "Compatibility: Unknown".
356
+ * The function mimics how wordpress.org API crafts the "tested" field out of "Tested up to".
357
+ *
358
+ * @param Puc_v4p11_Metadata|null $update
359
+ */
360
+ protected function fixSupportedWordpressVersion(Puc_v4p11_Metadata $update = null) {
361
+ if ( !isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested) ) {
362
+ return;
363
+ }
364
+
365
+ $actualWpVersions = array();
366
+
367
+ $wpVersion = $GLOBALS['wp_version'];
368
+
369
+ if ( function_exists('get_core_updates') ) {
370
+ $coreUpdates = get_core_updates();
371
+ if ( is_array($coreUpdates) ) {
372
+ foreach ($coreUpdates as $coreUpdate) {
373
+ if ( isset($coreUpdate->current) ) {
374
+ $actualWpVersions[] = $coreUpdate->current;
375
+ }
376
+ }
377
+ }
378
+ }
379
+
380
+ $actualWpVersions[] = $wpVersion;
381
+
382
+ $actualWpPatchNumber = null;
383
+ foreach ($actualWpVersions as $version) {
384
+ if ( preg_match('/^(?P<majorMinor>\d++\.\d++)(?:\.(?P<patch>\d++))?/', $version, $versionParts) ) {
385
+ if ( $versionParts['majorMinor'] === $update->tested ) {
386
+ $patch = isset($versionParts['patch']) ? intval($versionParts['patch']) : 0;
387
+ if ( $actualWpPatchNumber === null ) {
388
+ $actualWpPatchNumber = $patch;
389
+ } else {
390
+ $actualWpPatchNumber = max($actualWpPatchNumber, $patch);
391
+ }
392
+ }
393
+ }
394
+ }
395
+ if ( $actualWpPatchNumber === null ) {
396
+ $actualWpPatchNumber = 999;
397
+ }
398
+
399
+ if ( $actualWpPatchNumber > 0 ) {
400
+ $update->tested .= '.' . $actualWpPatchNumber;
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Get the currently installed version of the plugin or theme.
406
+ *
407
+ * @return string|null Version number.
408
+ */
409
+ public function getInstalledVersion() {
410
+ return $this->package->getInstalledVersion();
411
+ }
412
+
413
+ /**
414
+ * Get the full path of the plugin or theme directory.
415
+ *
416
+ * @return string
417
+ */
418
+ public function getAbsoluteDirectoryPath() {
419
+ return $this->package->getAbsoluteDirectoryPath();
420
+ }
421
+
422
+ /**
423
+ * Trigger a PHP error, but only when $debugMode is enabled.
424
+ *
425
+ * @param string $message
426
+ * @param int $errorType
427
+ */
428
+ public function triggerError($message, $errorType) {
429
+ if ( $this->isDebugModeEnabled() ) {
430
+ trigger_error($message, $errorType);
431
+ }
432
+ }
433
+
434
+ /**
435
+ * @return bool
436
+ */
437
+ protected function isDebugModeEnabled() {
438
+ if ( $this->debugMode === null ) {
439
+ $this->debugMode = (bool)(constant('WP_DEBUG'));
440
+ }
441
+ return $this->debugMode;
442
+ }
443
+
444
+ /**
445
+ * Get the full name of an update checker filter, action or DB entry.
446
+ *
447
+ * This method adds the "puc_" prefix and the "-$slug" suffix to the filter name.
448
+ * For example, "pre_inject_update" becomes "puc_pre_inject_update-plugin-slug".
449
+ *
450
+ * @param string $baseTag
451
+ * @return string
452
+ */
453
+ public function getUniqueName($baseTag) {
454
+ $name = 'puc_' . $baseTag;
455
+ if ( $this->filterSuffix !== '' ) {
456
+ $name .= '_' . $this->filterSuffix;
457
+ }
458
+ return $name . '-' . $this->slug;
459
+ }
460
+
461
+ /**
462
+ * Store API errors that are generated when checking for updates.
463
+ *
464
+ * @internal
465
+ * @param WP_Error $error
466
+ * @param array|null $httpResponse
467
+ * @param string|null $url
468
+ * @param string|null $slug
469
+ */
470
+ public function collectApiErrors($error, $httpResponse = null, $url = null, $slug = null) {
471
+ if ( isset($slug) && ($slug !== $this->slug) ) {
472
+ return;
473
+ }
474
+
475
+ $this->lastRequestApiErrors[] = array(
476
+ 'error' => $error,
477
+ 'httpResponse' => $httpResponse,
478
+ 'url' => $url,
479
+ );
480
+ }
481
+
482
+ /**
483
+ * @return array
484
+ */
485
+ public function getLastRequestApiErrors() {
486
+ return $this->lastRequestApiErrors;
487
+ }
488
+
489
+ /* -------------------------------------------------------------------
490
+ * PUC filters and filter utilities
491
+ * -------------------------------------------------------------------
492
+ */
493
+
494
+ /**
495
+ * Register a callback for one of the update checker filters.
496
+ *
497
+ * Identical to add_filter(), except it automatically adds the "puc_" prefix
498
+ * and the "-$slug" suffix to the filter name. For example, "request_info_result"
499
+ * becomes "puc_request_info_result-your_plugin_slug".
500
+ *
501
+ * @param string $tag
502
+ * @param callable $callback
503
+ * @param int $priority
504
+ * @param int $acceptedArgs
505
+ */
506
+ public function addFilter($tag, $callback, $priority = 10, $acceptedArgs = 1) {
507
+ add_filter($this->getUniqueName($tag), $callback, $priority, $acceptedArgs);
508
+ }
509
+
510
+ /* -------------------------------------------------------------------
511
+ * Inject updates
512
+ * -------------------------------------------------------------------
513
+ */
514
+
515
+ /**
516
+ * Insert the latest update (if any) into the update list maintained by WP.
517
+ *
518
+ * @param stdClass $updates Update list.
519
+ * @return stdClass Modified update list.
520
+ */
521
+ public function injectUpdate($updates) {
522
+ //Is there an update to insert?
523
+ $update = $this->getUpdate();
524
+
525
+ if ( !$this->shouldShowUpdates() ) {
526
+ $update = null;
527
+ }
528
+
529
+ if ( !empty($update) ) {
530
+ //Let plugins filter the update info before it's passed on to WordPress.
531
+ $update = apply_filters($this->getUniqueName('pre_inject_update'), $update);
532
+ $updates = $this->addUpdateToList($updates, $update->toWpFormat());
533
+ } else {
534
+ //Clean up any stale update info.
535
+ $updates = $this->removeUpdateFromList($updates);
536
+ //Add a placeholder item to the "no_update" list to enable auto-update support.
537
+ //If we don't do this, the option to enable automatic updates will only show up
538
+ //when an update is available.
539
+ $updates = $this->addNoUpdateItem($updates);
540
+ }
541
+
542
+ return $updates;
543
+ }
544
+
545
+ /**
546
+ * @param stdClass|null $updates
547
+ * @param stdClass|array $updateToAdd
548
+ * @return stdClass
549
+ */
550
+ protected function addUpdateToList($updates, $updateToAdd) {
551
+ if ( !is_object($updates) ) {
552
+ $updates = new stdClass();
553
+ $updates->response = array();
554
+ }
555
+
556
+ $updates->response[$this->getUpdateListKey()] = $updateToAdd;
557
+ return $updates;
558
+ }
559
+
560
+ /**
561
+ * @param stdClass|null $updates
562
+ * @return stdClass|null
563
+ */
564
+ protected function removeUpdateFromList($updates) {
565
+ if ( isset($updates, $updates->response) ) {
566
+ unset($updates->response[$this->getUpdateListKey()]);
567
+ }
568
+ return $updates;
569
+ }
570
+
571
+ /**
572
+ * See this post for more information:
573
+ * @link https://make.wordpress.org/core/2020/07/30/recommended-usage-of-the-updates-api-to-support-the-auto-updates-ui-for-plugins-and-themes-in-wordpress-5-5/
574
+ *
575
+ * @param stdClass|null $updates
576
+ * @return stdClass
577
+ */
578
+ protected function addNoUpdateItem($updates) {
579
+ if ( !is_object($updates) ) {
580
+ $updates = new stdClass();
581
+ $updates->response = array();
582
+ $updates->no_update = array();
583
+ } else if ( !isset($updates->no_update) ) {
584
+ $updates->no_update = array();
585
+ }
586
+
587
+ $updates->no_update[$this->getUpdateListKey()] = (object) $this->getNoUpdateItemFields();
588
+
589
+ return $updates;
590
+ }
591
+
592
+ /**
593
+ * Subclasses should override this method to add fields that are specific to plugins or themes.
594
+ * @return array
595
+ */
596
+ protected function getNoUpdateItemFields() {
597
+ return array(
598
+ 'new_version' => $this->getInstalledVersion(),
599
+ 'url' => '',
600
+ 'package' => '',
601
+ 'requires_php' => '',
602
+ );
603
+ }
604
+
605
+ /**
606
+ * Get the key that will be used when adding updates to the update list that's maintained
607
+ * by the WordPress core. The list is always an associative array, but the key is different
608
+ * for plugins and themes.
609
+ *
610
+ * @return string
611
+ */
612
+ abstract protected function getUpdateListKey();
613
+
614
+ /**
615
+ * Should we show available updates?
616
+ *
617
+ * Usually the answer is "yes", but there are exceptions. For example, WordPress doesn't
618
+ * support automatic updates installation for mu-plugins, so PUC usually won't show update
619
+ * notifications in that case. See the plugin-specific subclass for details.
620
+ *
621
+ * Note: This method only applies to updates that are displayed (or not) in the WordPress
622
+ * admin. It doesn't affect APIs like requestUpdate and getUpdate.
623
+ *
624
+ * @return bool
625
+ */
626
+ protected function shouldShowUpdates() {
627
+ return true;
628
+ }
629
+
630
+ /* -------------------------------------------------------------------
631
+ * JSON-based update API
632
+ * -------------------------------------------------------------------
633
+ */
634
+
635
+ /**
636
+ * Retrieve plugin or theme metadata from the JSON document at $this->metadataUrl.
637
+ *
638
+ * @param string $metaClass Parse the JSON as an instance of this class. It must have a static fromJson method.
639
+ * @param string $filterRoot
640
+ * @param array $queryArgs Additional query arguments.
641
+ * @return array [Puc_v4p11_Metadata|null, array|WP_Error] A metadata instance and the value returned by wp_remote_get().
642
+ */
643
+ protected function requestMetadata($metaClass, $filterRoot, $queryArgs = array()) {
644
+ //Query args to append to the URL. Plugins can add their own by using a filter callback (see addQueryArgFilter()).
645
+ $queryArgs = array_merge(
646
+ array(
647
+ 'installed_version' => strval($this->getInstalledVersion()),
648
+ 'php' => phpversion(),
649
+ 'locale' => get_locale(),
650
+ ),
651
+ $queryArgs
652
+ );
653
+ $queryArgs = apply_filters($this->getUniqueName($filterRoot . '_query_args'), $queryArgs);
654
+
655
+ //Various options for the wp_remote_get() call. Plugins can filter these, too.
656
+ $options = array(
657
+ 'timeout' => 10, //seconds
658
+ 'headers' => array(
659
+ 'Accept' => 'application/json',
660
+ ),
661
+ 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
662
+
663
+ );
664
+ $options = apply_filters($this->getUniqueName($filterRoot . '_options'), $options);
665
+
666
+ //The metadata file should be at 'http://your-api.com/url/here/$slug/info.json'
667
+ $url = $this->metadataUrl;
668
+ if ( !empty($queryArgs) ){
669
+ $url = add_query_arg($queryArgs, $url);
670
+ }
671
+
672
+ $result = wp_remote_get($url, $options);
673
+
674
+ $result = apply_filters($this->getUniqueName('request_metadata_http_result'), $result, $url, $options);
675
+
676
+ //Try to parse the response
677
+ $status = $this->validateApiResponse($result);
678
+ $metadata = null;
679
+ if ( !is_wp_error($status) ){
680
+ if ( version_compare(PHP_VERSION, '5.3', '>=') && (strpos($metaClass, '\\') === false) ) {
681
+ $metaClass = __NAMESPACE__ . '\\' . $metaClass;
682
+ }
683
+ $metadata = call_user_func(array($metaClass, 'fromJson'), $result['body']);
684
+ } else {
685
+ do_action('puc_api_error', $status, $result, $url, $this->slug);
686
+ $this->triggerError(
687
+ sprintf('The URL %s does not point to a valid metadata file. ', $url)
688
+ . $status->get_error_message(),
689
+ E_USER_WARNING
690
+ );
691
+ }
692
+
693
+ return array($metadata, $result);
694
+ }
695
+
696
+ /**
697
+ * Check if $result is a successful update API response.
698
+ *
699
+ * @param array|WP_Error $result
700
+ * @return true|WP_Error
701
+ */
702
+ protected function validateApiResponse($result) {
703
+ if ( is_wp_error($result) ) { /** @var WP_Error $result */
704
+ return new WP_Error($result->get_error_code(), 'WP HTTP Error: ' . $result->get_error_message());
705
+ }
706
+
707
+ if ( !isset($result['response']['code']) ) {
708
+ return new WP_Error(
709
+ 'puc_no_response_code',
710
+ 'wp_remote_get() returned an unexpected result.'
711
+ );
712
+ }
713
+
714
+ if ( $result['response']['code'] !== 200 ) {
715
+ return new WP_Error(
716
+ 'puc_unexpected_response_code',
717
+ 'HTTP response code is ' . $result['response']['code'] . ' (expected: 200)'
718
+ );
719
+ }
720
+
721
+ if ( empty($result['body']) ) {
722
+ return new WP_Error('puc_empty_response', 'The metadata file appears to be empty.');
723
+ }
724
+
725
+ return true;
726
+ }
727
+
728
+ /* -------------------------------------------------------------------
729
+ * Language packs / Translation updates
730
+ * -------------------------------------------------------------------
731
+ */
732
+
733
+ /**
734
+ * Filter a list of translation updates and return a new list that contains only updates
735
+ * that apply to the current site.
736
+ *
737
+ * @param array $translations
738
+ * @return array
739
+ */
740
+ protected function filterApplicableTranslations($translations) {
741
+ $languages = array_flip(array_values(get_available_languages()));
742
+ $installedTranslations = $this->getInstalledTranslations();
743
+
744
+ $applicableTranslations = array();
745
+ foreach ($translations as $translation) {
746
+ //Does it match one of the available core languages?
747
+ $isApplicable = array_key_exists($translation->language, $languages);
748
+ //Is it more recent than an already-installed translation?
749
+ if ( isset($installedTranslations[$translation->language]) ) {
750
+ $updateTimestamp = strtotime($translation->updated);
751
+ $installedTimestamp = strtotime($installedTranslations[$translation->language]['PO-Revision-Date']);
752
+ $isApplicable = $updateTimestamp > $installedTimestamp;
753
+ }
754
+
755
+ if ( $isApplicable ) {
756
+ $applicableTranslations[] = $translation;
757
+ }
758
+ }
759
+
760
+ return $applicableTranslations;
761
+ }
762
+
763
+ /**
764
+ * Get a list of installed translations for this plugin or theme.
765
+ *
766
+ * @return array
767
+ */
768
+ protected function getInstalledTranslations() {
769
+ if ( !function_exists('wp_get_installed_translations') ) {
770
+ return array();
771
+ }
772
+ $installedTranslations = wp_get_installed_translations($this->translationType . 's');
773
+ if ( isset($installedTranslations[$this->directoryName]) ) {
774
+ $installedTranslations = $installedTranslations[$this->directoryName];
775
+ } else {
776
+ $installedTranslations = array();
777
+ }
778
+ return $installedTranslations;
779
+ }
780
+
781
+ /**
782
+ * Insert translation updates into the list maintained by WordPress.
783
+ *
784
+ * @param stdClass $updates
785
+ * @return stdClass
786
+ */
787
+ public function injectTranslationUpdates($updates) {
788
+ $translationUpdates = $this->getTranslationUpdates();
789
+ if ( empty($translationUpdates) ) {
790
+ return $updates;
791
+ }
792
+
793
+ //Being defensive.
794
+ if ( !is_object($updates) ) {
795
+ $updates = new stdClass();
796
+ }
797
+ if ( !isset($updates->translations) ) {
798
+ $updates->translations = array();
799
+ }
800
+
801
+ //In case there's a name collision with a plugin or theme hosted on wordpress.org,
802
+ //remove any preexisting updates that match our thing.
803
+ $updates->translations = array_values(array_filter(
804
+ $updates->translations,
805
+ array($this, 'isNotMyTranslation')
806
+ ));
807
+
808
+ //Add our updates to the list.
809
+ foreach($translationUpdates as $update) {
810
+ $convertedUpdate = array_merge(
811
+ array(
812
+ 'type' => $this->translationType,
813
+ 'slug' => $this->directoryName,
814
+ 'autoupdate' => 0,
815
+ //AFAICT, WordPress doesn't actually use the "version" field for anything.
816
+ //But lets make sure it's there, just in case.
817
+ 'version' => isset($update->version) ? $update->version : ('1.' . strtotime($update->updated)),
818
+ ),
819
+ (array)$update
820
+ );
821
+
822
+ $updates->translations[] = $convertedUpdate;
823
+ }
824
+
825
+ return $updates;
826
+ }
827
+
828
+ /**
829
+ * Get a list of available translation updates.
830
+ *
831
+ * This method will return an empty array if there are no updates.
832
+ * Uses cached update data.
833
+ *
834
+ * @return array
835
+ */
836
+ public function getTranslationUpdates() {
837
+ return $this->updateState->getTranslations();
838
+ }
839
+
840
+ /**
841
+ * Remove all cached translation updates.
842
+ *
843
+ * @see wp_clean_update_cache
844
+ */
845
+ public function clearCachedTranslationUpdates() {
846
+ $this->updateState->setTranslations(array());
847
+ }
848
+
849
+ /**
850
+ * Filter callback. Keeps only translations that *don't* match this plugin or theme.
851
+ *
852
+ * @param array $translation
853
+ * @return bool
854
+ */
855
+ protected function isNotMyTranslation($translation) {
856
+ $isMatch = isset($translation['type'], $translation['slug'])
857
+ && ($translation['type'] === $this->translationType)
858
+ && ($translation['slug'] === $this->directoryName);
859
+
860
+ return !$isMatch;
861
+ }
862
+
863
+ /* -------------------------------------------------------------------
864
+ * Fix directory name when installing updates
865
+ * -------------------------------------------------------------------
866
+ */
867
+
868
+ /**
869
+ * Rename the update directory to match the existing plugin/theme directory.
870
+ *
871
+ * When WordPress installs a plugin or theme update, it assumes that the ZIP file will contain
872
+ * exactly one directory, and that the directory name will be the same as the directory where
873
+ * the plugin or theme is currently installed.
874
+ *
875
+ * GitHub and other repositories provide ZIP downloads, but they often use directory names like
876
+ * "project-branch" or "project-tag-hash". We need to change the name to the actual plugin folder.
877
+ *
878
+ * This is a hook callback. Don't call it from a plugin.
879
+ *
880
+ * @access protected
881
+ *
882
+ * @param string $source The directory to copy to /wp-content/plugins or /wp-content/themes. Usually a subdirectory of $remoteSource.
883
+ * @param string $remoteSource WordPress has extracted the update to this directory.
884
+ * @param WP_Upgrader $upgrader
885
+ * @return string|WP_Error
886
+ */
887
+ public function fixDirectoryName($source, $remoteSource, $upgrader) {
888
+ global $wp_filesystem;
889
+ /** @var WP_Filesystem_Base $wp_filesystem */
890
+
891
+ //Basic sanity checks.
892
+ if ( !isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem) ) {
893
+ return $source;
894
+ }
895
+
896
+ //If WordPress is upgrading anything other than our plugin/theme, leave the directory name unchanged.
897
+ if ( !$this->isBeingUpgraded($upgrader) ) {
898
+ return $source;
899
+ }
900
+
901
+ //Rename the source to match the existing directory.
902
+ $correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
903
+ if ( $source !== $correctedSource ) {
904
+ //The update archive should contain a single directory that contains the rest of plugin/theme files.
905
+ //Otherwise, WordPress will try to copy the entire working directory ($source == $remoteSource).
906
+ //We can't rename $remoteSource because that would break WordPress code that cleans up temporary files
907
+ //after update.
908
+ if ( $this->isBadDirectoryStructure($remoteSource) ) {
909
+ return new WP_Error(
910
+ 'puc-incorrect-directory-structure',
911
+ sprintf(
912
+ 'The directory structure of the update is incorrect. All files should be inside ' .
913
+ 'a directory named <span class="code">%s</span>, not at the root of the ZIP archive.',
914
+ htmlentities($this->slug)
915
+ )
916
+ );
917
+ }
918
+
919
+ /** @var WP_Upgrader_Skin $upgrader ->skin */
920
+ $upgrader->skin->feedback(sprintf(
921
+ 'Renaming %s to %s&#8230;',
922
+ '<span class="code">' . basename($source) . '</span>',
923
+ '<span class="code">' . $this->directoryName . '</span>'
924
+ ));
925
+
926
+ if ( $wp_filesystem->move($source, $correctedSource, true) ) {
927
+ $upgrader->skin->feedback('Directory successfully renamed.');
928
+ return $correctedSource;
929
+ } else {
930
+ return new WP_Error(
931
+ 'puc-rename-failed',
932
+ 'Unable to rename the update to match the existing directory.'
933
+ );
934
+ }
935
+ }
936
+
937
+ return $source;
938
+ }
939
+
940
+ /**
941
+ * Is there an update being installed right now, for this plugin or theme?
942
+ *
943
+ * @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
944
+ * @return bool
945
+ */
946
+ abstract public function isBeingUpgraded($upgrader = null);
947
+
948
+ /**
949
+ * Check for incorrect update directory structure. An update must contain a single directory,
950
+ * all other files should be inside that directory.
951
+ *
952
+ * @param string $remoteSource Directory path.
953
+ * @return bool
954
+ */
955
+ protected function isBadDirectoryStructure($remoteSource) {
956
+ global $wp_filesystem;
957
+ /** @var WP_Filesystem_Base $wp_filesystem */
958
+
959
+ $sourceFiles = $wp_filesystem->dirlist($remoteSource);
960
+ if ( is_array($sourceFiles) ) {
961
+ $sourceFiles = array_keys($sourceFiles);
962
+ $firstFilePath = trailingslashit($remoteSource) . $sourceFiles[0];
963
+ return (count($sourceFiles) > 1) || (!$wp_filesystem->is_dir($firstFilePath));
964
+ }
965
+
966
+ //Assume it's fine.
967
+ return false;
968
+ }
969
+
970
+ /* -------------------------------------------------------------------
971
+ * DebugBar integration
972
+ * -------------------------------------------------------------------
973
+ */
974
+
975
+ /**
976
+ * Initialize the update checker Debug Bar plugin/add-on thingy.
977
+ */
978
+ public function maybeInitDebugBar() {
979
+ if ( class_exists('Debug_Bar', false) && file_exists(dirname(__FILE__) . '/DebugBar') ) {
980
+ $this->debugBarExtension = $this->createDebugBarExtension();
981
+ }
982
+ }
983
+
984
+ protected function createDebugBarExtension() {
985
+ return new Puc_v4p11_DebugBar_Extension($this);
986
+ }
987
+
988
+ /**
989
+ * Display additional configuration details in the Debug Bar panel.
990
+ *
991
+ * @param Puc_v4p11_DebugBar_Panel $panel
992
+ */
993
+ public function onDisplayConfiguration($panel) {
994
+ //Do nothing. Subclasses can use this to add additional info to the panel.
995
+ }
996
+
997
+ }
998
+
999
+ endif;
app/core/puc/Puc/v4p11/UpgraderStatus.php ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_UpgraderStatus', false) ):
3
+
4
+ /**
5
+ * A utility class that helps figure out which plugin or theme WordPress is upgrading.
6
+ *
7
+ * It may seem strange to have a separate class just for that, but the task is surprisingly complicated.
8
+ * Core classes like Plugin_Upgrader don't expose the plugin file name during an in-progress update (AFAICT).
9
+ * This class uses a few workarounds and heuristics to get the file name.
10
+ */
11
+ class Puc_v4p11_UpgraderStatus {
12
+ private $currentType = null; //"plugin" or "theme".
13
+ private $currentId = null; //Plugin basename or theme directory name.
14
+
15
+ public function __construct() {
16
+ //Keep track of which plugin/theme WordPress is currently upgrading.
17
+ add_filter('upgrader_pre_install', array($this, 'setUpgradedThing'), 10, 2);
18
+ add_filter('upgrader_package_options', array($this, 'setUpgradedPluginFromOptions'), 10, 1);
19
+ add_filter('upgrader_post_install', array($this, 'clearUpgradedThing'), 10, 1);
20
+ add_action('upgrader_process_complete', array($this, 'clearUpgradedThing'), 10, 1);
21
+ }
22
+
23
+ /**
24
+ * Is there and update being installed RIGHT NOW, for a specific plugin?
25
+ *
26
+ * Caution: This method is unreliable. WordPress doesn't make it easy to figure out what it is upgrading,
27
+ * and upgrader implementations are liable to change without notice.
28
+ *
29
+ * @param string $pluginFile The plugin to check.
30
+ * @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
31
+ * @return bool True if the plugin identified by $pluginFile is being upgraded.
32
+ */
33
+ public function isPluginBeingUpgraded($pluginFile, $upgrader = null) {
34
+ return $this->isBeingUpgraded('plugin', $pluginFile, $upgrader);
35
+ }
36
+
37
+ /**
38
+ * Is there an update being installed for a specific theme?
39
+ *
40
+ * @param string $stylesheet Theme directory name.
41
+ * @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
42
+ * @return bool
43
+ */
44
+ public function isThemeBeingUpgraded($stylesheet, $upgrader = null) {
45
+ return $this->isBeingUpgraded('theme', $stylesheet, $upgrader);
46
+ }
47
+
48
+ /**
49
+ * Check if a specific theme or plugin is being upgraded.
50
+ *
51
+ * @param string $type
52
+ * @param string $id
53
+ * @param Plugin_Upgrader|WP_Upgrader|null $upgrader
54
+ * @return bool
55
+ */
56
+ protected function isBeingUpgraded($type, $id, $upgrader = null) {
57
+ if ( isset($upgrader) ) {
58
+ list($currentType, $currentId) = $this->getThingBeingUpgradedBy($upgrader);
59
+ if ( $currentType !== null ) {
60
+ $this->currentType = $currentType;
61
+ $this->currentId = $currentId;
62
+ }
63
+ }
64
+ return ($this->currentType === $type) && ($this->currentId === $id);
65
+ }
66
+
67
+ /**
68
+ * Figure out which theme or plugin is being upgraded by a WP_Upgrader instance.
69
+ *
70
+ * Returns an array with two items. The first item is the type of the thing that's being
71
+ * upgraded: "plugin" or "theme". The second item is either the plugin basename or
72
+ * the theme directory name. If we can't determine what the upgrader is doing, both items
73
+ * will be NULL.
74
+ *
75
+ * Examples:
76
+ * ['plugin', 'plugin-dir-name/plugin.php']
77
+ * ['theme', 'theme-dir-name']
78
+ *
79
+ * @param Plugin_Upgrader|WP_Upgrader $upgrader
80
+ * @return array
81
+ */
82
+ private function getThingBeingUpgradedBy($upgrader) {
83
+ if ( !isset($upgrader, $upgrader->skin) ) {
84
+ return array(null, null);
85
+ }
86
+
87
+ //Figure out which plugin or theme is being upgraded.
88
+ $pluginFile = null;
89
+ $themeDirectoryName = null;
90
+
91
+ $skin = $upgrader->skin;
92
+ if ( isset($skin->theme_info) && ($skin->theme_info instanceof WP_Theme) ) {
93
+ $themeDirectoryName = $skin->theme_info->get_stylesheet();
94
+ } elseif ( $skin instanceof Plugin_Upgrader_Skin ) {
95
+ if ( isset($skin->plugin) && is_string($skin->plugin) && ($skin->plugin !== '') ) {
96
+ $pluginFile = $skin->plugin;
97
+ }
98
+ } elseif ( $skin instanceof Theme_Upgrader_Skin ) {
99
+ if ( isset($skin->theme) && is_string($skin->theme) && ($skin->theme !== '') ) {
100
+ $themeDirectoryName = $skin->theme;
101
+ }
102
+ } elseif ( isset($skin->plugin_info) && is_array($skin->plugin_info) ) {
103
+ //This case is tricky because Bulk_Plugin_Upgrader_Skin (etc) doesn't actually store the plugin
104
+ //filename anywhere. Instead, it has the plugin headers in $plugin_info. So the best we can
105
+ //do is compare those headers to the headers of installed plugins.
106
+ $pluginFile = $this->identifyPluginByHeaders($skin->plugin_info);
107
+ }
108
+
109
+ if ( $pluginFile !== null ) {
110
+ return array('plugin', $pluginFile);
111
+ } elseif ( $themeDirectoryName !== null ) {
112
+ return array('theme', $themeDirectoryName);
113
+ }
114
+ return array(null, null);
115
+ }
116
+
117
+ /**
118
+ * Identify an installed plugin based on its headers.
119
+ *
120
+ * @param array $searchHeaders The plugin file header to look for.
121
+ * @return string|null Plugin basename ("foo/bar.php"), or NULL if we can't identify the plugin.
122
+ */
123
+ private function identifyPluginByHeaders($searchHeaders) {
124
+ if ( !function_exists('get_plugins') ){
125
+ /** @noinspection PhpIncludeInspection */
126
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
127
+ }
128
+
129
+ $installedPlugins = get_plugins();
130
+ $matches = array();
131
+ foreach($installedPlugins as $pluginBasename => $headers) {
132
+ $diff1 = array_diff_assoc($headers, $searchHeaders);
133
+ $diff2 = array_diff_assoc($searchHeaders, $headers);
134
+ if ( empty($diff1) && empty($diff2) ) {
135
+ $matches[] = $pluginBasename;
136
+ }
137
+ }
138
+
139
+ //It's possible (though very unlikely) that there could be two plugins with identical
140
+ //headers. In that case, we can't unambiguously identify the plugin that's being upgraded.
141
+ if ( count($matches) !== 1 ) {
142
+ return null;
143
+ }
144
+
145
+ return reset($matches);
146
+ }
147
+
148
+ /**
149
+ * @access private
150
+ *
151
+ * @param mixed $input
152
+ * @param array $hookExtra
153
+ * @return mixed Returns $input unaltered.
154
+ */
155
+ public function setUpgradedThing($input, $hookExtra) {
156
+ if ( !empty($hookExtra['plugin']) && is_string($hookExtra['plugin']) ) {
157
+ $this->currentId = $hookExtra['plugin'];
158
+ $this->currentType = 'plugin';
159
+ } elseif ( !empty($hookExtra['theme']) && is_string($hookExtra['theme']) ) {
160
+ $this->currentId = $hookExtra['theme'];
161
+ $this->currentType = 'theme';
162
+ } else {
163
+ $this->currentType = null;
164
+ $this->currentId = null;
165
+ }
166
+ return $input;
167
+ }
168
+
169
+ /**
170
+ * @access private
171
+ *
172
+ * @param array $options
173
+ * @return array
174
+ */
175
+ public function setUpgradedPluginFromOptions($options) {
176
+ if ( isset($options['hook_extra']['plugin']) && is_string($options['hook_extra']['plugin']) ) {
177
+ $this->currentType = 'plugin';
178
+ $this->currentId = $options['hook_extra']['plugin'];
179
+ } else {
180
+ $this->currentType = null;
181
+ $this->currentId = null;
182
+ }
183
+ return $options;
184
+ }
185
+
186
+ /**
187
+ * @access private
188
+ *
189
+ * @param mixed $input
190
+ * @return mixed Returns $input unaltered.
191
+ */
192
+ public function clearUpgradedThing($input = null) {
193
+ $this->currentId = null;
194
+ $this->currentType = null;
195
+ return $input;
196
+ }
197
+ }
198
+
199
+ endif;
app/core/puc/Puc/v4p11/Utils.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_Utils', false) ):
4
+
5
+ class Puc_v4p11_Utils {
6
+ /**
7
+ * Get a value from a nested array or object based on a path.
8
+ *
9
+ * @param array|object|null $collection Get an entry from this array.
10
+ * @param array|string $path A list of array keys in hierarchy order, or a string path like "foo.bar.baz".
11
+ * @param mixed $default The value to return if the specified path is not found.
12
+ * @param string $separator Path element separator. Only applies to string paths.
13
+ * @return mixed
14
+ */
15
+ public static function get($collection, $path, $default = null, $separator = '.') {
16
+ if ( is_string($path) ) {
17
+ $path = explode($separator, $path);
18
+ }
19
+
20
+ //Follow the $path into $input as far as possible.
21
+ $currentValue = $collection;
22
+ foreach ($path as $node) {
23
+ if ( is_array($currentValue) && isset($currentValue[$node]) ) {
24
+ $currentValue = $currentValue[$node];
25
+ } else if ( is_object($currentValue) && isset($currentValue->$node) ) {
26
+ $currentValue = $currentValue->$node;
27
+ } else {
28
+ return $default;
29
+ }
30
+ }
31
+
32
+ return $currentValue;
33
+ }
34
+
35
+ /**
36
+ * Get the first array element that is not empty.
37
+ *
38
+ * @param array $values
39
+ * @param mixed|null $default Returns this value if there are no non-empty elements.
40
+ * @return mixed|null
41
+ */
42
+ public static function findNotEmpty($values, $default = null) {
43
+ if ( empty($values) ) {
44
+ return $default;
45
+ }
46
+
47
+ foreach ($values as $value) {
48
+ if ( !empty($value) ) {
49
+ return $value;
50
+ }
51
+ }
52
+
53
+ return $default;
54
+ }
55
+
56
+ /**
57
+ * Check if the input string starts with the specified prefix.
58
+ *
59
+ * @param string $input
60
+ * @param string $prefix
61
+ * @return bool
62
+ */
63
+ public static function startsWith($input, $prefix) {
64
+ $length = strlen($prefix);
65
+ return (substr($input, 0, $length) === $prefix);
66
+ }
67
+ }
68
+
69
+ endif;
app/core/puc/Puc/v4p11/Vcs/Api.php ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Vcs_Api') ):
3
+
4
+ abstract class Puc_v4p11_Vcs_Api {
5
+ protected $tagNameProperty = 'name';
6
+ protected $slug = '';
7
+
8
+ /**
9
+ * @var string
10
+ */
11
+ protected $repositoryUrl = '';
12
+
13
+ /**
14
+ * @var mixed Authentication details for private repositories. Format depends on service.
15
+ */
16
+ protected $credentials = null;
17
+
18
+ /**
19
+ * @var string The filter tag that's used to filter options passed to wp_remote_get.
20
+ * For example, "puc_request_info_options-slug" or "puc_request_update_options_theme-slug".
21
+ */
22
+ protected $httpFilterName = '';
23
+
24
+ /**
25
+ * @var string|null
26
+ */
27
+ protected $localDirectory = null;
28
+
29
+ /**
30
+ * Puc_v4p11_Vcs_Api constructor.
31
+ *
32
+ * @param string $repositoryUrl
33
+ * @param array|string|null $credentials
34
+ */
35
+ public function __construct($repositoryUrl, $credentials = null) {
36
+ $this->repositoryUrl = $repositoryUrl;
37
+ $this->setAuthentication($credentials);
38
+ }
39
+
40
+ /**
41
+ * @return string
42
+ */
43
+ public function getRepositoryUrl() {
44
+ return $this->repositoryUrl;
45
+ }
46
+
47
+ /**
48
+ * Figure out which reference (i.e tag or branch) contains the latest version.
49
+ *
50
+ * @param string $configBranch Start looking in this branch.
51
+ * @return null|Puc_v4p11_Vcs_Reference
52
+ */
53
+ abstract public function chooseReference($configBranch);
54
+
55
+ /**
56
+ * Get the readme.txt file from the remote repository and parse it
57
+ * according to the plugin readme standard.
58
+ *
59
+ * @param string $ref Tag or branch name.
60
+ * @return array Parsed readme.
61
+ */
62
+ public function getRemoteReadme($ref = 'master') {
63
+ $fileContents = $this->getRemoteFile($this->getLocalReadmeName(), $ref);
64
+ if ( empty($fileContents) ) {
65
+ return array();
66
+ }
67
+
68
+ $parser = new PucReadmeParser();
69
+ return $parser->parse_readme_contents($fileContents);
70
+ }
71
+
72
+ /**
73
+ * Get the case-sensitive name of the local readme.txt file.
74
+ *
75
+ * In most cases it should just be called "readme.txt", but some plugins call it "README.txt",
76
+ * "README.TXT", or even "Readme.txt". Most VCS are case-sensitive so we need to know the correct
77
+ * capitalization.
78
+ *
79
+ * Defaults to "readme.txt" (all lowercase).
80
+ *
81
+ * @return string
82
+ */
83
+ public function getLocalReadmeName() {
84
+ static $fileName = null;
85
+ if ( $fileName !== null ) {
86
+ return $fileName;
87
+ }
88
+
89
+ $fileName = 'readme.txt';
90
+ if ( isset($this->localDirectory) ) {
91
+ $files = scandir($this->localDirectory);
92
+ if ( !empty($files) ) {
93
+ foreach ($files as $possibleFileName) {
94
+ if ( strcasecmp($possibleFileName, 'readme.txt') === 0 ) {
95
+ $fileName = $possibleFileName;
96
+ break;
97
+ }
98
+ }
99
+ }
100
+ }
101
+ return $fileName;
102
+ }
103
+
104
+ /**
105
+ * Get a branch.
106
+ *
107
+ * @param string $branchName
108
+ * @return Puc_v4p11_Vcs_Reference|null
109
+ */
110
+ abstract public function getBranch($branchName);
111
+
112
+ /**
113
+ * Get a specific tag.
114
+ *
115
+ * @param string $tagName
116
+ * @return Puc_v4p11_Vcs_Reference|null
117
+ */
118
+ abstract public function getTag($tagName);
119
+
120
+ /**
121
+ * Get the tag that looks like the highest version number.
122
+ * (Implementations should skip pre-release versions if possible.)
123
+ *
124
+ * @return Puc_v4p11_Vcs_Reference|null
125
+ */
126
+ abstract public function getLatestTag();
127
+
128
+ /**
129
+ * Check if a tag name string looks like a version number.
130
+ *
131
+ * @param string $name
132
+ * @return bool
133
+ */
134
+ protected function looksLikeVersion($name) {
135
+ //Tag names may be prefixed with "v", e.g. "v1.2.3".
136
+ $name = ltrim($name, 'v');
137
+
138
+ //The version string must start with a number.
139
+ if ( !is_numeric(substr($name, 0, 1)) ) {
140
+ return false;
141
+ }
142
+
143
+ //The goal is to accept any SemVer-compatible or "PHP-standardized" version number.
144
+ return (preg_match('@^(\d{1,5}?)(\.\d{1,10}?){0,4}?($|[abrdp+_\-]|\s)@i', $name) === 1);
145
+ }
146
+
147
+ /**
148
+ * Check if a tag appears to be named like a version number.
149
+ *
150
+ * @param stdClass $tag
151
+ * @return bool
152
+ */
153
+ protected function isVersionTag($tag) {
154
+ $property = $this->tagNameProperty;
155
+ return isset($tag->$property) && $this->looksLikeVersion($tag->$property);
156
+ }
157
+
158
+ /**
159
+ * Sort a list of tags as if they were version numbers.
160
+ * Tags that don't look like version number will be removed.
161
+ *
162
+ * @param stdClass[] $tags Array of tag objects.
163
+ * @return stdClass[] Filtered array of tags sorted in descending order.
164
+ */
165
+ protected function sortTagsByVersion($tags) {
166
+ //Keep only those tags that look like version numbers.
167
+ $versionTags = array_filter($tags, array($this, 'isVersionTag'));
168
+ //Sort them in descending order.
169
+ usort($versionTags, array($this, 'compareTagNames'));
170
+
171
+ return $versionTags;
172
+ }
173
+
174
+ /**
175
+ * Compare two tags as if they were version number.
176
+ *
177
+ * @param stdClass $tag1 Tag object.
178
+ * @param stdClass $tag2 Another tag object.
179
+ * @return int
180
+ */
181
+ protected function compareTagNames($tag1, $tag2) {
182
+ $property = $this->tagNameProperty;
183
+ if ( !isset($tag1->$property) ) {
184
+ return 1;
185
+ }
186
+ if ( !isset($tag2->$property) ) {
187
+ return -1;
188
+ }
189
+ return -version_compare(ltrim($tag1->$property, 'v'), ltrim($tag2->$property, 'v'));
190
+ }
191
+
192
+ /**
193
+ * Get the contents of a file from a specific branch or tag.
194
+ *
195
+ * @param string $path File name.
196
+ * @param string $ref
197
+ * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
198
+ */
199
+ abstract public function getRemoteFile($path, $ref = 'master');
200
+
201
+ /**
202
+ * Get the timestamp of the latest commit that changed the specified branch or tag.
203
+ *
204
+ * @param string $ref Reference name (e.g. branch or tag).
205
+ * @return string|null
206
+ */
207
+ abstract public function getLatestCommitTime($ref);
208
+
209
+ /**
210
+ * Get the contents of the changelog file from the repository.
211
+ *
212
+ * @param string $ref
213
+ * @param string $localDirectory Full path to the local plugin or theme directory.
214
+ * @return null|string The HTML contents of the changelog.
215
+ */
216
+ public function getRemoteChangelog($ref, $localDirectory) {
217
+ $filename = $this->findChangelogName($localDirectory);
218
+ if ( empty($filename) ) {
219
+ return null;
220
+ }
221
+
222
+ $changelog = $this->getRemoteFile($filename, $ref);
223
+ if ( $changelog === null ) {
224
+ return null;
225
+ }
226
+
227
+ /** @noinspection PhpUndefinedClassInspection */
228
+ return Parsedown::instance()->text($changelog);
229
+ }
230
+
231
+ /**
232
+ * Guess the name of the changelog file.
233
+ *
234
+ * @param string $directory
235
+ * @return string|null
236
+ */
237
+ protected function findChangelogName($directory = null) {
238
+ if ( !isset($directory) ) {
239
+ $directory = $this->localDirectory;
240
+ }
241
+ if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
242
+ return null;
243
+ }
244
+
245
+ $possibleNames = array('CHANGES.md', 'CHANGELOG.md', 'changes.md', 'changelog.md');
246
+ $files = scandir($directory);
247
+ $foundNames = array_intersect($possibleNames, $files);
248
+
249
+ if ( !empty($foundNames) ) {
250
+ return reset($foundNames);
251
+ }
252
+ return null;
253
+ }
254
+
255
+ /**
256
+ * Set authentication credentials.
257
+ *
258
+ * @param $credentials
259
+ */
260
+ public function setAuthentication($credentials) {
261
+ $this->credentials = $credentials;
262
+ }
263
+
264
+ public function isAuthenticationEnabled() {
265
+ return !empty($this->credentials);
266
+ }
267
+
268
+ /**
269
+ * @param string $url
270
+ * @return string
271
+ */
272
+ public function signDownloadUrl($url) {
273
+ return $url;
274
+ }
275
+
276
+ /**
277
+ * @param string $filterName
278
+ */
279
+ public function setHttpFilterName($filterName) {
280
+ $this->httpFilterName = $filterName;
281
+ }
282
+
283
+ /**
284
+ * @param string $directory
285
+ */
286
+ public function setLocalDirectory($directory) {
287
+ if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
288
+ $this->localDirectory = null;
289
+ } else {
290
+ $this->localDirectory = $directory;
291
+ }
292
+ }
293
+
294
+ /**
295
+ * @param string $slug
296
+ */
297
+ public function setSlug($slug) {
298
+ $this->slug = $slug;
299
+ }
300
+ }
301
+
302
+ endif;
app/core/puc/Puc/v4p11/Vcs/BaseChecker.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !interface_exists('Puc_v4p11_Vcs_BaseChecker', false) ):
3
+
4
+ interface Puc_v4p11_Vcs_BaseChecker {
5
+ /**
6
+ * Set the repository branch to use for updates. Defaults to 'master'.
7
+ *
8
+ * @param string $branch
9
+ * @return $this
10
+ */
11
+ public function setBranch($branch);
12
+
13
+ /**
14
+ * Set authentication credentials.
15
+ *
16
+ * @param array|string $credentials
17
+ * @return $this
18
+ */
19
+ public function setAuthentication($credentials);
20
+
21
+ /**
22
+ * @return Puc_v4p11_Vcs_Api
23
+ */
24
+ public function getVcsApi();
25
+ }
26
+
27
+ endif;
app/core/puc/Puc/v4p11/Vcs/BitBucketApi.php ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Vcs_BitBucketApi', false) ):
3
+
4
+ class Puc_v4p11_Vcs_BitBucketApi extends Puc_v4p11_Vcs_Api {
5
+ /**
6
+ * @var Puc_v4p11_OAuthSignature
7
+ */
8
+ private $oauth = null;
9
+
10
+ /**
11
+ * @var string
12
+ */
13
+ private $username;
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ private $repository;
19
+
20
+ public function __construct($repositoryUrl, $credentials = array()) {
21
+ $path = parse_url($repositoryUrl, PHP_URL_PATH);
22
+ if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
23
+ $this->username = $matches['username'];
24
+ $this->repository = $matches['repository'];
25
+ } else {
26
+ throw new InvalidArgumentException('Invalid BitBucket repository URL: "' . $repositoryUrl . '"');
27
+ }
28
+
29
+ parent::__construct($repositoryUrl, $credentials);
30
+ }
31
+
32
+ /**
33
+ * Figure out which reference (i.e tag or branch) contains the latest version.
34
+ *
35
+ * @param string $configBranch Start looking in this branch.
36
+ * @return null|Puc_v4p11_Vcs_Reference
37
+ */
38
+ public function chooseReference($configBranch) {
39
+ $updateSource = null;
40
+
41
+ //Check if there's a "Stable tag: 1.2.3" header that points to a valid tag.
42
+ $updateSource = $this->getStableTag($configBranch);
43
+
44
+ //Look for version-like tags.
45
+ if ( !$updateSource && ($configBranch === 'master' || $configBranch === 'main') ) {
46
+ $updateSource = $this->getLatestTag();
47
+ }
48
+ //If all else fails, use the specified branch itself.
49
+ if ( !$updateSource ) {
50
+ $updateSource = $this->getBranch($configBranch);
51
+ }
52
+
53
+ return $updateSource;
54
+ }
55
+
56
+ public function getBranch($branchName) {
57
+ $branch = $this->api('/refs/branches/' . $branchName);
58
+ if ( is_wp_error($branch) || empty($branch) ) {
59
+ return null;
60
+ }
61
+
62
+ //The "/src/{stuff}/{path}" endpoint doesn't seem to handle branch names that contain slashes.
63
+ //If we don't encode the slash, we get a 404. If we encode it as "%2F", we get a 401.
64
+ //To avoid issues, if the branch name is not URL-safe, let's use the commit hash instead.
65
+ $ref = $branch->name;
66
+ if ((urlencode($ref) !== $ref) && isset($branch->target->hash)) {
67
+ $ref = $branch->target->hash;
68
+ }
69
+
70
+ return new Puc_v4p11_Vcs_Reference(array(
71
+ 'name' => $ref,
72
+ 'updated' => $branch->target->date,
73
+ 'downloadUrl' => $this->getDownloadUrl($branch->name),
74
+ ));
75
+ }
76
+
77
+ /**
78
+ * Get a specific tag.
79
+ *
80
+ * @param string $tagName
81
+ * @return Puc_v4p11_Vcs_Reference|null
82
+ */
83
+ public function getTag($tagName) {
84
+ $tag = $this->api('/refs/tags/' . $tagName);
85
+ if ( is_wp_error($tag) || empty($tag) ) {
86
+ return null;
87
+ }
88
+
89
+ return new Puc_v4p11_Vcs_Reference(array(
90
+ 'name' => $tag->name,
91
+ 'version' => ltrim($tag->name, 'v'),
92
+ 'updated' => $tag->target->date,
93
+ 'downloadUrl' => $this->getDownloadUrl($tag->name),
94
+ ));
95
+ }
96
+
97
+ /**
98
+ * Get the tag that looks like the highest version number.
99
+ *
100
+ * @return Puc_v4p11_Vcs_Reference|null
101
+ */
102
+ public function getLatestTag() {
103
+ $tags = $this->api('/refs/tags?sort=-target.date');
104
+ if ( !isset($tags, $tags->values) || !is_array($tags->values) ) {
105
+ return null;
106
+ }
107
+
108
+ //Filter and sort the list of tags.
109
+ $versionTags = $this->sortTagsByVersion($tags->values);
110
+
111
+ //Return the first result.
112
+ if ( !empty($versionTags) ) {
113
+ $tag = $versionTags[0];
114
+ return new Puc_v4p11_Vcs_Reference(array(
115
+ 'name' => $tag->name,
116
+ 'version' => ltrim($tag->name, 'v'),
117
+ 'updated' => $tag->target->date,
118
+ 'downloadUrl' => $this->getDownloadUrl($tag->name),
119
+ ));
120
+ }
121
+ return null;
122
+ }
123
+
124
+ /**
125
+ * Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
126
+ *
127
+ * @param string $branch
128
+ * @return null|Puc_v4p11_Vcs_Reference
129
+ */
130
+ protected function getStableTag($branch) {
131
+ $remoteReadme = $this->getRemoteReadme($branch);
132
+ if ( !empty($remoteReadme['stable_tag']) ) {
133
+ $tag = $remoteReadme['stable_tag'];
134
+
135
+ //You can explicitly opt out of using tags by setting "Stable tag" to
136
+ //"trunk" or the name of the current branch.
137
+ if ( ($tag === $branch) || ($tag === 'trunk') ) {
138
+ return $this->getBranch($branch);
139
+ }
140
+
141
+ return $this->getTag($tag);
142
+ }
143
+
144
+ return null;
145
+ }
146
+
147
+ /**
148
+ * @param string $ref
149
+ * @return string
150
+ */
151
+ protected function getDownloadUrl($ref) {
152
+ return sprintf(
153
+ 'https://bitbucket.org/%s/%s/get/%s.zip',
154
+ $this->username,
155
+ $this->repository,
156
+ $ref
157
+ );
158
+ }
159
+
160
+ /**
161
+ * Get the contents of a file from a specific branch or tag.
162
+ *
163
+ * @param string $path File name.
164
+ * @param string $ref
165
+ * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
166
+ */
167
+ public function getRemoteFile($path, $ref = 'master') {
168
+ $response = $this->api('src/' . $ref . '/' . ltrim($path));
169
+ if ( is_wp_error($response) || !is_string($response) ) {
170
+ return null;
171
+ }
172
+ return $response;
173
+ }
174
+
175
+ /**
176
+ * Get the timestamp of the latest commit that changed the specified branch or tag.
177
+ *
178
+ * @param string $ref Reference name (e.g. branch or tag).
179
+ * @return string|null
180
+ */
181
+ public function getLatestCommitTime($ref) {
182
+ $response = $this->api('commits/' . $ref);
183
+ if ( isset($response->values, $response->values[0], $response->values[0]->date) ) {
184
+ return $response->values[0]->date;
185
+ }
186
+ return null;
187
+ }
188
+
189
+ /**
190
+ * Perform a BitBucket API 2.0 request.
191
+ *
192
+ * @param string $url
193
+ * @param string $version
194
+ * @return mixed|WP_Error
195
+ */
196
+ public function api($url, $version = '2.0') {
197
+ $url = ltrim($url, '/');
198
+ $isSrcResource = Puc_v4p11_Utils::startsWith($url, 'src/');
199
+
200
+ $url = implode('/', array(
201
+ 'https://api.bitbucket.org',
202
+ $version,
203
+ 'repositories',
204
+ $this->username,
205
+ $this->repository,
206
+ $url
207
+ ));
208
+ $baseUrl = $url;
209
+
210
+ if ( $this->oauth ) {
211
+ $url = $this->oauth->sign($url,'GET');
212
+ }
213
+
214
+ $options = array('timeout' => 10);
215
+ if ( !empty($this->httpFilterName) ) {
216
+ $options = apply_filters($this->httpFilterName, $options);
217
+ }
218
+ $response = wp_remote_get($url, $options);
219
+ if ( is_wp_error($response) ) {
220
+ do_action('puc_api_error', $response, null, $url, $this->slug);
221
+ return $response;
222
+ }
223
+
224
+ $code = wp_remote_retrieve_response_code($response);
225
+ $body = wp_remote_retrieve_body($response);
226
+ if ( $code === 200 ) {
227
+ if ( $isSrcResource ) {
228
+ //Most responses are JSON-encoded, but src resources just
229
+ //return raw file contents.
230
+ $document = $body;
231
+ } else {
232
+ $document = json_decode($body);
233
+ }
234
+ return $document;
235
+ }
236
+
237
+ $error = new WP_Error(
238
+ 'puc-bitbucket-http-error',
239
+ sprintf('BitBucket API error. Base URL: "%s", HTTP status code: %d.', $baseUrl, $code)
240
+ );
241
+ do_action('puc_api_error', $error, $response, $url, $this->slug);
242
+
243
+ return $error;
244
+ }
245
+
246
+ /**
247
+ * @param array $credentials
248
+ */
249
+ public function setAuthentication($credentials) {
250
+ parent::setAuthentication($credentials);
251
+
252
+ if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
253
+ $this->oauth = new Puc_v4p11_OAuthSignature(
254
+ $credentials['consumer_key'],
255
+ $credentials['consumer_secret']
256
+ );
257
+ } else {
258
+ $this->oauth = null;
259
+ }
260
+ }
261
+
262
+ public function signDownloadUrl($url) {
263
+ //Add authentication data to download URLs. Since OAuth signatures incorporate
264
+ //timestamps, we have to do this immediately before inserting the update. Otherwise
265
+ //authentication could fail due to a stale timestamp.
266
+ if ( $this->oauth ) {
267
+ $url = $this->oauth->sign($url);
268
+ }
269
+ return $url;
270
+ }
271
+ }
272
+
273
+ endif;
app/core/puc/Puc/v4p11/Vcs/GitHubApi.php ADDED
@@ -0,0 +1,441 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_Vcs_GitHubApi', false) ):
4
+
5
+ class Puc_v4p11_Vcs_GitHubApi extends Puc_v4p11_Vcs_Api {
6
+ /**
7
+ * @var string GitHub username.
8
+ */
9
+ protected $userName;
10
+ /**
11
+ * @var string GitHub repository name.
12
+ */
13
+ protected $repositoryName;
14
+
15
+ /**
16
+ * @var string Either a fully qualified repository URL, or just "user/repo-name".
17
+ */
18
+ protected $repositoryUrl;
19
+
20
+ /**
21
+ * @var string GitHub authentication token. Optional.
22
+ */
23
+ protected $accessToken;
24
+
25
+ /**
26
+ * @var bool Whether to download release assets instead of the auto-generated source code archives.
27
+ */
28
+ protected $releaseAssetsEnabled = false;
29
+
30
+ /**
31
+ * @var string|null Regular expression that's used to filter release assets by name. Optional.
32
+ */
33
+ protected $assetFilterRegex = null;
34
+
35
+ /**
36
+ * @var string|null The unchanging part of a release asset URL. Used to identify download attempts.
37
+ */
38
+ protected $assetApiBaseUrl = null;
39
+
40
+ /**
41
+ * @var bool
42
+ */
43
+ private $downloadFilterAdded = false;
44
+
45
+ public function __construct($repositoryUrl, $accessToken = null) {
46
+ $path = parse_url($repositoryUrl, PHP_URL_PATH);
47
+ if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
48
+ $this->userName = $matches['username'];
49
+ $this->repositoryName = $matches['repository'];
50
+ } else {
51
+ throw new InvalidArgumentException('Invalid GitHub repository URL: "' . $repositoryUrl . '"');
52
+ }
53
+
54
+ parent::__construct($repositoryUrl, $accessToken);
55
+ }
56
+
57
+ /**
58
+ * Get the latest release from GitHub.
59
+ *
60
+ * @return Puc_v4p11_Vcs_Reference|null
61
+ */
62
+ public function getLatestRelease() {
63
+ $release = $this->api('/repos/:user/:repo/releases/latest');
64
+ if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
65
+ return null;
66
+ }
67
+
68
+ $reference = new Puc_v4p11_Vcs_Reference(array(
69
+ 'name' => $release->tag_name,
70
+ 'version' => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
71
+ 'downloadUrl' => $release->zipball_url,
72
+ 'updated' => $release->created_at,
73
+ 'apiResponse' => $release,
74
+ ));
75
+
76
+ if ( isset($release->assets[0]) ) {
77
+ $reference->downloadCount = $release->assets[0]->download_count;
78
+ }
79
+
80
+ if ( $this->releaseAssetsEnabled && isset($release->assets, $release->assets[0]) ) {
81
+ //Use the first release asset that matches the specified regular expression.
82
+ $matchingAssets = array_filter($release->assets, array($this, 'matchesAssetFilter'));
83
+ if ( !empty($matchingAssets) ) {
84
+ if ( $this->isAuthenticationEnabled() ) {
85
+ /**
86
+ * Keep in mind that we'll need to add an "Accept" header to download this asset.
87
+ *
88
+ * @see setUpdateDownloadHeaders()
89
+ */
90
+ $reference->downloadUrl = $matchingAssets[0]->url;
91
+ } else {
92
+ //It seems that browser_download_url only works for public repositories.
93
+ //Using an access_token doesn't help. Maybe OAuth would work?
94
+ $reference->downloadUrl = $matchingAssets[0]->browser_download_url;
95
+ }
96
+
97
+ $reference->downloadCount = $matchingAssets[0]->download_count;
98
+ }
99
+ }
100
+
101
+ if ( !empty($release->body) ) {
102
+ /** @noinspection PhpUndefinedClassInspection */
103
+ $reference->changelog = Parsedown::instance()->text($release->body);
104
+ }
105
+
106
+ return $reference;
107
+ }
108
+
109
+ /**
110
+ * Get the tag that looks like the highest version number.
111
+ *
112
+ * @return Puc_v4p11_Vcs_Reference|null
113
+ */
114
+ public function getLatestTag() {
115
+ $tags = $this->api('/repos/:user/:repo/tags');
116
+
117
+ if ( is_wp_error($tags) || !is_array($tags) ) {
118
+ return null;
119
+ }
120
+
121
+ $versionTags = $this->sortTagsByVersion($tags);
122
+ if ( empty($versionTags) ) {
123
+ return null;
124
+ }
125
+
126
+ $tag = $versionTags[0];
127
+ return new Puc_v4p11_Vcs_Reference(array(
128
+ 'name' => $tag->name,
129
+ 'version' => ltrim($tag->name, 'v'),
130
+ 'downloadUrl' => $tag->zipball_url,
131
+ 'apiResponse' => $tag,
132
+ ));
133
+ }
134
+
135
+ /**
136
+ * Get a branch by name.
137
+ *
138
+ * @param string $branchName
139
+ * @return null|Puc_v4p11_Vcs_Reference
140
+ */
141
+ public function getBranch($branchName) {
142
+ $branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
143
+ if ( is_wp_error($branch) || empty($branch) ) {
144
+ return null;
145
+ }
146
+
147
+ $reference = new Puc_v4p11_Vcs_Reference(array(
148
+ 'name' => $branch->name,
149
+ 'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
150
+ 'apiResponse' => $branch,
151
+ ));
152
+
153
+ if ( isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date) ) {
154
+ $reference->updated = $branch->commit->commit->author->date;
155
+ }
156
+
157
+ return $reference;
158
+ }
159
+
160
+ /**
161
+ * Get the latest commit that changed the specified file.
162
+ *
163
+ * @param string $filename
164
+ * @param string $ref Reference name (e.g. branch or tag).
165
+ * @return StdClass|null
166
+ */
167
+ public function getLatestCommit($filename, $ref = 'master') {
168
+ $commits = $this->api(
169
+ '/repos/:user/:repo/commits',
170
+ array(
171
+ 'path' => $filename,
172
+ 'sha' => $ref,
173
+ )
174
+ );
175
+ if ( !is_wp_error($commits) && isset($commits[0]) ) {
176
+ return $commits[0];
177
+ }
178
+ return null;
179
+ }
180
+
181
+ /**
182
+ * Get the timestamp of the latest commit that changed the specified branch or tag.
183
+ *
184
+ * @param string $ref Reference name (e.g. branch or tag).
185
+ * @return string|null
186
+ */
187
+ public function getLatestCommitTime($ref) {
188
+ $commits = $this->api('/repos/:user/:repo/commits', array('sha' => $ref));
189
+ if ( !is_wp_error($commits) && isset($commits[0]) ) {
190
+ return $commits[0]->commit->author->date;
191
+ }
192
+ return null;
193
+ }
194
+
195
+ /**
196
+ * Perform a GitHub API request.
197
+ *
198
+ * @param string $url
199
+ * @param array $queryParams
200
+ * @return mixed|WP_Error
201
+ */
202
+ protected function api($url, $queryParams = array()) {
203
+ $baseUrl = $url;
204
+ $url = $this->buildApiUrl($url, $queryParams);
205
+
206
+ $options = array('timeout' => 10);
207
+ if ( $this->isAuthenticationEnabled() ) {
208
+ $options['headers'] = array('Authorization' => $this->getAuthorizationHeader());
209
+ }
210
+
211
+ if ( !empty($this->httpFilterName) ) {
212
+ $options = apply_filters($this->httpFilterName, $options);
213
+ }
214
+ $response = wp_remote_get($url, $options);
215
+ if ( is_wp_error($response) ) {
216
+ do_action('puc_api_error', $response, null, $url, $this->slug);
217
+ return $response;
218
+ }
219
+
220
+ $code = wp_remote_retrieve_response_code($response);
221
+ $body = wp_remote_retrieve_body($response);
222
+ if ( $code === 200 ) {
223
+ $document = json_decode($body);
224
+ return $document;
225
+ }
226
+
227
+ $error = new WP_Error(
228
+ 'puc-github-http-error',
229
+ sprintf('GitHub API error. Base URL: "%s", HTTP status code: %d.', $baseUrl, $code)
230
+ );
231
+ do_action('puc_api_error', $error, $response, $url, $this->slug);
232
+
233
+ return $error;
234
+ }
235
+
236
+ /**
237
+ * Build a fully qualified URL for an API request.
238
+ *
239
+ * @param string $url
240
+ * @param array $queryParams
241
+ * @return string
242
+ */
243
+ protected function buildApiUrl($url, $queryParams) {
244
+ $variables = array(
245
+ 'user' => $this->userName,
246
+ 'repo' => $this->repositoryName,
247
+ );
248
+ foreach ($variables as $name => $value) {
249
+ $url = str_replace('/:' . $name, '/' . urlencode($value), $url);
250
+ }
251
+ $url = 'https://api.github.com' . $url;
252
+
253
+ if ( !empty($queryParams) ) {
254
+ $url = add_query_arg($queryParams, $url);
255
+ }
256
+
257
+ return $url;
258
+ }
259
+
260
+ /**
261
+ * Get the contents of a file from a specific branch or tag.
262
+ *
263
+ * @param string $path File name.
264
+ * @param string $ref
265
+ * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
266
+ */
267
+ public function getRemoteFile($path, $ref = 'master') {
268
+ $apiUrl = '/repos/:user/:repo/contents/' . $path;
269
+ $response = $this->api($apiUrl, array('ref' => $ref));
270
+
271
+ if ( is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64') ) {
272
+ return null;
273
+ }
274
+ return base64_decode($response->content);
275
+ }
276
+
277
+ /**
278
+ * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
279
+ *
280
+ * @param string $ref
281
+ * @return string
282
+ */
283
+ public function buildArchiveDownloadUrl($ref = 'master') {
284
+ $url = sprintf(
285
+ 'https://api.github.com/repos/%1$s/%2$s/zipball/%3$s',
286
+ urlencode($this->userName),
287
+ urlencode($this->repositoryName),
288
+ urlencode($ref)
289
+ );
290
+ return $url;
291
+ }
292
+
293
+ /**
294
+ * Get a specific tag.
295
+ *
296
+ * @param string $tagName
297
+ * @return void
298
+ */
299
+ public function getTag($tagName) {
300
+ //The current GitHub update checker doesn't use getTag, so I didn't bother to implement it.
301
+ throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
302
+ }
303
+
304
+ public function setAuthentication($credentials) {
305
+ parent::setAuthentication($credentials);
306
+ $this->accessToken = is_string($credentials) ? $credentials : null;
307
+
308
+ //Optimization: Instead of filtering all HTTP requests, let's do it only when
309
+ //WordPress is about to download an update.
310
+ add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
311
+ }
312
+
313
+ /**
314
+ * Figure out which reference (i.e tag or branch) contains the latest version.
315
+ *
316
+ * @param string $configBranch Start looking in this branch.
317
+ * @return null|Puc_v4p11_Vcs_Reference
318
+ */
319
+ public function chooseReference($configBranch) {
320
+ $updateSource = null;
321
+
322
+ if ( $configBranch === 'master' ) {
323
+ //Use the latest release.
324
+ $updateSource = $this->getLatestRelease();
325
+ if ( $updateSource === null ) {
326
+ //Failing that, use the tag with the highest version number.
327
+ $updateSource = $this->getLatestTag();
328
+ }
329
+ }
330
+ //Alternatively, just use the branch itself.
331
+ if ( empty($updateSource) ) {
332
+ $updateSource = $this->getBranch($configBranch);
333
+ }
334
+
335
+ return $updateSource;
336
+ }
337
+
338
+ /**
339
+ * Enable updating via release assets.
340
+ *
341
+ * If the latest release contains no usable assets, the update checker
342
+ * will fall back to using the automatically generated ZIP archive.
343
+ *
344
+ * Private repositories will only work with WordPress 3.7 or later.
345
+ *
346
+ * @param string|null $fileNameRegex Optional. Use only those assets where the file name matches this regex.
347
+ */
348
+ public function enableReleaseAssets($fileNameRegex = null) {
349
+ $this->releaseAssetsEnabled = true;
350
+ $this->assetFilterRegex = $fileNameRegex;
351
+ $this->assetApiBaseUrl = sprintf(
352
+ '//api.github.com/repos/%1$s/%2$s/releases/assets/',
353
+ $this->userName,
354
+ $this->repositoryName
355
+ );
356
+ }
357
+
358
+ /**
359
+ * Does this asset match the file name regex?
360
+ *
361
+ * @param stdClass $releaseAsset
362
+ * @return bool
363
+ */
364
+ protected function matchesAssetFilter($releaseAsset) {
365
+ if ( $this->assetFilterRegex === null ) {
366
+ //The default is to accept all assets.
367
+ return true;
368
+ }
369
+ return isset($releaseAsset->name) && preg_match($this->assetFilterRegex, $releaseAsset->name);
370
+ }
371
+
372
+ /**
373
+ * @internal
374
+ * @param bool $result
375
+ * @return bool
376
+ */
377
+ public function addHttpRequestFilter($result) {
378
+ if ( !$this->downloadFilterAdded && $this->isAuthenticationEnabled() ) {
379
+ add_filter('http_request_args', array($this, 'setUpdateDownloadHeaders'), 10, 2);
380
+ add_action('requests-requests.before_redirect', array($this, 'removeAuthHeaderFromRedirects'), 10, 4);
381
+ $this->downloadFilterAdded = true;
382
+ }
383
+ return $result;
384
+ }
385
+
386
+ /**
387
+ * Set the HTTP headers that are necessary to download updates from private repositories.
388
+ *
389
+ * See GitHub docs:
390
+ * @link https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
391
+ * @link https://developer.github.com/v3/auth/#basic-authentication
392
+ *
393
+ * @internal
394
+ * @param array $requestArgs
395
+ * @param string $url
396
+ * @return array
397
+ */
398
+ public function setUpdateDownloadHeaders($requestArgs, $url = '') {
399
+ //Is WordPress trying to download one of our release assets?
400
+ if ( $this->releaseAssetsEnabled && (strpos($url, $this->assetApiBaseUrl) !== false) ) {
401
+ $requestArgs['headers']['Accept'] = 'application/octet-stream';
402
+ }
403
+ //Use Basic authentication, but only if the download is from our repository.
404
+ $repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
405
+ if ( $this->isAuthenticationEnabled() && (strpos($url, $repoApiBaseUrl)) === 0 ) {
406
+ $requestArgs['headers']['Authorization'] = $this->getAuthorizationHeader();
407
+ }
408
+ return $requestArgs;
409
+ }
410
+
411
+ /**
412
+ * When following a redirect, the Requests library will automatically forward
413
+ * the authorization header to other hosts. We don't want that because it breaks
414
+ * AWS downloads and can leak authorization information.
415
+ *
416
+ * @internal
417
+ * @param string $location
418
+ * @param array $headers
419
+ */
420
+ public function removeAuthHeaderFromRedirects(&$location, &$headers) {
421
+ $repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
422
+ if ( strpos($location, $repoApiBaseUrl) === 0 ) {
423
+ return; //This request is going to GitHub, so it's fine.
424
+ }
425
+ //Remove the header.
426
+ if ( isset($headers['Authorization']) ) {
427
+ unset($headers['Authorization']);
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Generate the value of the "Authorization" header.
433
+ *
434
+ * @return string
435
+ */
436
+ protected function getAuthorizationHeader() {
437
+ return 'Basic ' . base64_encode($this->userName . ':' . $this->accessToken);
438
+ }
439
+ }
440
+
441
+ endif;
app/core/puc/Puc/v4p11/Vcs/GitLabApi.php ADDED
@@ -0,0 +1,399 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_Vcs_GitLabApi', false) ):
4
+
5
+ class Puc_v4p11_Vcs_GitLabApi extends Puc_v4p11_Vcs_Api {
6
+ /**
7
+ * @var string GitLab username.
8
+ */
9
+ protected $userName;
10
+
11
+ /**
12
+ * @var string GitLab server host.
13
+ */
14
+ protected $repositoryHost;
15
+
16
+ /**
17
+ * @var string Protocol used by this GitLab server: "http" or "https".
18
+ */
19
+ protected $repositoryProtocol = 'https';
20
+
21
+ /**
22
+ * @var string GitLab repository name.
23
+ */
24
+ protected $repositoryName;
25
+
26
+ /**
27
+ * @var string GitLab authentication token. Optional.
28
+ */
29
+ protected $accessToken;
30
+
31
+ /**
32
+ * @var bool Whether to download release assets instead of the auto-generated source code archives.
33
+ */
34
+ protected $releaseAssetsEnabled = false;
35
+
36
+ /**
37
+ * @var bool Whether to download release asset package rather than release asset source.
38
+ */
39
+ protected $releasePackageEnabled = false;
40
+
41
+ public function __construct($repositoryUrl, $accessToken = null, $subgroup = null) {
42
+ //Parse the repository host to support custom hosts.
43
+ $port = parse_url($repositoryUrl, PHP_URL_PORT);
44
+ if ( !empty($port) ) {
45
+ $port = ':' . $port;
46
+ }
47
+ $this->repositoryHost = parse_url($repositoryUrl, PHP_URL_HOST) . $port;
48
+
49
+ if ( $this->repositoryHost !== 'gitlab.com' ) {
50
+ $this->repositoryProtocol = parse_url($repositoryUrl, PHP_URL_SCHEME);
51
+ }
52
+
53
+ //Find the repository information
54
+ $path = parse_url($repositoryUrl, PHP_URL_PATH);
55
+ if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
56
+ $this->userName = $matches['username'];
57
+ $this->repositoryName = $matches['repository'];
58
+ } elseif ( ($this->repositoryHost === 'gitlab.com') ) {
59
+ //This is probably a repository in a subgroup, e.g. "/organization/category/repo".
60
+ $parts = explode('/', trim($path, '/'));
61
+ if ( count($parts) < 3 ) {
62
+ throw new InvalidArgumentException('Invalid GitLab.com repository URL: "' . $repositoryUrl . '"');
63
+ }
64
+ $lastPart = array_pop($parts);
65
+ $this->userName = implode('/', $parts);
66
+ $this->repositoryName = $lastPart;
67
+ } else {
68
+ //There could be subgroups in the URL: gitlab.domain.com/group/subgroup/subgroup2/repository
69
+ if ( $subgroup !== null ) {
70
+ $path = str_replace(trailingslashit($subgroup), '', $path);
71
+ }
72
+
73
+ //This is not a traditional url, it could be gitlab is in a deeper subdirectory.
74
+ //Get the path segments.
75
+ $segments = explode('/', untrailingslashit(ltrim($path, '/')));
76
+
77
+ //We need at least /user-name/repository-name/
78
+ if ( count($segments) < 2 ) {
79
+ throw new InvalidArgumentException('Invalid GitLab repository URL: "' . $repositoryUrl . '"');
80
+ }
81
+
82
+ //Get the username and repository name.
83
+ $usernameRepo = array_splice($segments, -2, 2);
84
+ $this->userName = $usernameRepo[0];
85
+ $this->repositoryName = $usernameRepo[1];
86
+
87
+ //Append the remaining segments to the host if there are segments left.
88
+ if ( count($segments) > 0 ) {
89
+ $this->repositoryHost = trailingslashit($this->repositoryHost) . implode('/', $segments);
90
+ }
91
+
92
+ //Add subgroups to username.
93
+ if ( $subgroup !== null ) {
94
+ $this->userName = $usernameRepo[0] . '/' . untrailingslashit($subgroup);
95
+ }
96
+ }
97
+
98
+ parent::__construct($repositoryUrl, $accessToken);
99
+ }
100
+
101
+ /**
102
+ * Get the latest release from GitLab.
103
+ *
104
+ * @return Puc_v4p11_Vcs_Reference|null
105
+ */
106
+ public function getLatestRelease() {
107
+ $releases = $this->api('/:id/releases');
108
+ if ( is_wp_error($releases) || empty($releases) || !is_array($releases) ) {
109
+ return null;
110
+ }
111
+
112
+ foreach ($releases as $release) {
113
+ if ( true !== $release->upcoming_release ) {
114
+ break 1; //Break the loop on the first release we find that isn't an upcoming release
115
+ }
116
+ }
117
+ if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
118
+ return null;
119
+ }
120
+
121
+ $reference = new Puc_v4p11_Vcs_Reference(array(
122
+ 'name' => $release->tag_name,
123
+ 'version' => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
124
+ 'downloadUrl' => '',
125
+ 'updated' => $release->released_at,
126
+ 'apiResponse' => $release,
127
+ ));
128
+ $download_url = false;
129
+
130
+ if ( $this->releasePackageEnabled && isset($release->assets, $release->assets->links) ) {
131
+ /**
132
+ * Use the first asset LINK that is a zip format file generated by a Gitlab Release Pipeline
133
+ *
134
+ * @link https://gist.github.com/timwiel/9dfd3526c768efad4973254085e065ce
135
+ */
136
+ foreach ($release->assets->links as $link) {
137
+ if ( 'zip' === substr($link->url, -3) ) {
138
+ $download_url = $link->url;
139
+ break 1;
140
+ }
141
+ }
142
+ if ( empty( $download_url ) ) {
143
+ return null;
144
+ }
145
+ if ( ! empty( $this->accessToken ) ) {
146
+ $download_url = add_query_arg('private_token', $this->accessToken, $download_url);
147
+ }
148
+ $reference->downloadUrl = $download_url;
149
+ return $reference;
150
+
151
+ } elseif ( isset($release->assets) ) {
152
+ /**
153
+ * Use the first asset SOURCE file that is a zip format from a Gitlab Release which should be a zip file
154
+ */
155
+ foreach ($release->assets->sources as $source) {
156
+ if ( 'zip' === $source->format ) {
157
+ $download_url = $source->url;
158
+ break 1;
159
+ }
160
+ }
161
+ if ( empty( $download_url ) ) {
162
+ return null;
163
+ }
164
+ if ( ! empty( $this->accessToken ) ) {
165
+ $download_url = add_query_arg('private_token', $this->accessToken, $download_url);
166
+ }
167
+ $reference->downloadUrl = $download_url;
168
+ return $reference;
169
+
170
+ }
171
+
172
+ //If we get this far without a return then obviosuly noi release download urls were found
173
+ return null;
174
+ }
175
+
176
+ /**
177
+ * Get the tag that looks like the highest version number.
178
+ *
179
+ * @return Puc_v4p11_Vcs_Reference|null
180
+ */
181
+ public function getLatestTag() {
182
+ $tags = $this->api('/:id/repository/tags');
183
+ if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
184
+ return null;
185
+ }
186
+
187
+ $versionTags = $this->sortTagsByVersion($tags);
188
+ if ( empty($versionTags) ) {
189
+ return null;
190
+ }
191
+
192
+ $tag = $versionTags[0];
193
+ return new Puc_v4p11_Vcs_Reference(array(
194
+ 'name' => $tag->name,
195
+ 'version' => ltrim($tag->name, 'v'),
196
+ 'downloadUrl' => $this->buildArchiveDownloadUrl($tag->name),
197
+ 'apiResponse' => $tag,
198
+ ));
199
+ }
200
+
201
+ /**
202
+ * Get a branch by name.
203
+ *
204
+ * @param string $branchName
205
+ * @return null|Puc_v4p11_Vcs_Reference
206
+ */
207
+ public function getBranch($branchName) {
208
+ $branch = $this->api('/:id/repository/branches/' . $branchName);
209
+ if ( is_wp_error($branch) || empty($branch) ) {
210
+ return null;
211
+ }
212
+
213
+ $reference = new Puc_v4p11_Vcs_Reference(array(
214
+ 'name' => $branch->name,
215
+ 'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
216
+ 'apiResponse' => $branch,
217
+ ));
218
+
219
+ if ( isset($branch->commit, $branch->commit->committed_date) ) {
220
+ $reference->updated = $branch->commit->committed_date;
221
+ }
222
+
223
+ return $reference;
224
+ }
225
+
226
+ /**
227
+ * Get the timestamp of the latest commit that changed the specified branch or tag.
228
+ *
229
+ * @param string $ref Reference name (e.g. branch or tag).
230
+ * @return string|null
231
+ */
232
+ public function getLatestCommitTime($ref) {
233
+ $commits = $this->api('/:id/repository/commits/', array('ref_name' => $ref));
234
+ if ( is_wp_error($commits) || !is_array($commits) || !isset($commits[0]) ) {
235
+ return null;
236
+ }
237
+
238
+ return $commits[0]->committed_date;
239
+ }
240
+
241
+ /**
242
+ * Perform a GitLab API request.
243
+ *
244
+ * @param string $url
245
+ * @param array $queryParams
246
+ * @return mixed|WP_Error
247
+ */
248
+ protected function api($url, $queryParams = array()) {
249
+ $baseUrl = $url;
250
+ $url = $this->buildApiUrl($url, $queryParams);
251
+
252
+ $options = array('timeout' => 10);
253
+ if ( !empty($this->httpFilterName) ) {
254
+ $options = apply_filters($this->httpFilterName, $options);
255
+ }
256
+
257
+ $response = wp_remote_get($url, $options);
258
+ if ( is_wp_error($response) ) {
259
+ do_action('puc_api_error', $response, null, $url, $this->slug);
260
+ return $response;
261
+ }
262
+
263
+ $code = wp_remote_retrieve_response_code($response);
264
+ $body = wp_remote_retrieve_body($response);
265
+ if ( $code === 200 ) {
266
+ return json_decode($body);
267
+ }
268
+
269
+ $error = new WP_Error(
270
+ 'puc-gitlab-http-error',
271
+ sprintf('GitLab API error. URL: "%s", HTTP status code: %d.', $baseUrl, $code)
272
+ );
273
+ do_action('puc_api_error', $error, $response, $url, $this->slug);
274
+
275
+ return $error;
276
+ }
277
+
278
+ /**
279
+ * Build a fully qualified URL for an API request.
280
+ *
281
+ * @param string $url
282
+ * @param array $queryParams
283
+ * @return string
284
+ */
285
+ protected function buildApiUrl($url, $queryParams) {
286
+ $variables = array(
287
+ 'user' => $this->userName,
288
+ 'repo' => $this->repositoryName,
289
+ 'id' => $this->userName . '/' . $this->repositoryName,
290
+ );
291
+
292
+ foreach ($variables as $name => $value) {
293
+ $url = str_replace("/:{$name}", '/' . urlencode($value), $url);
294
+ }
295
+
296
+ $url = substr($url, 1);
297
+ $url = sprintf('%1$s://%2$s/api/v4/projects/%3$s', $this->repositoryProtocol, $this->repositoryHost, $url);
298
+
299
+ if ( !empty($this->accessToken) ) {
300
+ $queryParams['private_token'] = $this->accessToken;
301
+ }
302
+
303
+ if ( !empty($queryParams) ) {
304
+ $url = add_query_arg($queryParams, $url);
305
+ }
306
+
307
+ return $url;
308
+ }
309
+
310
+ /**
311
+ * Get the contents of a file from a specific branch or tag.
312
+ *
313
+ * @param string $path File name.
314
+ * @param string $ref
315
+ * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
316
+ */
317
+ public function getRemoteFile($path, $ref = 'master') {
318
+ $response = $this->api('/:id/repository/files/' . $path, array('ref' => $ref));
319
+ if ( is_wp_error($response) || !isset($response->content) || $response->encoding !== 'base64' ) {
320
+ return null;
321
+ }
322
+
323
+ return base64_decode($response->content);
324
+ }
325
+
326
+ /**
327
+ * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
328
+ *
329
+ * @param string $ref
330
+ * @return string
331
+ */
332
+ public function buildArchiveDownloadUrl($ref = 'master') {
333
+ $url = sprintf(
334
+ '%1$s://%2$s/api/v4/projects/%3$s/repository/archive.zip',
335
+ $this->repositoryProtocol,
336
+ $this->repositoryHost,
337
+ urlencode($this->userName . '/' . $this->repositoryName)
338
+ );
339
+ $url = add_query_arg('sha', urlencode($ref), $url);
340
+
341
+ if ( !empty($this->accessToken) ) {
342
+ $url = add_query_arg('private_token', $this->accessToken, $url);
343
+ }
344
+
345
+ return $url;
346
+ }
347
+
348
+ /**
349
+ * Get a specific tag.
350
+ *
351
+ * @param string $tagName
352
+ * @return void
353
+ */
354
+ public function getTag($tagName) {
355
+ throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
356
+ }
357
+
358
+ /**
359
+ * Figure out which reference (i.e tag or branch) contains the latest version.
360
+ *
361
+ * @param string $configBranch Start looking in this branch.
362
+ * @return null|Puc_v4p11_Vcs_Reference
363
+ */
364
+ public function chooseReference($configBranch) {
365
+
366
+ if ( $configBranch === 'main' || $configBranch === 'master' ) {
367
+ //Use the latest release.
368
+ $updateSource = $this->getLatestRelease();
369
+ if ( $updateSource === null ) {
370
+ //Failing that, use the tag with the highest version number.
371
+ $updateSource = $this->getLatestTag();
372
+ }
373
+ }
374
+ //Alternatively, just use the branch itself.
375
+ if ( empty($updateSource) ) {
376
+ $updateSource = $this->getBranch($configBranch);
377
+ }
378
+
379
+ return $updateSource;
380
+ }
381
+
382
+ public function setAuthentication($credentials) {
383
+ parent::setAuthentication($credentials);
384
+ $this->accessToken = is_string($credentials) ? $credentials : null;
385
+ }
386
+
387
+ public function enableReleaseAssets() {
388
+ $this->releaseAssetsEnabled = true;
389
+ $this->releasePackageEnabled = false;
390
+ }
391
+
392
+ public function enableReleasePackages() {
393
+ $this->releaseAssetsEnabled = false;
394
+ $this->releasePackageEnabled = true;
395
+ }
396
+
397
+ }
398
+
399
+ endif;
app/core/puc/Puc/v4p11/Vcs/PluginUpdateChecker.php ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Vcs_PluginUpdateChecker') ):
3
+
4
+ class Puc_v4p11_Vcs_PluginUpdateChecker extends Puc_v4p11_Plugin_UpdateChecker implements Puc_v4p11_Vcs_BaseChecker {
5
+ /**
6
+ * @var string The branch where to look for updates. Defaults to "master".
7
+ */
8
+ protected $branch = 'master';
9
+
10
+ /**
11
+ * @var Puc_v4p11_Vcs_Api Repository API client.
12
+ */
13
+ protected $api = null;
14
+
15
+ /**
16
+ * Puc_v4p11_Vcs_PluginUpdateChecker constructor.
17
+ *
18
+ * @param Puc_v4p11_Vcs_Api $api
19
+ * @param string $pluginFile
20
+ * @param string $slug
21
+ * @param int $checkPeriod
22
+ * @param string $optionName
23
+ * @param string $muPluginFile
24
+ */
25
+ public function __construct($api, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
26
+ $this->api = $api;
27
+ $this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
28
+
29
+ parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
30
+
31
+ $this->api->setSlug($this->slug);
32
+ }
33
+
34
+ public function requestInfo($unusedParameter = null) {
35
+ //We have to make several remote API requests to gather all the necessary info
36
+ //which can take a while on slow networks.
37
+ if ( function_exists('set_time_limit') ) {
38
+ @set_time_limit(60);
39
+ }
40
+
41
+ $api = $this->api;
42
+ $api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
43
+
44
+ $info = new Puc_v4p11_Plugin_Info();
45
+ $info->filename = $this->pluginFile;
46
+ $info->slug = $this->slug;
47
+
48
+ $this->setInfoFromHeader($this->package->getPluginHeader(), $info);
49
+ $this->setIconsFromLocalAssets($info);
50
+ $this->setBannersFromLocalAssets($info);
51
+
52
+ //Pick a branch or tag.
53
+ $updateSource = $api->chooseReference($this->branch);
54
+ if ( $updateSource ) {
55
+ $ref = $updateSource->name;
56
+ $info->version = $updateSource->version;
57
+ $info->last_updated = $updateSource->updated;
58
+ $info->download_url = $updateSource->downloadUrl;
59
+
60
+ if ( !empty($updateSource->changelog) ) {
61
+ $info->sections['changelog'] = $updateSource->changelog;
62
+ }
63
+ if ( isset($updateSource->downloadCount) ) {
64
+ $info->downloaded = $updateSource->downloadCount;
65
+ }
66
+ } else {
67
+ //There's probably a network problem or an authentication error.
68
+ do_action(
69
+ 'puc_api_error',
70
+ new WP_Error(
71
+ 'puc-no-update-source',
72
+ 'Could not retrieve version information from the repository. '
73
+ . 'This usually means that the update checker either can\'t connect '
74
+ . 'to the repository or it\'s configured incorrectly.'
75
+ ),
76
+ null, null, $this->slug
77
+ );
78
+ return null;
79
+ }
80
+
81
+ //Get headers from the main plugin file in this branch/tag. Its "Version" header and other metadata
82
+ //are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
83
+ $mainPluginFile = basename($this->pluginFile);
84
+ $remotePlugin = $api->getRemoteFile($mainPluginFile, $ref);
85
+ if ( !empty($remotePlugin) ) {
86
+ $remoteHeader = $this->package->getFileHeader($remotePlugin);
87
+ $this->setInfoFromHeader($remoteHeader, $info);
88
+ }
89
+
90
+ //Try parsing readme.txt. If it's formatted according to WordPress.org standards, it will contain
91
+ //a lot of useful information like the required/tested WP version, changelog, and so on.
92
+ if ( $this->readmeTxtExistsLocally() ) {
93
+ $this->setInfoFromRemoteReadme($ref, $info);
94
+ }
95
+
96
+ //The changelog might be in a separate file.
97
+ if ( empty($info->sections['changelog']) ) {
98
+ $info->sections['changelog'] = $api->getRemoteChangelog($ref, $this->package->getAbsoluteDirectoryPath());
99
+ if ( empty($info->sections['changelog']) ) {
100
+ $info->sections['changelog'] = __('There is no changelog available.', 'plugin-update-checker');
101
+ }
102
+ }
103
+
104
+ if ( empty($info->last_updated) ) {
105
+ //Fetch the latest commit that changed the tag or branch and use it as the "last_updated" date.
106
+ $latestCommitTime = $api->getLatestCommitTime($ref);
107
+ if ( $latestCommitTime !== null ) {
108
+ $info->last_updated = $latestCommitTime;
109
+ }
110
+ }
111
+
112
+ $info = apply_filters($this->getUniqueName('request_info_result'), $info, null);
113
+ return $info;
114
+ }
115
+
116
+ /**
117
+ * Check if the currently installed version has a readme.txt file.
118
+ *
119
+ * @return bool
120
+ */
121
+ protected function readmeTxtExistsLocally() {
122
+ return $this->package->fileExists($this->api->getLocalReadmeName());
123
+ }
124
+
125
+ /**
126
+ * Copy plugin metadata from a file header to a Plugin Info object.
127
+ *
128
+ * @param array $fileHeader
129
+ * @param Puc_v4p11_Plugin_Info $pluginInfo
130
+ */
131
+ protected function setInfoFromHeader($fileHeader, $pluginInfo) {
132
+ $headerToPropertyMap = array(
133
+ 'Version' => 'version',
134
+ 'Name' => 'name',
135
+ 'PluginURI' => 'homepage',
136
+ 'Author' => 'author',
137
+ 'AuthorName' => 'author',
138
+ 'AuthorURI' => 'author_homepage',
139
+
140
+ 'Requires WP' => 'requires',
141
+ 'Tested WP' => 'tested',
142
+ 'Requires at least' => 'requires',
143
+ 'Tested up to' => 'tested',
144
+
145
+ 'Requires PHP' => 'requires_php',
146
+ );
147
+ foreach ($headerToPropertyMap as $headerName => $property) {
148
+ if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
149
+ $pluginInfo->$property = $fileHeader[$headerName];
150
+ }
151
+ }
152
+
153
+ if ( !empty($fileHeader['Description']) ) {
154
+ $pluginInfo->sections['description'] = $fileHeader['Description'];
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Copy plugin metadata from the remote readme.txt file.
160
+ *
161
+ * @param string $ref GitHub tag or branch where to look for the readme.
162
+ * @param Puc_v4p11_Plugin_Info $pluginInfo
163
+ */
164
+ protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
165
+ $readme = $this->api->getRemoteReadme($ref);
166
+ if ( empty($readme) ) {
167
+ return;
168
+ }
169
+
170
+ if ( isset($readme['sections']) ) {
171
+ $pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
172
+ }
173
+ if ( !empty($readme['tested_up_to']) ) {
174
+ $pluginInfo->tested = $readme['tested_up_to'];
175
+ }
176
+ if ( !empty($readme['requires_at_least']) ) {
177
+ $pluginInfo->requires = $readme['requires_at_least'];
178
+ }
179
+ if ( !empty($readme['requires_php']) ) {
180
+ $pluginInfo->requires_php = $readme['requires_php'];
181
+ }
182
+
183
+ if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
184
+ $pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Add icons from the currently installed version to a Plugin Info object.
190
+ *
191
+ * The icons should be in a subdirectory named "assets". Supported image formats
192
+ * and file names are described here:
193
+ * @link https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-icons
194
+ *
195
+ * @param Puc_v4p11_Plugin_Info $pluginInfo
196
+ */
197
+ protected function setIconsFromLocalAssets($pluginInfo) {
198
+ $icons = $this->getLocalAssetUrls(array(
199
+ 'icon.svg' => 'svg',
200
+ 'icon-256x256.png' => '2x',
201
+ 'icon-256x256.jpg' => '2x',
202
+ 'icon-128x128.png' => '1x',
203
+ 'icon-128x128.jpg' => '1x',
204
+ ));
205
+
206
+ if ( !empty($icons) ) {
207
+ //The "default" key seems to be used only as last-resort fallback in WP core (5.8/5.9),
208
+ //but we'll set it anyway in case some code somewhere needs it.
209
+ reset($icons);
210
+ $firstKey = key($icons);
211
+ $icons['default'] = $icons[$firstKey];
212
+
213
+ $pluginInfo->icons = $icons;
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Add banners from the currently installed version to a Plugin Info object.
219
+ *
220
+ * The banners should be in a subdirectory named "assets". Supported image formats
221
+ * and file names are described here:
222
+ * @link https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-headers
223
+ *
224
+ * @param Puc_v4p11_Plugin_Info $pluginInfo
225
+ */
226
+ protected function setBannersFromLocalAssets($pluginInfo) {
227
+ $banners = $this->getLocalAssetUrls(array(
228
+ 'banner-772x250.png' => 'high',
229
+ 'banner-772x250.jpg' => 'high',
230
+ 'banner-1544x500.png' => 'low',
231
+ 'banner-1544x500.jpg' => 'low',
232
+ ));
233
+
234
+ if ( !empty($banners) ) {
235
+ $pluginInfo->banners = $banners;
236
+ }
237
+ }
238
+
239
+ /**
240
+ * @param array<string, string> $filesToKeys
241
+ * @return array<string, string>
242
+ */
243
+ protected function getLocalAssetUrls($filesToKeys) {
244
+ $assetDirectory = $this->package->getAbsoluteDirectoryPath() . DIRECTORY_SEPARATOR . 'assets';
245
+ if ( !is_dir($assetDirectory) ) {
246
+ return array();
247
+ }
248
+ $assetBaseUrl = trailingslashit(plugins_url('', $assetDirectory . '/imaginary.file'));
249
+
250
+ $foundAssets = array();
251
+ foreach ($filesToKeys as $fileName => $key) {
252
+ $fullBannerPath = $assetDirectory . DIRECTORY_SEPARATOR . $fileName;
253
+ if ( !isset($icons[$key]) && is_file($fullBannerPath) ) {
254
+ $foundAssets[$key] = $assetBaseUrl . $fileName;
255
+ }
256
+ }
257
+
258
+ return $foundAssets;
259
+ }
260
+
261
+ public function setBranch($branch) {
262
+ $this->branch = $branch;
263
+ return $this;
264
+ }
265
+
266
+ public function setAuthentication($credentials) {
267
+ $this->api->setAuthentication($credentials);
268
+ return $this;
269
+ }
270
+
271
+ public function getVcsApi() {
272
+ return $this->api;
273
+ }
274
+
275
+ public function getUpdate() {
276
+ $update = parent::getUpdate();
277
+
278
+ if ( isset($update) && !empty($update->download_url) ) {
279
+ $update->download_url = $this->api->signDownloadUrl($update->download_url);
280
+ }
281
+
282
+ return $update;
283
+ }
284
+
285
+ public function onDisplayConfiguration($panel) {
286
+ parent::onDisplayConfiguration($panel);
287
+ $panel->row('Branch', $this->branch);
288
+ $panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
289
+ $panel->row('API client', get_class($this->api));
290
+ }
291
+ }
292
+
293
+ endif;
app/core/puc/Puc/v4p11/Vcs/Reference.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Puc_v4p11_Vcs_Reference', false) ):
3
+
4
+ /**
5
+ * This class represents a VCS branch or tag. It's intended as a read only, short-lived container
6
+ * that only exists to provide a limited degree of type checking.
7
+ *
8
+ * @property string $name
9
+ * @property string|null version
10
+ * @property string $downloadUrl
11
+ * @property string $updated
12
+ *
13
+ * @property string|null $changelog
14
+ * @property int|null $downloadCount
15
+ */
16
+ class Puc_v4p11_Vcs_Reference {
17
+ private $properties = array();
18
+
19
+ public function __construct($properties = array()) {
20
+ $this->properties = $properties;
21
+ }
22
+
23
+ /**
24
+ * @param string $name
25
+ * @return mixed|null
26
+ */
27
+ public function __get($name) {
28
+ return array_key_exists($name, $this->properties) ? $this->properties[$name] : null;
29
+ }
30
+
31
+ /**
32
+ * @param string $name
33
+ * @param mixed $value
34
+ */
35
+ public function __set($name, $value) {
36
+ $this->properties[$name] = $value;
37
+ }
38
+
39
+ /**
40
+ * @param string $name
41
+ * @return bool
42
+ */
43
+ public function __isset($name) {
44
+ return isset($this->properties[$name]);
45
+ }
46
+
47
+ }
48
+
49
+ endif;
app/core/puc/Puc/v4p11/Vcs/ThemeUpdateChecker.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('Puc_v4p11_Vcs_ThemeUpdateChecker', false) ):
4
+
5
+ class Puc_v4p11_Vcs_ThemeUpdateChecker extends Puc_v4p11_Theme_UpdateChecker implements Puc_v4p11_Vcs_BaseChecker {
6
+ /**
7
+ * @var string The branch where to look for updates. Defaults to "master".
8
+ */
9
+ protected $branch = 'master';
10
+
11
+ /**
12
+ * @var Puc_v4p11_Vcs_Api Repository API client.
13
+ */
14
+ protected $api = null;
15
+
16
+ /**
17
+ * Puc_v4p11_Vcs_ThemeUpdateChecker constructor.
18
+ *
19
+ * @param Puc_v4p11_Vcs_Api $api
20
+ * @param null $stylesheet
21
+ * @param null $customSlug
22
+ * @param int $checkPeriod
23
+ * @param string $optionName
24
+ */
25
+ public function __construct($api, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') {
26
+ $this->api = $api;
27
+ $this->api->setHttpFilterName($this->getUniqueName('request_update_options'));
28
+
29
+ parent::__construct($api->getRepositoryUrl(), $stylesheet, $customSlug, $checkPeriod, $optionName);
30
+
31
+ $this->api->setSlug($this->slug);
32
+ }
33
+
34
+ public function requestUpdate() {
35
+ $api = $this->api;
36
+ $api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
37
+
38
+ $update = new Puc_v4p11_Theme_Update();
39
+ $update->slug = $this->slug;
40
+
41
+ //Figure out which reference (tag or branch) we'll use to get the latest version of the theme.
42
+ $updateSource = $api->chooseReference($this->branch);
43
+ if ( $updateSource ) {
44
+ $ref = $updateSource->name;
45
+ $update->download_url = $updateSource->downloadUrl;
46
+ } else {
47
+ do_action(
48
+ 'puc_api_error',
49
+ new WP_Error(
50
+ 'puc-no-update-source',
51
+ 'Could not retrieve version information from the repository. '
52
+ . 'This usually means that the update checker either can\'t connect '
53
+ . 'to the repository or it\'s configured incorrectly.'
54
+ ),
55
+ null, null, $this->slug
56
+ );
57
+ $ref = $this->branch;
58
+ }
59
+
60
+ //Get headers from the main stylesheet in this branch/tag. Its "Version" header and other metadata
61
+ //are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
62
+ $remoteHeader = $this->package->getFileHeader($api->getRemoteFile('style.css', $ref));
63
+ $update->version = Puc_v4p11_Utils::findNotEmpty(array(
64
+ $remoteHeader['Version'],
65
+ Puc_v4p11_Utils::get($updateSource, 'version'),
66
+ ));
67
+
68
+ //The details URL defaults to the Theme URI header or the repository URL.
69
+ $update->details_url = Puc_v4p11_Utils::findNotEmpty(array(
70
+ $remoteHeader['ThemeURI'],
71
+ $this->package->getHeaderValue('ThemeURI'),
72
+ $this->metadataUrl,
73
+ ));
74
+
75
+ if ( empty($update->version) ) {
76
+ //It looks like we didn't find a valid update after all.
77
+ $update = null;
78
+ }
79
+
80
+ $update = $this->filterUpdateResult($update);
81
+ return $update;
82
+ }
83
+
84
+ //FIXME: This is duplicated code. Both theme and plugin subclasses that use VCS share these methods.
85
+
86
+ public function setBranch($branch) {
87
+ $this->branch = $branch;
88
+ return $this;
89
+ }
90
+
91
+ public function setAuthentication($credentials) {
92
+ $this->api->setAuthentication($credentials);
93
+ return $this;
94
+ }
95
+
96
+ public function getVcsApi() {
97
+ return $this->api;
98
+ }
99
+
100
+ public function getUpdate() {
101
+ $update = parent::getUpdate();
102
+
103
+ if ( isset($update) && !empty($update->download_url) ) {
104
+ $update->download_url = $this->api->signDownloadUrl($update->download_url);
105
+ }
106
+
107
+ return $update;
108
+ }
109
+
110
+ public function onDisplayConfiguration($panel) {
111
+ parent::onDisplayConfiguration($panel);
112
+ $panel->row('Branch', $this->branch);
113
+ $panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
114
+ $panel->row('API client', get_class($this->api));
115
+ }
116
+ }
117
+
118
+ endif;
app/core/puc/README.md ADDED
@@ -0,0 +1,326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Plugin Update Checker
2
+ =====================
3
+
4
+ This is a custom update checker library for WordPress plugins and themes. It lets you add automatic update notifications and one-click upgrades to your commercial plugins, private themes, and so on. All you need to do is put your plugin/theme details in a JSON file, place the file on your server, and pass the URL to the library. The library periodically checks the URL to see if there's a new version available and displays an update notification to the user if necessary.
5
+
6
+ From the users' perspective, it works just like with plugins and themes hosted on WordPress.org. The update checker uses the default upgrade UI that is familiar to most WordPress users.
7
+
8
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
9
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
10
+ **Table of Contents**
11
+
12
+ - [Getting Started](#getting-started)
13
+ - [Self-hosted Plugins and Themes](#self-hosted-plugins-and-themes)
14
+ - [How to Release an Update](#how-to-release-an-update)
15
+ - [Notes](#notes)
16
+ - [GitHub Integration](#github-integration)
17
+ - [How to Release an Update](#how-to-release-an-update-1)
18
+ - [Notes](#notes-1)
19
+ - [BitBucket Integration](#bitbucket-integration)
20
+ - [How to Release an Update](#how-to-release-an-update-2)
21
+ - [GitLab Integration](#gitlab-integration)
22
+ - [How to Release a GitLab Update](#how-to-release-a-gitlab-update)
23
+ - [License Management](#license-management)
24
+ - [Resources](#resources)
25
+
26
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
27
+
28
+ Getting Started
29
+ ---------------
30
+
31
+ *Note:* In each of the below examples, part of the instructions are to create an instance of the update checker class. It's recommended to do this either during the `plugins_loaded` action or outside of any hooks. If you do it only during an `admin_*` action, then updates will not be visible to a wide variety of WordPress maanagement tools; they will only be visible to logged-in users on dashboard pages.
32
+
33
+ ### Self-hosted Plugins and Themes
34
+
35
+ 1. Download [the latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
36
+ 2. Go to the `examples` subdirectory and open the .json file that fits your project type. Replace the placeholder data with your plugin/theme details.
37
+ - Plugin example:
38
+
39
+ ```json
40
+ {
41
+ "name" : "Plugin Name",
42
+ "version" : "2.0",
43
+ "download_url" : "http://example.com/plugin-name-2.0.zip",
44
+ "sections" : {
45
+ "description" : "Plugin description here. You can use HTML."
46
+ }
47
+ }
48
+ ```
49
+
50
+ This is a minimal example that leaves out optional fields. See [this table](https://docs.google.com/spreadsheets/d/1eOBbW7Go2qEQXReOOCdidMTf_tDYRq4JfegcO1CBPIs/edit?usp=sharing) for a full list of supported fields and their descriptions.
51
+ - Theme example:
52
+
53
+ ```json
54
+ {
55
+ "version": "2.0",
56
+ "details_url": "http://example.com/version-2.0-details.html",
57
+ "download_url": "http://example.com/example-theme-2.0.zip"
58
+ }
59
+ ```
60
+
61
+ This is actually a complete example that shows all theme-related fields. `version` and `download_url` should be self-explanatory. The `details_url` key specifies the page that the user will see if they click the "View version 1.2.3 details" link in an update notification.
62
+ 3. Upload the JSON file to a publicly accessible location.
63
+ 4. Add the following code to the main plugin file or to the `functions.php` file:
64
+
65
+ ```php
66
+ require 'path/to/plugin-update-checker/plugin-update-checker.php';
67
+ $myUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
68
+ 'http://example.com/path/to/details.json',
69
+ __FILE__, //Full path to the main plugin file or functions.php.
70
+ 'unique-plugin-or-theme-slug'
71
+ );
72
+ ```
73
+ Note: If you're using the Composer autoloader, you don't need to explicitly `require` the library.
74
+
75
+ #### How to Release an Update
76
+
77
+ Change the `version` number in the JSON file and make sure that `download_url` points to the latest version. Update the other fields if necessary. Tip: You can use [wp-update-server](https://github.com/YahnisElsts/wp-update-server) to automate this process.
78
+
79
+ By default, the library will check the specified URL for changes every 12 hours. You can force it to check immediately by clicking the "Check for updates" link on the "Plugins" page (it's next to the "Visit plugin site" link). Themes don't have that link, but you can also trigger an update check like this:
80
+
81
+ 1. Install [Debug Bar](https://srd.wordpress.org/plugins/debug-bar/).
82
+ 2. Click the "Debug" menu in the Admin Bar (a.k.a Toolbar).
83
+ 3. Open the "PUC (your-slug)" panel.
84
+ 4. Click the "Check Now" button.
85
+
86
+ #### Notes
87
+ - The second argument passed to `buildUpdateChecker` must be the absolute path to the main plugin file or any file in the theme directory. If you followed the "getting started" instructions, you can just use the `__FILE__` constant.
88
+ - The third argument - i.e. the slug - is optional but recommended. In most cases, the slug should be the same as the name of your plugin directory. For example, if your plugin lives in `/wp-content/plugins/my-plugin`, set the slug to `my-plugin`. If the slug is omitted, the update checker will use the name of the main plugin file as the slug (e.g. `my-cool-plugin.php` &rarr; `my-cool-plugin`). This can lead to conflicts if your plugin has a generic file name like `plugin.php`.
89
+
90
+ This doesn't affect themes because PUC uses the theme directory name as the default slug. Still, if you're planning to use the slug in your own code - e.g. to filter updates or override update checker behaviour - it can be a good idea to set it explicitly.
91
+
92
+ ### GitHub Integration
93
+
94
+ 1. Download [the latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
95
+ 2. Add the following code to the main plugin file or `functions.php`:
96
+
97
+ ```php
98
+ require 'plugin-update-checker/plugin-update-checker.php';
99
+ $myUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
100
+ 'https://github.com/user-name/repo-name/',
101
+ __FILE__,
102
+ 'unique-plugin-or-theme-slug'
103
+ );
104
+
105
+ //Set the branch that contains the stable release.
106
+ $myUpdateChecker->setBranch('stable-branch-name');
107
+
108
+ //Optional: If you're using a private repository, specify the access token like this:
109
+ $myUpdateChecker->setAuthentication('your-token-here');
110
+ ```
111
+ 3. Plugins only: Add a `readme.txt` file formatted according to the [WordPress.org plugin readme standard](https://wordpress.org/plugins/readme.txt) to your repository. The contents of this file will be shown when the user clicks the "View version 1.2.3 details" link.
112
+
113
+ #### How to Release an Update
114
+
115
+ This library supports a couple of different ways to release updates on GitHub. Pick the one that best fits your workflow.
116
+
117
+ - **GitHub releases**
118
+
119
+ Create a new release using the "Releases" feature on GitHub. The tag name and release title don't matter. The description is optional, but if you do provide one, it will be displayed when the user clicks the "View version x.y.z details" link on the "Plugins" page. Note that PUC ignores releases marked as "This is a pre-release".
120
+
121
+ If you want to use release assets, call the `enableReleaseAssets()` method after creating the update checker instance:
122
+ ```php
123
+ $myUpdateChecker->getVcsApi()->enableReleaseAssets();
124
+ ```
125
+
126
+ - **Tags**
127
+
128
+ To release version 1.2.3, create a new Git tag named `v1.2.3` or `1.2.3`. That's it.
129
+
130
+ PUC doesn't require strict adherence to [SemVer](http://semver.org/). These are all valid tag names: `v1.2.3`, `v1.2-foo`, `1.2.3_rc1-ABC`, `1.2.3.4.5`. However, be warned that it's not smart enough to filter out alpha/beta/RC versions. If that's a problem, you might want to use GitHub releases or branches instead.
131
+
132
+ - **Stable branch**
133
+
134
+ Point the update checker at a stable, production-ready branch:
135
+ ```php
136
+ $updateChecker->setBranch('branch-name');
137
+ ```
138
+ PUC will periodically check the `Version` header in the main plugin file or `style.css` and display a notification if it's greater than the installed version.
139
+
140
+ Caveat: If you set the branch to `master` (the default), the update checker will look for recent releases and tags first. It'll only use the `master` branch if it doesn't find anything else suitable.
141
+
142
+ #### Notes
143
+
144
+ The library will pull update details from the following parts of a release/tag/branch:
145
+
146
+ - Version number
147
+ - The "Version" plugin header.
148
+ - The latest GitHub release or tag name.
149
+ - Changelog
150
+ - The "Changelog" section of `readme.txt`.
151
+ - One of the following files:
152
+ CHANGES.md, CHANGELOG.md, changes.md, changelog.md
153
+ - GitHub release notes.
154
+ - Required and tested WordPress versions
155
+ - The "Requires at least" and "Tested up to" fields in `readme.txt`.
156
+ - The following plugin headers:
157
+ `Required WP`, `Tested WP`, `Requires at least`, `Tested up to`
158
+ - "Last updated" timestamp
159
+ - The creation timestamp of the latest GitHub release.
160
+ - The latest commit in the selected tag or branch.
161
+ - Number of downloads
162
+ - The `download_count` statistic of the latest release.
163
+ - If you're not using GitHub releases, there will be no download stats.
164
+ - Other plugin details - author, homepage URL, description
165
+ - The "Description" section of `readme.txt`.
166
+ - Remote plugin headers (i.e. the latest version on GitHub).
167
+ - Local plugin headers (i.e. the currently installed version).
168
+ - Ratings, banners, screenshots
169
+ - Not supported.
170
+
171
+ ### BitBucket Integration
172
+
173
+ 1. Download [the latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
174
+ 2. Add the following code to the main plugin file or `functions.php`:
175
+
176
+ ```php
177
+ require 'plugin-update-checker/plugin-update-checker.php';
178
+ $myUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
179
+ 'https://bitbucket.org/user-name/repo-name',
180
+ __FILE__,
181
+ 'unique-plugin-or-theme-slug'
182
+ );
183
+
184
+ //Optional: If you're using a private repository, create an OAuth consumer
185
+ //and set the authentication credentials like this:
186
+ //Note: For now you need to check "This is a private consumer" when
187
+ //creating the consumer to work around #134:
188
+ // https://github.com/YahnisElsts/plugin-update-checker/issues/134
189
+ $myUpdateChecker->setAuthentication(array(
190
+ 'consumer_key' => '...',
191
+ 'consumer_secret' => '...',
192
+ ));
193
+
194
+ //Optional: Set the branch that contains the stable release.
195
+ $myUpdateChecker->setBranch('stable-branch-name');
196
+ ```
197
+ 3. Optional: Add a `readme.txt` file formatted according to the [WordPress.org plugin readme standard](https://wordpress.org/plugins/readme.txt) to your repository. For plugins, the contents of this file will be shown when the user clicks the "View version 1.2.3 details" link.
198
+
199
+ #### How to Release an Update
200
+
201
+ BitBucket doesn't have an equivalent to GitHub's releases, so the process is slightly different. You can use any of the following approaches:
202
+
203
+ - **`Stable tag` header**
204
+
205
+ This is the recommended approach if you're using tags to mark each version. Add a `readme.txt` file formatted according to the [WordPress.org plugin readme standard](https://wordpress.org/plugins/readme.txt) to your repository. Set the "stable tag" header to the tag that represents the latest release. Example:
206
+ ```text
207
+ Stable tag: v1.2.3
208
+ ```
209
+ The tag doesn't have to start with a "v" or follow any particular format. You can use any name you like as long as it's a valid Git tag.
210
+
211
+ Tip: If you explicitly set a stable branch, the update checker will look for a `readme.txt` in that branch. Otherwise it will only look at the `master` branch.
212
+
213
+ - **Tags**
214
+
215
+ You can skip the "stable tag" bit and just create a new Git tag named `v1.2.3` or `1.2.3`. The update checker will look at the most recent tags and pick the one that looks like the highest version number.
216
+
217
+ PUC doesn't require strict adherence to [SemVer](http://semver.org/). These are all valid tag names: `v1.2.3`, `v1.2-foo`, `1.2.3_rc1-ABC`, `1.2.3.4.5`. However, be warned that it's not smart enough to filter out alpha/beta/RC versions.
218
+
219
+ - **Stable branch**
220
+
221
+ Point the update checker at a stable, production-ready branch:
222
+ ```php
223
+ $updateChecker->setBranch('branch-name');
224
+ ```
225
+ PUC will periodically check the `Version` header in the main plugin file or `style.css` and display a notification if it's greater than the installed version. Caveat: If you set the branch to `master`, the update checker will still look for tags first.
226
+
227
+ ### GitLab Integration
228
+
229
+ 1. Download [the latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
230
+ 2. Add the following code to the main plugin file or `functions.php` and define how you want to check for updates from Gitlab (refer to: [Gitlab: How to Release an Update](#how-to-release-a-gitlab-update)):
231
+
232
+ ```php
233
+ require 'plugin-update-checker/plugin-update-checker.php';
234
+ $myUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
235
+ 'https://gitlab.com/user-name/repo-name/',
236
+ __FILE__,
237
+ 'unique-plugin-or-theme-slug'
238
+ );
239
+
240
+ //Optional: If you're using a private repository, specify the access token like this:
241
+ $myUpdateChecker->setAuthentication('your-token-here');
242
+ ```
243
+
244
+ Alternatively, if you're using a self-hosted GitLab instance, initialize the update checker like this:
245
+ ```php
246
+ $myUpdateChecker = new Puc_v4p11_Vcs_PluginUpdateChecker(
247
+ new Puc_v4p11_Vcs_GitLabApi('https://myserver.com/user-name/repo-name/'),
248
+ __FILE__,
249
+ 'unique-plugin-or-theme-slug'
250
+ );
251
+ //Optional: Add setAuthentication(...) and setBranch(...) as shown above.
252
+ ```
253
+ If you're using a self-hosted GitLab instance and [subgroups or nested groups](https://docs.gitlab.com/ce/user/group/subgroups/index.html), you have to tell the update checker which parts of the URL are subgroups:
254
+ ```php
255
+ $myUpdateChecker = new Puc_v4p11_Vcs_PluginUpdateChecker(
256
+ new Puc_v4p11_Vcs_GitLabApi('https://myserver.com/group-name/subgroup-level1/subgroup-level2/subgroup-level3/repo-name/', null, 'subgroup-level1/subgroup-level2/subgroup-level3'),
257
+ __FILE__,
258
+ 'unique-plugin-or-theme-slug'
259
+ );
260
+
261
+ ```
262
+
263
+ 3. Plugins only: Add a `readme.txt` file formatted according to the [WordPress.org plugin readme standard](https://wordpress.org/plugins/readme.txt) to your repository. The contents of this file will be shown when the user clicks the "View version 1.2.3 details" link.
264
+
265
+ #### How to Release a GitLab Update
266
+ A Gitlab repository can be checked for updates in 4 different ways.
267
+
268
+ 1. **Stable branch** (other than `master` or `main`):
269
+ - Point the update checker at any stable, production-ready branch and PUC will periodically check the `Version` header in the main plugin file or `style.css` and display a notification if it's greater than the installed version.
270
+ - Add the following code:
271
+ ```php
272
+ //Add the following code to your main plugin file or `functions.php` file to check for updates from a custom branch
273
+ $myUpdateChecker->setBranch('stable-branch-name');
274
+ ```
275
+ - Caveats:
276
+ - If you set the branch to `main` (the default) or `master` (the historical default), the update checker will look for recent releases and tags first. It'll only use the `main` or `master` branch if it doesn't find anything else suitable.
277
+
278
+ 2. **GitLab Releases using Generic Packages**:
279
+ - Use a Gitlab CI/CD Pipeline to automatically generate your update on release using a Generic Package. The benefit of using Generic Package assets over the Source Code assets is that the code can already be built and production ready.
280
+ - Add the following code:
281
+ ```php
282
+ //Add the following code to your main plugin file or `functions.php` file to check for a new update from releases using generic packages
283
+ $myUpdateChecker->getVcsApi()->enableReleasePackages();
284
+ ```
285
+ - PUC will periodically check the release version (i.e. the tag name of the release) and will display a notification if the release is a greater version than the installed version.
286
+ - The release tag name should loosely follow [SemVer](http://semver.org/) but these are all valid release names: `v1.2.3`, `v1.2-foo`, `1.2.3_rc1-ABC`, `1.2.3.4.5` However, be warned that it's not smart enough to filter out alpha/beta/RC versions. If that's a problem, you might want to use GitLab branches instead.
287
+ - For more information about *Gitlab Release Generic Packages* refer to the following links:
288
+ - [Gitlab CI/CD Release Documentation](https://docs.gitlab.com/ee/user/project/releases/#create-release-from-gitlab-ci)
289
+ - [Gitlab Release Assets as Generic Package Documentation](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs/examples/release-assets-as-generic-package/)
290
+ - [Example .gitlab-ci.yml file using Release Generic Packages for generating a update package from the Sensei-LMS wordpress plugin](https://gist.github.com/timwiel/9dfd3526c768efad4973254085e065ce)
291
+
292
+
293
+ 3. **GitLab Releases using Source Code Assets**:
294
+ - Create a new release using the "Releases" feature on Gitlab.
295
+ - Add the following code:
296
+ ```php
297
+ //Add the following code to your main plugin file or `functions.php` file to check for a new update from releases using release assets
298
+ $myUpdateChecker->getVcsApi()->enableReleaseAssets();
299
+ ```
300
+ - PUC will periodically check the release version (based on release tag name) and display a notification if the release version is greater than the installed version.
301
+ - The release name should loosely follow [SemVer](http://semver.org/) but these are all valid release names: `v1.2.3`, `v1.2-foo`, `1.2.3_rc1-ABC`, `1.2.3.4.5` However, be warned that it's not smart enough to filter out alpha/beta/RC versions. If that's a problem, you might want to use GitLab branches instead.
302
+
303
+
304
+ 4. **Tags** (this is the default option):
305
+ - To release version 1.2.3, create a new Git tag named `v1.2.3` or `1.2.3`.
306
+ - Optionally, add the following code:
307
+ ```php
308
+ //Add the following code to your main plugin file or `functions.php` file to check for updates from the default branch
309
+ $myUpdateChecker->setBranch('master'); //or 'main'
310
+ ```
311
+ - PUC doesn't require strict adherence to [SemVer](http://semver.org/). These are all valid tag names: `v1.2.3`, `v1.2-foo`, `1.2.3_rc1-ABC`, `1.2.3.4.5`. However, be warned that it's not smart enough to filter out alpha/beta/RC versions. If that's a problem, you might want to use GitLab branches instead.
312
+
313
+ License Management
314
+ ------------------
315
+
316
+ Currently, the update checker doesn't have any built-in license management features. It only provides some hooks that you can use to, for example, append license keys to update requests (`$updateChecker->addQueryArgFilter()`). If you're looking for ways to manage and verify licenses, please post your feedback in [this issue](https://github.com/YahnisElsts/plugin-update-checker/issues/222).
317
+
318
+ Resources
319
+ ---------
320
+
321
+ - [This blog post](http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/) has more information about the update checker API. *Slightly out of date.*
322
+ - [Debug Bar](https://wordpress.org/plugins/debug-bar/) - useful for testing and debugging the update checker.
323
+ - [Update format reference](https://docs.google.com/spreadsheets/d/1eOBbW7Go2qEQXReOOCdidMTf_tDYRq4JfegcO1CBPIs/edit?usp=sharing) - describes all fields supported by the JSON-based update information format used by the update checker. Only covers plugins. Themes use a similar but more limited format.
324
+ - [Securing download links](http://w-shadow.com/blog/2013/03/19/plugin-updates-securing-download-links/) - a general overview.
325
+ - [A GUI for entering download credentials](http://open-tools.net/documentation/tutorial-automatic-updates.html#wordpress)
326
+ - [Theme Update Checker](http://w-shadow.com/blog/2011/06/02/automatic-updates-for-commercial-themes/) - an older, theme-only variant of this update checker.
app/core/puc/composer.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "yahnis-elsts/plugin-update-checker",
3
+ "type": "library",
4
+ "description": "A custom update checker for WordPress plugins and themes. Useful if you can't host your plugin in the official WP repository but still want it to support automatic updates.",
5
+ "keywords": ["wordpress", "plugin updates", "automatic updates", "theme updates"],
6
+ "homepage": "https://github.com/YahnisElsts/plugin-update-checker/",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Yahnis Elsts",
11
+ "email": "whiteshadow@w-shadow.com",
12
+ "homepage": "http://w-shadow.com/",
13
+ "role": "Developer"
14
+ }
15
+ ],
16
+ "require": {
17
+ "php": ">=5.2.0",
18
+ "ext-json": "*"
19
+ },
20
+ "autoload": {
21
+ "files": ["load-v4p11.php"]
22
+ }
23
+ }
app/core/puc/css/puc-debug-bar.css ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .puc-debug-bar-panel-v4 pre {
2
+ margin-top: 0;
3
+ }
4
+
5
+ /* Style the debug data table to match "widefat" table style used by WordPress. */
6
+ table.puc-debug-data {
7
+ width: 100%;
8
+ clear: both;
9
+ margin: 0;
10
+
11
+ border-spacing: 0;
12
+ background-color: #f9f9f9;
13
+
14
+ border-radius: 3px;
15
+ border: 1px solid #dfdfdf;
16
+ border-collapse: separate;
17
+ }
18
+
19
+ table.puc-debug-data * {
20
+ word-wrap: break-word;
21
+ }
22
+
23
+ table.puc-debug-data th {
24
+ width: 11em;
25
+ padding: 7px 7px 8px;
26
+ text-align: left;
27
+
28
+ font-family: "Georgia", "Times New Roman", "Bitstream Charter", "Times", serif;
29
+ font-weight: 400;
30
+ font-size: 14px;
31
+ line-height: 1.3em;
32
+ text-shadow: rgba(255, 255, 255, 0.804) 0 1px 0;
33
+ }
34
+
35
+ table.puc-debug-data td, table.puc-debug-data th {
36
+ border-width: 1px 0;
37
+ border-style: solid;
38
+
39
+ border-top-color: #fff;
40
+ border-bottom-color: #dfdfdf;
41
+
42
+ text-transform: none;
43
+ }
44
+
45
+ table.puc-debug-data td {
46
+ color: #555;
47
+ font-size: 12px;
48
+ padding: 4px 7px 2px;
49
+ vertical-align: top;
50
+ }
51
+
52
+ .puc-ajax-response {
53
+ border: 1px solid #dfdfdf;
54
+ border-radius: 3px;
55
+ padding: 0.5em;
56
+ margin: 5px 0;
57
+ background-color: white;
58
+ }
59
+
60
+ .puc-ajax-nonce {
61
+ display: none;
62
+ }
63
+
64
+ .puc-ajax-response dt {
65
+ margin: 0;
66
+ }
67
+
68
+ .puc-ajax-response dd {
69
+ margin: 0 0 1em;
70
+ }
app/core/puc/examples/plugin.json ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "My Example Plugin",
3
+ "version": "2.0",
4
+ "download_url": "http://example.com/updates/example-plugin.zip",
5
+
6
+ "homepage": "http://example.com/",
7
+ "requires": "4.5",
8
+ "tested": "4.8",
9
+ "last_updated": "2017-01-01 16:17:00",
10
+ "upgrade_notice": "Here's why you should upgrade...",
11
+
12
+ "author": "Janis Elsts",
13
+ "author_homepage": "http://example.com/",
14
+
15
+ "sections": {
16
+ "description": "(Required) Plugin description. Basic HTML can be used in all sections.",
17
+ "installation": "(Recommended) Installation instructions.",
18
+ "changelog": "(Recommended) Changelog. <p>This section will be displayed by default when the user clicks 'View version x.y.z details'.</p>",
19
+ "custom_section": "This is a custom section labeled 'Custom Section'."
20
+ },
21
+
22
+ "icons" : {
23
+ "1x" : "http://w-shadow.com/files/external-update-example/assets/icon-128x128.png",
24
+ "2x" : "http://w-shadow.com/files/external-update-example/assets/icon-256x256.png"
25
+ },
26
+
27
+ "banners": {
28
+ "low": "http://w-shadow.com/files/external-update-example/assets/banner-772x250.png",
29
+ "high": "http://w-shadow.com/files/external-update-example/assets/banner-1544x500.png"
30
+ },
31
+
32
+ "translations": [
33
+ {
34
+ "language": "fr_FR",
35
+ "version": "4.0",
36
+ "updated": "2016-04-22 23:22:42",
37
+ "package": "http://example.com/updates/translations/french-language-pack.zip"
38
+ },
39
+ {
40
+ "language": "de_DE",
41
+ "version": "5.0",
42
+ "updated": "2016-04-22 23:22:42",
43
+ "package": "http://example.com/updates/translations/german-language-pack.zip"
44
+ }
45
+ ],
46
+
47
+ "rating": 90,
48
+ "num_ratings": 123,
49
+
50
+ "downloaded": 1234,
51
+ "active_installs": 12345
52
+ }
app/core/puc/examples/theme.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ {
2
+ "version": "2.0",
3
+ "details_url": "http://example.com/version-2.0-details.html",
4
+ "download_url": "http://example.com/example-theme-2.0.zip"
5
+ }
app/core/puc/js/debug-bar.js ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function($) {
2
+
3
+ function runAjaxAction(button, action) {
4
+ button = $(button);
5
+ var panel = button.closest('.puc-debug-bar-panel-v4');
6
+ var responseBox = button.closest('td').find('.puc-ajax-response');
7
+
8
+ responseBox.text('Processing...').show();
9
+ $.post(
10
+ ajaxurl,
11
+ {
12
+ action : action,
13
+ uid : panel.data('uid'),
14
+ _wpnonce: panel.data('nonce')
15
+ },
16
+ function(data) {
17
+ responseBox.html(data);
18
+ },
19
+ 'html'
20
+ );
21
+ }
22
+
23
+ $('.puc-debug-bar-panel-v4 input[name="puc-check-now-button"]').on('click', function() {
24
+ runAjaxAction(this, 'puc_v4_debug_check_now');
25
+ return false;
26
+ });
27
+
28
+ $('.puc-debug-bar-panel-v4 input[name="puc-request-info-button"]').on('click', function() {
29
+ runAjaxAction(this, 'puc_v4_debug_request_info');
30
+ return false;
31
+ });
32
+
33
+
34
+ // Debug Bar uses the panel class name as part of its link and container IDs. This means we can
35
+ // end up with multiple identical IDs if more than one plugin uses the update checker library.
36
+ // Fix it by replacing the class name with the plugin slug.
37
+ var panels = $('#debug-menu-targets').find('.puc-debug-bar-panel-v4');
38
+ panels.each(function() {
39
+ var panel = $(this);
40
+ var uid = panel.data('uid');
41
+ var target = panel.closest('.debug-menu-target');
42
+
43
+ //Change the panel wrapper ID.
44
+ target.attr('id', 'debug-menu-target-puc-' + uid);
45
+
46
+ //Change the menu link ID as well and point it at the new target ID.
47
+ $('#debug-bar-menu').find('.puc-debug-menu-link-' + uid)
48
+ .closest('.debug-menu-link')
49
+ .attr('id', 'debug-menu-link-puc-' + uid)
50
+ .attr('href', '#' + target.attr('id'));
51
+ });
52
+ });
app/core/puc/languages/plugin-update-checker-ca.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-ca.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2019-09-25 18:15+0200\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: ca\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprova si hi ha actualitzacions"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "L’extensió %s està actualitzada."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nova versió de l’extensió %s està disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No s’ha pogut determinar si hi ha actualitzacions per a %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estat del comprovador d’actualitzacions desconegut \"%s\""
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hi ha cap registre de canvis disponible."
app/core/puc/languages/plugin-update-checker-cs_CZ.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-cs_CZ.po ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2017-05-20 10:53+0300\n"
6
+ "PO-Revision-Date: 2017-07-05 15:39+0000\n"
7
+ "Last-Translator: Vojtěch Sajdl <vojtech@sajdl.com>\n"
8
+ "Language-Team: Czech (Czech Republic)\n"
9
+ "Language: cs-CZ\n"
10
+ "Plural-Forms: nplurals=2; plural=(n != 1)\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "X-Loco-Source-Locale: cs_CZ\n"
15
+ "X-Generator: Loco - https://localise.biz/\n"
16
+ "X-Poedit-Basepath: ..\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
19
+ "X-Poedit-SearchPath-0: .\n"
20
+ "X-Loco-Parser: loco_parse_po"
21
+
22
+ #: Puc/v4p1/Plugin/UpdateChecker.php:358
23
+ msgid "Check for updates"
24
+ msgstr "Zkontrolovat aktualizace"
25
+
26
+ #: Puc/v4p1/Plugin/UpdateChecker.php:405
27
+ #, php-format
28
+ msgctxt "the plugin title"
29
+ msgid "The %s plugin is up to date."
30
+ msgstr "Plugin %s je aktuální."
31
+
32
+ #: Puc/v4p1/Plugin/UpdateChecker.php:407
33
+ #, php-format
34
+ msgctxt "the plugin title"
35
+ msgid "A new version of the %s plugin is available."
36
+ msgstr "Nová verze pluginu %s je dostupná."
37
+
38
+ #: Puc/v4p1/Plugin/UpdateChecker.php:409
39
+ #, php-format
40
+ msgid "Unknown update checker status \"%s\""
41
+ msgstr "Neznámý status kontroly aktualizací \"%s\""
42
+
43
+ #: Puc/v4p1/Vcs/PluginUpdateChecker.php:83
44
+ msgid "There is no changelog available."
45
+ msgstr "Changelog není dostupný."
app/core/puc/languages/plugin-update-checker-da_DK.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-da_DK.po ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-05-20 10:53+0300\n"
5
+ "PO-Revision-Date: 2017-10-17 11:07+0200\n"
6
+ "Last-Translator: Mikk3lRo\n"
7
+ "Language-Team: Mikk3lRo\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 2.0.4\n"
12
+ "X-Poedit-Basepath: ..\n"
13
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
16
+ "Language: da_DK\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p1/Plugin/UpdateChecker.php:358
20
+ msgid "Check for updates"
21
+ msgstr "Undersøg for opdateringer"
22
+
23
+ #: Puc/v4p1/Plugin/UpdateChecker.php:405
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "Plugin'et %s er allerede opdateret."
28
+
29
+ #: Puc/v4p1/Plugin/UpdateChecker.php:407
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "En ny version af plugin'et %s er tilgængelig."
34
+
35
+ #: Puc/v4p1/Plugin/UpdateChecker.php:409
36
+ #, php-format
37
+ msgid "Unknown update checker status \"%s\""
38
+ msgstr "Ukendt opdateringsstatus: \"%s\""
39
+
40
+ #: Puc/v4p1/Vcs/PluginUpdateChecker.php:83
41
+ msgid "There is no changelog available."
42
+ msgstr "Der er ingen ændringslog tilgængelig."
app/core/puc/languages/plugin-update-checker-de_DE.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-de_DE.po ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2016-06-29 20:21+0100\n"
5
+ "PO-Revision-Date: 2016-06-29 20:23+0100\n"
6
+ "Last-Translator: Igor Lückel <info@igorlueckel.de>\n"
7
+ "Language-Team: \n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 1.8.1\n"
12
+ "X-Poedit-Basepath: ..\n"
13
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Poedit-KeywordsList: __;_e\n"
16
+ "Language: de_DE\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: github-checker.php:137
20
+ msgid "There is no changelog available."
21
+ msgstr "Es ist keine Liste von Programmänderungen verfügbar."
22
+
23
+ #: plugin-update-checker.php:852
24
+ msgid "Check for updates"
25
+ msgstr "Nach Update suchen"
26
+
27
+ #: plugin-update-checker.php:896
28
+ msgid "This plugin is up to date."
29
+ msgstr "Das Plugin ist aktuell."
30
+
31
+ #: plugin-update-checker.php:898
32
+ msgid "A new version of this plugin is available."
33
+ msgstr "Es ist eine neue Version für das Plugin verfügbar."
34
+
35
+ #: plugin-update-checker.php:900
36
+ #, php-format
37
+ msgid "Unknown update checker status \"%s\""
38
+ msgstr "Unbekannter Update Status \"%s\""
app/core/puc/languages/plugin-update-checker-es_AR.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_AR.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:13-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_CL.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_CL.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_CO.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_CO.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_CR.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_CR.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_DO.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_DO.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_ES.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_ES.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 14:56-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_GT.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_GT.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_HN.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_HN.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_MX.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_MX.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 14:57-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_PE.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_PE.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:15-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_PR.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_PR.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:15-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_UY.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_UY.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:15-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-es_VE.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-es_VE.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 14:57-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
app/core/puc/languages/plugin-update-checker-fa_IR.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-fa_IR.po ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2016-02-17 14:21+0100\n"
5
+ "PO-Revision-Date: 2016-10-28 14:30+0330\n"
6
+ "Last-Translator: studio RVOLA <hello@rvola.com>\n"
7
+ "Language-Team: Pro Style <info@prostyle.ir>\n"
8
+ "Language: fa_IR\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.8\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=2; plural=(n > 1);\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-KeywordsList: __;_e\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: github-checker.php:120
20
+ msgid "There is no changelog available."
21
+ msgstr "شرحی برای تغییرات یافت نشد"
22
+
23
+ #: plugin-update-checker.php:637
24
+ msgid "Check for updates"
25
+ msgstr "بررسی برای بروزرسانی "
26
+
27
+ #: plugin-update-checker.php:681
28
+ msgid "This plugin is up to date."
29
+ msgstr "شما از آخرین نسخه استفاده میکنید . به‌روز باشید"
30
+
31
+ #: plugin-update-checker.php:683
32
+ msgid "A new version of this plugin is available."
33
+ msgstr "نسخه جدیدی برای افزونه ارائه شده است ."
34
+
35
+ #: plugin-update-checker.php:685
36
+ #, php-format
37
+ msgid "Unknown update checker status \"%s\""
38
+ msgstr "وضعیت ناشناخته برای بروزرسانی \"%s\""
app/core/puc/languages/plugin-update-checker-fr_CA.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-fr_CA.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2018-02-12 10:32-0500\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.0.4\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n > 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: Eric Gagnon <eric.gagnon@banq.qc.ca>\n"
16
+ "Language: fr_CA\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Vérifier les mises à jour"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "L’extension %s est à jour."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Une nouvelle version de l’extension %s est disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "Impossible de déterminer si une mise à jour est disponible pour \"%s\""
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Un problème inconnu est survenu \"%s\""
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "Il n’y a aucun journal de mise à jour disponible."
app/core/puc/languages/plugin-update-checker-fr_FR.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-fr_FR.po ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-07-07 14:53+0200\n"
5
+ "PO-Revision-Date: 2017-07-07 14:54+0200\n"
6
+ "Language-Team: studio RVOLA <http://www.rvola.com>\n"
7
+ "Language: fr_FR\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 2.0.2\n"
12
+ "X-Poedit-Basepath: ..\n"
13
+ "Plural-Forms: nplurals=2; plural=(n > 1);\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
16
+ "Last-Translator: Nicolas GEHIN\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p1/Plugin/UpdateChecker.php:358
20
+ msgid "Check for updates"
21
+ msgstr "Vérifier les mises à jour"
22
+
23
+ #: Puc/v4p1/Plugin/UpdateChecker.php:405
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "L’extension %s est à jour."
28
+
29
+ #: Puc/v4p1/Plugin/UpdateChecker.php:407
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Une nouvelle version de l’extension %s est disponible."
34
+
35
+ #: Puc/v4p1/Plugin/UpdateChecker.php:409
36
+ #, php-format
37
+ msgid "Unknown update checker status \"%s\""
38
+ msgstr "Un problème inconnu est survenu \"%s\""
39
+
40
+ #: Puc/v4p1/Vcs/PluginUpdateChecker.php:85
41
+ msgid "There is no changelog available."
42
+ msgstr "Il n’y a aucun journal de mise à jour disponible."
app/core/puc/languages/plugin-update-checker-hu_HU.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-hu_HU.po ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2016-01-11 21:23+0100\n"
5
+ "PO-Revision-Date: 2016-01-11 21:25+0100\n"
6
+ "Last-Translator: Tamás András Horváth <htomy92@gmail.com>\n"
7
+ "Language-Team: \n"
8
+ "Language: hu_HU\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.6\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-KeywordsList: __;_e\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: github-checker.php:137
20
+ msgid "There is no changelog available."
21
+ msgstr "Nem érhető el a changelog."
22
+
23
+ #: plugin-update-checker.php:852
24
+ msgid "Check for updates"
25
+ msgstr "Frissítés ellenőrzése"
26
+
27
+ #: plugin-update-checker.php:896
28
+ msgid "This plugin is up to date."
29
+ msgstr "Ez a plugin naprakész."
30
+
31
+ #: plugin-update-checker.php:898
32
+ msgid "A new version of this plugin is available."
33
+ msgstr "Új verzió érhető el a kiegészítőhöz"
34
+
35
+ #: plugin-update-checker.php:900
36
+ #, php-format
37
+ msgid "Unknown update checker status \"%s\""
38
+ msgstr "Ismeretlen a frissítés ellenőrző státusza \"%s\""
39
+
40
+ #~ msgid "Every %d hours"
41
+ #~ msgstr "Minden %d órában"
app/core/puc/languages/plugin-update-checker-it_IT.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-it_IT.po ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2016-06-29 20:21+0100\n"
5
+ "PO-Revision-Date: 2017-01-15 12:24+0100\n"
6
+ "Last-Translator: Igor Lückel <info@igorlueckel.de>\n"
7
+ "Language-Team: \n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 1.5.5\n"
12
+ "X-Poedit-Basepath: ..\n"
13
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Poedit-KeywordsList: __;_e\n"
16
+ "Language: de_DE\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: github-checker.php:137
20
+ msgid "There is no changelog available."
21
+ msgstr "Non c'è alcuna sezione di aggiornamento disponibile"
22
+
23
+ #: plugin-update-checker.php:852
24
+ msgid "Check for updates"
25
+ msgstr "Verifica aggiornamenti"
26
+
27
+ #: plugin-update-checker.php:896
28
+ msgid "This plugin is up to date."
29
+ msgstr "Il plugin è aggiornato"
30
+
31
+ #: plugin-update-checker.php:898
32
+ msgid "A new version of this plugin is available."
33
+ msgstr "Una nuova versione del plugin è disponibile"
34
+
35
+ #: plugin-update-checker.php:900
36
+ #, php-format
37
+ msgid "Unknown update checker status \"%s\""
38
+ msgstr "Si è verificato un problema sconosciuto \"%s\""
app/core/puc/languages/plugin-update-checker-ja.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-ja.po ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: \n"
4
+ "POT-Creation-Date: 2019-07-15 17:07+0900\n"
5
+ "PO-Revision-Date: 2019-07-15 17:12+0900\n"
6
+ "Last-Translator: tak <tak7725@gmail.com>\n"
7
+ "Language-Team: \n"
8
+ "Language: ja_JP\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 2.2.3\n"
13
+ "X-Poedit-Basepath: ../../../../../../Applications/XAMPP/xamppfiles/htdocs/"
14
+ "kisagai/wordpress/wp-content/plugins/simple-stripe-gateway/Puc\n"
15
+ "Plural-Forms: nplurals=1; plural=0;\n"
16
+ "X-Poedit-KeywordsList: __;_x:1,2c\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: v4p7/Plugin/Ui.php:54
20
+ msgid "View details"
21
+ msgstr "詳細を表示"
22
+
23
+ #: v4p7/Plugin/Ui.php:77
24
+ #, php-format
25
+ msgid "More information about %s"
26
+ msgstr "%sについての詳細"
27
+
28
+ #: v4p7/Plugin/Ui.php:128
29
+ msgid "Check for updates"
30
+ msgstr "アップデートを確認"
31
+
32
+ #: v4p7/Plugin/Ui.php:213
33
+ #, php-format
34
+ msgctxt "the plugin title"
35
+ msgid "The %s plugin is up to date."
36
+ msgstr "%s プラグインは、最新バージョンです。"
37
+
38
+ #: v4p7/Plugin/Ui.php:215
39
+ #, php-format
40
+ msgctxt "the plugin title"
41
+ msgid "A new version of the %s plugin is available."
42
+ msgstr "%s プラグインの最新バージョンがあります。"
43
+
44
+ #: v4p7/Plugin/Ui.php:217
45
+ #, php-format
46
+ msgctxt "the plugin title"
47
+ msgid "Could not determine if updates are available for %s."
48
+ msgstr "%s のアップデートがあるかどうかを判断できませんでした。"
49
+
50
+ #: v4p7/Plugin/Ui.php:223
51
+ #, php-format
52
+ msgid "Unknown update checker status \"%s\""
53
+ msgstr "バージョンアップの確認で想定外の状態になりました。ステータス:”%s”"
54
+
55
+ #: v4p7/Vcs/PluginUpdateChecker.php:98
56
+ msgid "There is no changelog available."
57
+ msgstr "更新履歴はありません。"
app/core/puc/languages/plugin-update-checker-nl_BE.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-nl_BE.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2018-03-25 18:15+0200\n"
5
+ "PO-Revision-Date: 2018-03-25 18:32+0200\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 1.8.7.1\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: Frank Goossens <frank@optimizingmatters.com>\n"
16
+ "Language: nl_BE\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Controleer op nieuwe versies"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "De meest recente %s versie is geïnstalleerd."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Er is een nieuwe versie van %s beschikbaar."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "Kon niet bepalen of er nieuwe versie van %s beschikbaar is."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Ongekende status bij controle op nieuwe versie: \"%s\""
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "Er is geen changelog beschikbaar."
app/core/puc/languages/plugin-update-checker-nl_NL.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-nl_NL.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2018-03-25 18:15+0200\n"
5
+ "PO-Revision-Date: 2018-03-25 18:32+0200\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 1.8.7.1\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: Frank Goossens <frank@optimizingmatters.com>\n"
16
+ "Language: nl_NL\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Controleer op nieuwe versies"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "De meest recente %s versie is geïnstalleerd."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Er is een nieuwe versie van %s beschikbaar."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "Kon niet bepalen of er nieuwe versie van %s beschikbaar is."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Ongekende status bij controle op nieuwe versie: \"%s\""
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "Er is geen changelog beschikbaar."
app/core/puc/languages/plugin-update-checker-pt_BR.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-pt_BR.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-05-19 15:41-0300\n"
5
+ "PO-Revision-Date: 2017-05-19 15:42-0300\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: \n"
8
+ "Language: pt_BR\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.8\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "Plural-Forms: nplurals=2; plural=(n > 1);\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-KeywordsList: __;_e;_x;_x:1,2c\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p1/Plugin/UpdateChecker.php:358
20
+ msgid "Check for updates"
21
+ msgstr "Verificar Atualizações"
22
+
23
+ #: Puc/v4p1/Plugin/UpdateChecker.php:401 Puc/v4p1/Plugin/UpdateChecker.php:406
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "O plugin %s já está na sua versão mais recente."
28
+
29
+ #: Puc/v4p1/Plugin/UpdateChecker.php:408
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Há uma nova versão para o plugin %s disponível para download."
34
+
35
+ #: Puc/v4p1/Plugin/UpdateChecker.php:410
36
+ #, php-format
37
+ msgid "Unknown update checker status \"%s\""
38
+ msgstr "Status \"%s\" desconhecido."
39
+
40
+ #: Puc/v4p1/Vcs/PluginUpdateChecker.php:83
41
+ msgid "There is no changelog available."
42
+ msgstr "Não há um changelog disponível."
43
+
44
+ #~ msgid "The %s plugin is up to date."
45
+ #~ msgstr "O plugin %s já está na sua versão mais recente."
46
+
47
+ #~ msgid "A new version of the %s plugin is available."
48
+ #~ msgstr "Há uma nova versão para o plugin %s disponível para download."
app/core/puc/languages/plugin-update-checker-ru_RU.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-ru_RU.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2020-08-08 14:36+0300\n"
5
+ "PO-Revision-Date: 2021-12-20 17:59+0200\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.2\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: ru_RU\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p11/Plugin/Ui.php:128
20
+ msgid "Check for updates"
21
+ msgstr "Проверить обновления"
22
+
23
+ #: Puc/v4p11/Plugin/Ui.php:213
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "Плагин %s обновлён."
28
+
29
+ #: Puc/v4p11/Plugin/Ui.php:215
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Новая версия %s доступна."
34
+
35
+ #: Puc/v4p11/Plugin/Ui.php:217
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "Не удалось определить, доступны ли обновления для %s."
40
+
41
+ #: Puc/v4p11/Plugin/Ui.php:223
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Неизвестный статус средства проверки обновлений \"%s\""
45
+
46
+ #: Puc/v4p11/Vcs/PluginUpdateChecker.php:98
47
+ msgid "There is no changelog available."
48
+ msgstr "Журнал изменений отсутствует."
app/core/puc/languages/plugin-update-checker-sl_SI.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-sl_SI.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2018-10-27 20:36+0200\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.2\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100>=3 && n%100<=4 ? 2 : 3);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: Igor Funa\n"
16
+ "Language: sl_SI\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Preveri posodobitve"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "Vtičnik %s je že posodobljen."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Nova različica vtičnika %s je na razpolago."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "Ne morem ugotoviti če se za vtičnik %s na razpolago posodobitve."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Neznan status preverjanja posodobitev za \"%s\""
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "Dnevnik sprememb ni na razpolago."
app/core/puc/languages/plugin-update-checker-sv_SE.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-sv_SE.po ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-05-20 10:53+0300\n"
5
+ "PO-Revision-Date: 2017-10-16 15:02+0200\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.0.4\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: sv_SE\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p1/Plugin/UpdateChecker.php:358
20
+ msgid "Check for updates"
21
+ msgstr "Sök efter uppdateringar"
22
+
23
+ #: Puc/v4p1/Plugin/UpdateChecker.php:405
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "Tillägget %s är uppdaterat."
28
+
29
+ #: Puc/v4p1/Plugin/UpdateChecker.php:407
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Det finns en ny version av tillägget %s."
34
+
35
+ #: Puc/v4p1/Plugin/UpdateChecker.php:409
36
+ #, php-format
37
+ msgid "Unknown update checker status \"%s\""
38
+ msgstr "Okänd status för kontroll av uppdatering “%s”"
39
+
40
+ #: Puc/v4p1/Vcs/PluginUpdateChecker.php:83
41
+ msgid "There is no changelog available."
42
+ msgstr "Det finns ingen ändringslogg tillgänglig."
app/core/puc/languages/plugin-update-checker-tr_TR.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-tr_TR.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2021-11-15 19:07+0300\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 3.0\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: Emre Erkan <kara@karalamalar.net>\n"
16
+ "Language: tr\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Güncellemeleri kontrol et"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "%s eklentisi güncel."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "%s eklentisinin yeni bir sürümü mevcut."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "%s için güncelleme olup olmadığı belirlenemedi."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Bilinmeyen güncelleme denetleyicisi durumu \"%s\""
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "Kullanılabilir bir değişiklik yok."
app/core/puc/languages/plugin-update-checker-uk_UA.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-uk_UA.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2020-08-08 14:36+0300\n"
5
+ "PO-Revision-Date: 2021-12-20 17:55+0200\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.2\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: uk_UA\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p11/Plugin/Ui.php:128
20
+ msgid "Check for updates"
21
+ msgstr "Перевірити оновлення"
22
+
23
+ #: Puc/v4p11/Plugin/Ui.php:213
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "Плагін %s оновлено."
28
+
29
+ #: Puc/v4p11/Plugin/Ui.php:215
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Нова версія %s доступна."
34
+
35
+ #: Puc/v4p11/Plugin/Ui.php:217
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "Не вдалося визначити, чи доступні оновлення для %s."
40
+
41
+ #: Puc/v4p11/Plugin/Ui.php:223
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Невідомий статус перевірки оновлень \"%s\""
45
+
46
+ #: Puc/v4p11/Vcs/PluginUpdateChecker.php:98
47
+ msgid "There is no changelog available."
48
+ msgstr "Немає доступного журналу змін."
app/core/puc/languages/plugin-update-checker-zh_CN.mo ADDED
Binary file
app/core/puc/languages/plugin-update-checker-zh_CN.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-08-04 08:10+0800\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.4\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=1; plural=0;\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: Seaton Jiang <seaton@vtrois.com>\n"
16
+ "Language: zh_CN\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "检查更新"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "%s 目前是最新版本。"
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "%s 当前有可用的更新。"
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "%s 无法确定是否有可用的更新。"
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "未知的更新检查状态:%s"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "没有可用的更新日志。"
app/core/puc/languages/plugin-update-checker.pot ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #, fuzzy
2
+ msgid ""
3
+ msgstr ""
4
+ "Project-Id-Version: plugin-update-checker\n"
5
+ "POT-Creation-Date: 2020-08-08 14:36+0300\n"
6
+ "PO-Revision-Date: 2016-01-10 20:59+0100\n"
7
+ "Last-Translator: Tamás András Horváth <htomy92@gmail.com>\n"
8
+ "Language-Team: \n"
9
+ "Language: en_US\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Generator: Poedit 2.4\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
18
+ "X-Poedit-SearchPath-0: .\n"
19
+
20
+ #: Puc/v4p11/Plugin/Ui.php:128
21
+ msgid "Check for updates"
22
+ msgstr ""
23
+
24
+ #: Puc/v4p11/Plugin/Ui.php:213
25
+ #, php-format
26
+ msgctxt "the plugin title"
27
+ msgid "The %s plugin is up to date."
28
+ msgstr ""
29
+
30
+ #: Puc/v4p11/Plugin/Ui.php:215
31
+ #, php-format
32
+ msgctxt "the plugin title"
33
+ msgid "A new version of the %s plugin is available."
34
+ msgstr ""
35
+
36
+ #: Puc/v4p11/Plugin/Ui.php:217
37
+ #, php-format
38
+ msgctxt "the plugin title"
39
+ msgid "Could not determine if updates are available for %s."
40
+ msgstr ""
41
+
42
+ #: Puc/v4p11/Plugin/Ui.php:223
43
+ #, php-format
44
+ msgid "Unknown update checker status \"%s\""
45
+ msgstr ""
46
+
47
+ #: Puc/v4p11/Vcs/PluginUpdateChecker.php:98
48
+ msgid "There is no changelog available."
49
+ msgstr ""
app/core/puc/license.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ Copyright (c) 2017 Jānis Elsts
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
app/core/puc/load-v4p11.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require dirname(__FILE__) . '/Puc/v4p11/Autoloader.php';
3
+ new Puc_v4p11_Autoloader();
4
+
5
+ require dirname(__FILE__) . '/Puc/v4p11/Factory.php';
6
+ require dirname(__FILE__) . '/Puc/v4/Factory.php';
7
+
8
+ //Register classes defined in this version with the factory.
9
+ foreach (
10
+ array(
11
+ 'Plugin_UpdateChecker' => 'Puc_v4p11_Plugin_UpdateChecker',
12
+ 'Theme_UpdateChecker' => 'Puc_v4p11_Theme_UpdateChecker',
13
+
14
+ 'Vcs_PluginUpdateChecker' => 'Puc_v4p11_Vcs_PluginUpdateChecker',
15
+ 'Vcs_ThemeUpdateChecker' => 'Puc_v4p11_Vcs_ThemeUpdateChecker',
16
+
17
+ 'GitHubApi' => 'Puc_v4p11_Vcs_GitHubApi',
18
+ 'BitBucketApi' => 'Puc_v4p11_Vcs_BitBucketApi',
19
+ 'GitLabApi' => 'Puc_v4p11_Vcs_GitLabApi',
20
+ )
21
+ as $pucGeneralClass => $pucVersionedClass
22
+ ) {
23
+ Puc_v4_Factory::addVersion($pucGeneralClass, $pucVersionedClass, '4.11');
24
+ //Also add it to the minor-version factory in case the major-version factory
25
+ //was already defined by another, older version of the update checker.
26
+ Puc_v4p11_Factory::addVersion($pucGeneralClass, $pucVersionedClass, '4.11');
27
+ }
28
+
app/core/puc/plugin-update-checker.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Update Checker Library 4.11
4
+ * http://w-shadow.com/
5
+ *
6
+ * Copyright 2021 Janis Elsts
7
+ * Released under the MIT license. See license.txt for details.
8
+ */
9
+
10
+ require dirname(__FILE__) . '/load-v4p11.php';
app/core/puc/vendor/Parsedown.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !class_exists('Parsedown', false) ) {
3
+ //Load the Parsedown version that's compatible with the current PHP version.
4
+ if ( version_compare(PHP_VERSION, '5.3.0', '>=') ) {
5
+ require __DIR__ . '/ParsedownModern.php';
6
+ } else {
7
+ require __DIR__ . '/ParsedownLegacy.php';
8
+ }
9
+ }
app/core/puc/vendor/ParsedownLegacy.php ADDED
@@ -0,0 +1,1535 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ #
4
+ #
5
+ # Parsedown
6
+ # http://parsedown.org
7
+ #
8
+ # (c) Emanuil Rusev
9
+ # http://erusev.com
10
+ #
11
+ # For the full license information, view the LICENSE file that was distributed
12
+ # with this source code.
13
+ #
14
+ #
15
+
16
+ class Parsedown
17
+ {
18
+ # ~
19
+
20
+ const version = '1.5.0';
21
+
22
+ # ~
23
+
24
+ function text($text)
25
+ {
26
+ # make sure no definitions are set
27
+ $this->DefinitionData = array();
28
+
29
+ # standardize line breaks
30
+ $text = str_replace(array("\r\n", "\r"), "\n", $text);
31
+
32
+ # remove surrounding line breaks
33
+ $text = trim($text, "\n");
34
+
35
+ # split text into lines
36
+ $lines = explode("\n", $text);
37
+
38
+ # iterate through lines to identify blocks
39
+ $markup = $this->lines($lines);
40
+
41
+ # trim line breaks
42
+ $markup = trim($markup, "\n");
43
+
44
+ return $markup;
45
+ }
46
+
47
+ #
48
+ # Setters
49
+ #
50
+
51
+ function setBreaksEnabled($breaksEnabled)
52
+ {
53
+ $this->breaksEnabled = $breaksEnabled;
54
+
55
+ return $this;
56
+ }
57
+
58
+ protected $breaksEnabled;
59
+
60
+ function setMarkupEscaped($markupEscaped)
61
+ {
62
+ $this->markupEscaped = $markupEscaped;
63
+
64
+ return $this;
65
+ }
66
+
67
+ protected $markupEscaped;
68
+
69
+ function setUrlsLinked($urlsLinked)
70
+ {
71
+ $this->urlsLinked = $urlsLinked;
72
+
73
+ return $this;
74
+ }
75
+
76
+ protected $urlsLinked = true;
77
+
78
+ #
79
+ # Lines
80
+ #
81
+
82
+ protected $BlockTypes = array(
83
+ '#' => array('Header'),
84
+ '*' => array('Rule', 'List'),
85
+ '+' => array('List'),
86
+ '-' => array('SetextHeader', 'Table', 'Rule', 'List'),
87
+ '0' => array('List'),
88
+ '1' => array('List'),
89
+ '2' => array('List'),
90
+ '3' => array('List'),
91
+ '4' => array('List'),
92
+ '5' => array('List'),
93
+ '6' => array('List'),
94
+ '7' => array('List'),
95
+ '8' => array('List'),
96
+ '9' => array('List'),
97
+ ':' => array('Table'),
98
+ '<' => array('Comment', 'Markup'),
99
+ '=' => array('SetextHeader'),
100
+ '>' => array('Quote'),
101
+ '[' => array('Reference'),
102
+ '_' => array('Rule'),
103
+ '`' => array('FencedCode'),
104
+ '|' => array('Table'),
105
+ '~' => array('FencedCode'),
106
+ );
107
+
108
+ # ~
109
+
110
+ protected $DefinitionTypes = array(
111
+ '[' => array('Reference'),
112
+ );
113
+
114
+ # ~
115
+
116
+ protected $unmarkedBlockTypes = array(
117
+ 'Code',
118
+ );
119
+
120
+ #
121
+ # Blocks
122
+ #
123
+
124
+ private function lines(array $lines)
125
+ {
126
+ $CurrentBlock = null;
127
+
128
+ foreach ($lines as $line)
129
+ {
130
+ if (chop($line) === '')
131
+ {
132
+ if (isset($CurrentBlock))
133
+ {
134
+ $CurrentBlock['interrupted'] = true;
135
+ }
136
+
137
+ continue;
138
+ }
139
+
140
+ if (strpos($line, "\t") !== false)
141
+ {
142
+ $parts = explode("\t", $line);
143
+
144
+ $line = $parts[0];
145
+
146
+ unset($parts[0]);
147
+
148
+ foreach ($parts as $part)
149
+ {
150
+ $shortage = 4 - mb_strlen($line, 'utf-8') % 4;
151
+
152
+ $line .= str_repeat(' ', $shortage);
153
+ $line .= $part;
154
+ }
155
+ }
156
+
157
+ $indent = 0;
158
+
159
+ while (isset($line[$indent]) and $line[$indent] === ' ')
160
+ {
161
+ $indent ++;
162
+ }
163
+
164
+ $text = $indent > 0 ? substr($line, $indent) : $line;
165
+
166
+ # ~
167
+
168
+ $Line = array('body' => $line, 'indent' => $indent, 'text' => $text);
169
+
170
+ # ~
171
+
172
+ if (isset($CurrentBlock['incomplete']))
173
+ {
174
+ $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock);
175
+
176
+ if (isset($Block))
177
+ {
178
+ $CurrentBlock = $Block;
179
+
180
+ continue;
181
+ }
182
+ else
183
+ {
184
+ if (method_exists($this, 'block'.$CurrentBlock['type'].'Complete'))
185
+ {
186
+ $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
187
+ }
188
+
189
+ unset($CurrentBlock['incomplete']);
190
+ }
191
+ }
192
+
193
+ # ~
194
+
195
+ $marker = $text[0];
196
+
197
+ # ~
198
+
199
+ $blockTypes = $this->unmarkedBlockTypes;
200
+
201
+ if (isset($this->BlockTypes[$marker]))
202
+ {
203
+ foreach ($this->BlockTypes[$marker] as $blockType)
204
+ {
205
+ $blockTypes []= $blockType;
206
+ }
207
+ }
208
+
209
+ #
210
+ # ~
211
+
212
+ foreach ($blockTypes as $blockType)
213
+ {
214
+ $Block = $this->{'block'.$blockType}($Line, $CurrentBlock);
215
+
216
+ if (isset($Block))
217
+ {
218
+ $Block['type'] = $blockType;
219
+
220
+ if ( ! isset($Block['identified']))
221
+ {
222
+ $Blocks []= $CurrentBlock;
223
+
224
+ $Block['identified'] = true;
225
+ }
226
+
227
+ if (method_exists($this, 'block'.$blockType.'Continue'))
228
+ {
229
+ $Block['incomplete'] = true;
230
+ }
231
+
232
+ $CurrentBlock = $Block;
233
+
234
+ continue 2;
235
+ }
236
+ }
237
+
238
+ # ~
239
+
240
+ if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
241
+ {
242
+ $CurrentBlock['element']['text'] .= "\n".$text;
243
+ }
244
+ else
245
+ {
246
+ $Blocks []= $CurrentBlock;
247
+
248
+ $CurrentBlock = $this->paragraph($Line);
249
+
250
+ $CurrentBlock['identified'] = true;
251
+ }
252
+ }
253
+
254
+ # ~
255
+
256
+ if (isset($CurrentBlock['incomplete']) and method_exists($this, 'block'.$CurrentBlock['type'].'Complete'))
257
+ {
258
+ $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
259
+ }
260
+
261
+ # ~
262
+
263
+ $Blocks []= $CurrentBlock;
264
+
265
+ unset($Blocks[0]);
266
+
267
+ # ~
268
+
269
+ $markup = '';
270
+
271
+ foreach ($Blocks as $Block)
272
+ {
273
+ if (isset($Block['hidden']))
274
+ {
275
+ continue;
276
+ }
277
+
278
+ $markup .= "\n";
279
+ $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']);
280
+ }
281
+
282
+ $markup .= "\n";
283
+
284
+ # ~
285
+
286
+ return $markup;
287
+ }
288
+
289
+ #
290
+ # Code
291
+
292
+ protected function blockCode($Line, $Block = null)
293
+ {
294
+ if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted']))
295
+ {
296
+ return;
297
+ }
298
+
299
+ if ($Line['indent'] >= 4)
300
+ {
301
+ $text = substr($Line['body'], 4);
302
+
303
+ $Block = array(
304
+ 'element' => array(
305
+ 'name' => 'pre',
306
+ 'handler' => 'element',
307
+ 'text' => array(
308
+ 'name' => 'code',
309
+ 'text' => $text,
310
+ ),
311
+ ),
312
+ );
313
+
314
+ return $Block;
315
+ }
316
+ }
317
+
318
+ protected function blockCodeContinue($Line, $Block)
319
+ {
320
+ if ($Line['indent'] >= 4)
321
+ {
322
+ if (isset($Block['interrupted']))
323
+ {
324
+ $Block['element']['text']['text'] .= "\n";
325
+
326
+ unset($Block['interrupted']);
327
+ }
328
+
329
+ $Block['element']['text']['text'] .= "\n";
330
+
331
+ $text = substr($Line['body'], 4);
332
+
333
+ $Block['element']['text']['text'] .= $text;
334
+
335
+ return $Block;
336
+ }
337
+ }
338
+
339
+ protected function blockCodeComplete($Block)
340
+ {
341
+ $text = $Block['element']['text']['text'];
342
+
343
+ $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
344
+
345
+ $Block['element']['text']['text'] = $text;
346
+
347
+ return $Block;
348
+ }
349
+
350
+ #
351
+ # Comment
352
+
353
+ protected function blockComment($Line)
354
+ {
355
+ if ($this->markupEscaped)
356
+ {
357
+ return;
358
+ }
359
+
360
+ if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
361
+ {
362
+ $Block = array(
363
+ 'markup' => $Line['body'],
364
+ );
365
+
366
+ if (preg_match('/-->$/', $Line['text']))
367
+ {
368
+ $Block['closed'] = true;
369
+ }
370
+
371
+ return $Block;
372
+ }
373
+ }
374
+
375
+ protected function blockCommentContinue($Line, array $Block)
376
+ {
377
+ if (isset($Block['closed']))
378
+ {
379
+ return;
380
+ }
381
+
382
+ $Block['markup'] .= "\n" . $Line['body'];
383
+
384
+ if (preg_match('/-->$/', $Line['text']))
385
+ {
386
+ $Block['closed'] = true;
387
+ }
388
+
389
+ return $Block;
390
+ }
391
+
392
+ #
393
+ # Fenced Code
394
+
395
+ protected function blockFencedCode($Line)
396
+ {
397
+ if (preg_match('/^(['.$Line['text'][0].']{3,})[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches))
398
+ {
399
+ $Element = array(
400
+ 'name' => 'code',
401
+ 'text' => '',
402
+ );
403
+
404
+ if (isset($matches[2]))
405
+ {
406
+ $class = 'language-'.$matches[2];
407
+
408
+ $Element['attributes'] = array(
409
+ 'class' => $class,
410
+ );
411
+ }
412
+
413
+ $Block = array(
414
+ 'char' => $Line['text'][0],
415
+ 'element' => array(
416
+ 'name' => 'pre',
417
+ 'handler' => 'element',
418
+ 'text' => $Element,
419
+ ),
420
+ );
421
+
422
+ return $Block;
423
+ }
424
+ }
425
+
426
+ protected function blockFencedCodeContinue($Line, $Block)
427
+ {
428
+ if (isset($Block['complete']))
429
+ {
430
+ return;
431
+ }
432
+
433
+ if (isset($Block['interrupted']))
434
+ {
435
+ $Block['element']['text']['text'] .= "\n";
436
+
437
+ unset($Block['interrupted']);
438
+ }
439
+
440
+ if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text']))
441
+ {
442
+ $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1);
443
+
444
+ $Block['complete'] = true;
445
+
446
+ return $Block;
447
+ }
448
+
449
+ $Block['element']['text']['text'] .= "\n".$Line['body'];;
450
+
451
+ return $Block;
452
+ }
453
+
454
+ protected function blockFencedCodeComplete($Block)
455
+ {
456
+ $text = $Block['element']['text']['text'];
457
+
458
+ $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
459
+
460
+ $Block['element']['text']['text'] = $text;
461
+
462
+ return $Block;
463
+ }
464
+
465
+ #
466
+ # Header
467
+
468
+ protected function blockHeader($Line)
469
+ {
470
+ if (isset($Line['text'][1]))
471
+ {
472
+ $level = 1;
473
+
474
+ while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
475
+ {
476
+ $level ++;
477
+ }
478
+
479
+ if ($level > 6)
480
+ {
481
+ return;
482
+ }
483
+
484
+ $text = trim($Line['text'], '# ');
485
+
486
+ $Block = array(
487
+ 'element' => array(
488
+ 'name' => 'h' . min(6, $level),
489
+ 'text' => $text,
490
+ 'handler' => 'line',
491
+ ),
492
+ );
493
+
494
+ return $Block;
495
+ }
496
+ }
497
+
498
+ #
499
+ # List
500
+
501
+ protected function blockList($Line)
502
+ {
503
+ list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');
504
+
505
+ if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches))
506
+ {
507
+ $Block = array(
508
+ 'indent' => $Line['indent'],
509
+ 'pattern' => $pattern,
510
+ 'element' => array(
511
+ 'name' => $name,
512
+ 'handler' => 'elements',
513
+ ),
514
+ );
515
+
516
+ $Block['li'] = array(
517
+ 'name' => 'li',
518
+ 'handler' => 'li',
519
+ 'text' => array(
520
+ $matches[2],
521
+ ),
522
+ );
523
+
524
+ $Block['element']['text'] []= & $Block['li'];
525
+
526
+ return $Block;
527
+ }
528
+ }
529
+
530
+ protected function blockListContinue($Line, array $Block)
531
+ {
532
+ if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches))
533
+ {
534
+ if (isset($Block['interrupted']))
535
+ {
536
+ $Block['li']['text'] []= '';
537
+
538
+ unset($Block['interrupted']);
539
+ }
540
+
541
+ unset($Block['li']);
542
+
543
+ $text = isset($matches[1]) ? $matches[1] : '';
544
+
545
+ $Block['li'] = array(
546
+ 'name' => 'li',
547
+ 'handler' => 'li',
548
+ 'text' => array(
549
+ $text,
550
+ ),
551
+ );
552
+
553
+ $Block['element']['text'] []= & $Block['li'];
554
+
555
+ return $Block;
556
+ }
557
+
558
+ if ($Line['text'][0] === '[' and $this->blockReference($Line))
559
+ {
560
+ return $Block;
561
+ }
562
+
563
+ if ( ! isset($Block['interrupted']))
564
+ {
565
+ $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
566
+
567
+ $Block['li']['text'] []= $text;
568
+
569
+ return $Block;
570
+ }
571
+
572
+ if ($Line['indent'] > 0)
573
+ {
574
+ $Block['li']['text'] []= '';
575
+
576
+ $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
577
+
578
+ $Block['li']['text'] []= $text;
579
+
580
+ unset($Block['interrupted']);
581
+
582
+ return $Block;
583
+ }
584
+ }
585
+
586
+ #
587
+ # Quote
588
+
589
+ protected function blockQuote($Line)
590
+ {
591
+ if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
592
+ {
593
+ $Block = array(
594
+ 'element' => array(
595
+ 'name' => 'blockquote',
596
+ 'handler' => 'lines',
597
+ 'text' => (array) $matches[1],
598
+ ),
599
+ );
600
+
601
+ return $Block;
602
+ }
603
+ }
604
+
605
+ protected function blockQuoteContinue($Line, array $Block)
606
+ {
607
+ if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
608
+ {
609
+ if (isset($Block['interrupted']))
610
+ {
611
+ $Block['element']['text'] []= '';
612
+
613
+ unset($Block['interrupted']);
614
+ }
615
+
616
+ $Block['element']['text'] []= $matches[1];
617
+
618
+ return $Block;
619
+ }
620
+
621
+ if ( ! isset($Block['interrupted']))
622
+ {
623
+ $Block['element']['text'] []= $Line['text'];
624
+
625
+ return $Block;
626
+ }
627
+ }
628
+
629
+ #
630
+ # Rule
631
+
632
+ protected function blockRule($Line)
633
+ {
634
+ if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text']))
635
+ {
636
+ $Block = array(
637
+ 'element' => array(
638
+ 'name' => 'hr'
639
+ ),
640
+ );
641
+
642
+ return $Block;
643
+ }
644
+ }
645
+
646
+ #
647
+ # Setext
648
+
649
+ protected function blockSetextHeader($Line, array $Block = null)
650
+ {
651
+ if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
652
+ {
653
+ return;
654
+ }
655
+
656
+ if (chop($Line['text'], $Line['text'][0]) === '')
657
+ {
658
+ $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';
659
+
660
+ return $Block;
661
+ }
662
+ }
663
+
664
+ #
665
+ # Markup
666
+
667
+ protected function blockMarkup($Line)
668
+ {
669
+ if ($this->markupEscaped)
670
+ {
671
+ return;
672
+ }
673
+
674
+ if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
675
+ {
676
+ if (in_array($matches[1], $this->textLevelElements))
677
+ {
678
+ return;
679
+ }
680
+
681
+ $Block = array(
682
+ 'name' => $matches[1],
683
+ 'depth' => 0,
684
+ 'markup' => $Line['text'],
685
+ );
686
+
687
+ $length = strlen($matches[0]);
688
+
689
+ $remainder = substr($Line['text'], $length);
690
+
691
+ if (trim($remainder) === '')
692
+ {
693
+ if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
694
+ {
695
+ $Block['closed'] = true;
696
+
697
+ $Block['void'] = true;
698
+ }
699
+ }
700
+ else
701
+ {
702
+ if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
703
+ {
704
+ return;
705
+ }
706
+
707
+ if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
708
+ {
709
+ $Block['closed'] = true;
710
+ }
711
+ }
712
+
713
+ return $Block;
714
+ }
715
+ }
716
+
717
+ protected function blockMarkupContinue($Line, array $Block)
718
+ {
719
+ if (isset($Block['closed']))
720
+ {
721
+ return;
722
+ }
723
+
724
+ if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
725
+ {
726
+ $Block['depth'] ++;
727
+ }
728
+
729
+ if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
730
+ {
731
+ if ($Block['depth'] > 0)
732
+ {
733
+ $Block['depth'] --;
734
+ }
735
+ else
736
+ {
737
+ $Block['closed'] = true;
738
+ }
739
+
740
+ $Block['markup'] .= $matches[1];
741
+ }
742
+
743
+ if (isset($Block['interrupted']))
744
+ {
745
+ $Block['markup'] .= "\n";
746
+
747
+ unset($Block['interrupted']);
748
+ }
749
+
750
+ $Block['markup'] .= "\n".$Line['body'];
751
+
752
+ return $Block;
753
+ }
754
+
755
+ #
756
+ # Reference
757
+
758
+ protected function blockReference($Line)
759
+ {
760
+ if (preg_match('/^\[(.+?)\]:[ ]*<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
761
+ {
762
+ $id = strtolower($matches[1]);
763
+
764
+ $Data = array(
765
+ 'url' => $matches[2],
766
+ 'title' => null,
767
+ );
768
+
769
+ if (isset($matches[3]))
770
+ {
771
+ $Data['title'] = $matches[3];
772
+ }
773
+
774
+ $this->DefinitionData['Reference'][$id] = $Data;
775
+
776
+ $Block = array(
777
+ 'hidden' => true,
778
+ );
779
+
780
+ return $Block;
781
+ }
782
+ }
783
+
784
+ #
785
+ # Table
786
+
787
+ protected function blockTable($Line, array $Block = null)
788
+ {
789
+ if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
790
+ {
791
+ return;
792
+ }
793
+
794
+ if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '')
795
+ {
796
+ $alignments = array();
797
+
798
+ $divider = $Line['text'];
799
+
800
+ $divider = trim($divider);
801
+ $divider = trim($divider, '|');
802
+
803
+ $dividerCells = explode('|', $divider);
804
+
805
+ foreach ($dividerCells as $dividerCell)
806
+ {
807
+ $dividerCell = trim($dividerCell);
808
+
809
+ if ($dividerCell === '')
810
+ {
811
+ continue;
812
+ }
813
+
814
+ $alignment = null;
815
+
816
+ if ($dividerCell[0] === ':')
817
+ {
818
+ $alignment = 'left';
819
+ }
820
+
821
+ if (substr($dividerCell, - 1) === ':')
822
+ {
823
+ $alignment = $alignment === 'left' ? 'center' : 'right';
824
+ }
825
+
826
+ $alignments []= $alignment;
827
+ }
828
+
829
+ # ~
830
+
831
+ $HeaderElements = array();
832
+
833
+ $header = $Block['element']['text'];
834
+
835
+ $header = trim($header);
836
+ $header = trim($header, '|');
837
+
838
+ $headerCells = explode('|', $header);
839
+
840
+ foreach ($headerCells as $index => $headerCell)
841
+ {
842
+ $headerCell = trim($headerCell);
843
+
844
+ $HeaderElement = array(
845
+ 'name' => 'th',
846
+ 'text' => $headerCell,
847
+ 'handler' => 'line',
848
+ );
849
+
850
+ if (isset($alignments[$index]))
851
+ {
852
+ $alignment = $alignments[$index];
853
+
854
+ $HeaderElement['attributes'] = array(
855
+ 'style' => 'text-align: '.$alignment.';',
856
+ );
857
+ }
858
+
859
+ $HeaderElements []= $HeaderElement;
860
+ }
861
+
862
+ # ~
863
+
864
+ $Block = array(
865
+ 'alignments' => $alignments,
866
+ 'identified' => true,
867
+ 'element' => array(
868
+ 'name' => 'table',
869
+ 'handler' => 'elements',
870
+ ),
871
+ );
872
+
873
+ $Block['element']['text'] []= array(
874
+ 'name' => 'thead',
875
+ 'handler' => 'elements',
876
+ );
877
+
878
+ $Block['element']['text'] []= array(
879
+ 'name' => 'tbody',
880
+ 'handler' => 'elements',
881
+ 'text' => array(),
882
+ );
883
+
884
+ $Block['element']['text'][0]['text'] []= array(
885
+ 'name' => 'tr',
886
+ 'handler' => 'elements',
887
+ 'text' => $HeaderElements,
888
+ );
889
+
890
+ return $Block;
891
+ }
892
+ }
893
+
894
+ protected function blockTableContinue($Line, array $Block)
895
+ {
896
+ if (isset($Block['interrupted']))
897
+ {
898
+ return;
899
+ }
900
+
901
+ if ($Line['text'][0] === '|' or strpos($Line['text'], '|'))
902
+ {
903
+ $Elements = array();
904
+
905
+ $row = $Line['text'];
906
+
907
+ $row = trim($row);
908
+ $row = trim($row, '|');
909
+
910
+ preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches);
911
+
912
+ foreach ($matches[0] as $index => $cell)
913
+ {
914
+ $cell = trim($cell);
915
+
916
+ $Element = array(
917
+ 'name' => 'td',
918
+ 'handler' => 'line',
919
+ 'text' => $cell,
920
+ );
921
+
922
+ if (isset($Block['alignments'][$index]))
923
+ {
924
+ $Element['attributes'] = array(
925
+ 'style' => 'text-align: '.$Block['alignments'][$index].';',
926
+ );
927
+ }
928
+
929
+ $Elements []= $Element;
930
+ }
931
+
932
+ $Element = array(
933
+ 'name' => 'tr',
934
+ 'handler' => 'elements',
935
+ 'text' => $Elements,
936
+ );
937
+
938
+ $Block['element']['text'][1]['text'] []= $Element;
939
+
940
+ return $Block;
941
+ }
942
+ }
943
+
944
+ #
945
+ # ~
946
+ #
947
+
948
+ protected function paragraph($Line)
949
+ {
950
+ $Block = array(
951
+ 'element' => array(
952
+ 'name' => 'p',
953
+ 'text' => $Line['text'],
954
+ 'handler' => 'line',
955
+ ),
956
+ );
957
+
958
+ return $Block;
959
+ }
960
+
961
+ #
962
+ # Inline Elements
963
+ #
964
+
965
+ protected $InlineTypes = array(
966
+ '"' => array('SpecialCharacter'),
967
+ '!' => array('Image'),
968
+ '&' => array('SpecialCharacter'),
969
+ '*' => array('Emphasis'),
970
+ ':' => array('Url'),
971
+ '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'),
972
+ '>' => array('SpecialCharacter'),
973
+ '[' => array('Link'),
974
+ '_' => array('Emphasis'),
975
+ '`' => array('Code'),
976
+ '~' => array('Strikethrough'),
977
+ '\\' => array('EscapeSequence'),
978
+ );
979
+
980
+ # ~
981
+
982
+ protected $inlineMarkerList = '!"*_&[:<>`~\\';
983
+
984
+ #
985
+ # ~
986
+ #
987
+
988
+ public function line($text)
989
+ {
990
+ $markup = '';
991
+
992
+ $unexaminedText = $text;
993
+
994
+ $markerPosition = 0;
995
+
996
+ while ($excerpt = strpbrk($unexaminedText, $this->inlineMarkerList))
997
+ {
998
+ $marker = $excerpt[0];
999
+
1000
+ $markerPosition += strpos($unexaminedText, $marker);
1001
+
1002
+ $Excerpt = array('text' => $excerpt, 'context' => $text);
1003
+
1004
+ foreach ($this->InlineTypes[$marker] as $inlineType)
1005
+ {
1006
+ $Inline = $this->{'inline'.$inlineType}($Excerpt);
1007
+
1008
+ if ( ! isset($Inline))
1009
+ {
1010
+ continue;
1011
+ }
1012
+
1013
+ if (isset($Inline['position']) and $Inline['position'] > $markerPosition) # position is ahead of marker
1014
+ {
1015
+ continue;
1016
+ }
1017
+
1018
+ if ( ! isset($Inline['position']))
1019
+ {
1020
+ $Inline['position'] = $markerPosition;
1021
+ }
1022
+
1023
+ $unmarkedText = substr($text, 0, $Inline['position']);
1024
+
1025
+ $markup .= $this->unmarkedText($unmarkedText);
1026
+
1027
+ $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']);
1028
+
1029
+ $text = substr($text, $Inline['position'] + $Inline['extent']);
1030
+
1031
+ $unexaminedText = $text;
1032
+
1033
+ $markerPosition = 0;
1034
+
1035
+ continue 2;
1036
+ }
1037
+
1038
+ $unexaminedText = substr($excerpt, 1);
1039
+
1040
+ $markerPosition ++;
1041
+ }
1042
+
1043
+ $markup .= $this->unmarkedText($text);
1044
+
1045
+ return $markup;
1046
+ }
1047
+
1048
+ #
1049
+ # ~
1050
+ #
1051
+
1052
+ protected function inlineCode($Excerpt)
1053
+ {
1054
+ $marker = $Excerpt['text'][0];
1055
+
1056
+ if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
1057
+ {
1058
+ $text = $matches[2];
1059
+ $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
1060
+ $text = preg_replace("/[ ]*\n/", ' ', $text);
1061
+
1062
+ return array(
1063
+ 'extent' => strlen($matches[0]),
1064
+ 'element' => array(
1065
+ 'name' => 'code',
1066
+ 'text' => $text,
1067
+ ),
1068
+ );
1069
+ }
1070
+ }
1071
+
1072
+ protected function inlineEmailTag($Excerpt)
1073
+ {
1074
+ if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches))
1075
+ {
1076
+ $url = $matches[1];
1077
+
1078
+ if ( ! isset($matches[2]))
1079
+ {
1080
+ $url = 'mailto:' . $url;
1081
+ }
1082
+
1083
+ return array(
1084
+ 'extent' => strlen($matches[0]),
1085
+ 'element' => array(
1086
+ 'name' => 'a',
1087
+ 'text' => $matches[1],
1088
+ 'attributes' => array(
1089
+ 'href' => $url,
1090
+ ),
1091
+ ),
1092
+ );
1093
+ }
1094
+ }
1095
+
1096
+ protected function inlineEmphasis($Excerpt)
1097
+ {
1098
+ if ( ! isset($Excerpt['text'][1]))
1099
+ {
1100
+ return;
1101
+ }
1102
+
1103
+ $marker = $Excerpt['text'][0];
1104
+
1105
+ if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
1106
+ {
1107
+ $emphasis = 'strong';
1108
+ }
1109
+ elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
1110
+ {
1111
+ $emphasis = 'em';
1112
+ }
1113
+ else
1114
+ {
1115
+ return;
1116
+ }
1117
+
1118
+ return array(
1119
+ 'extent' => strlen($matches[0]),
1120
+ 'element' => array(
1121
+ 'name' => $emphasis,
1122
+ 'handler' => 'line',
1123
+ 'text' => $matches[1],
1124
+ ),
1125
+ );
1126
+ }
1127
+
1128
+ protected function inlineEscapeSequence($Excerpt)
1129
+ {
1130
+ if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters))
1131
+ {
1132
+ return array(
1133
+ 'markup' => $Excerpt['text'][1],
1134
+ 'extent' => 2,
1135
+ );
1136
+ }
1137
+ }
1138
+
1139
+ protected function inlineImage($Excerpt)
1140
+ {
1141
+ if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
1142
+ {
1143
+ return;
1144
+ }
1145
+
1146
+ $Excerpt['text']= substr($Excerpt['text'], 1);
1147
+
1148
+ $Link = $this->inlineLink($Excerpt);
1149
+
1150
+ if ($Link === null)
1151
+ {
1152
+ return;
1153
+ }
1154
+
1155
+ $Inline = array(
1156
+ 'extent' => $Link['extent'] + 1,
1157
+ 'element' => array(
1158
+ 'name' => 'img',
1159
+ 'attributes' => array(
1160
+ 'src' => $Link['element']['attributes']['href'],
1161
+ 'alt' => $Link['element']['text'],
1162
+ ),
1163
+ ),
1164
+ );
1165
+
1166
+ $Inline['element']['attributes'] += $Link['element']['attributes'];
1167
+
1168
+ unset($Inline['element']['attributes']['href']);
1169
+
1170
+ return $Inline;
1171
+ }
1172
+
1173
+ protected function inlineLink($Excerpt)
1174
+ {
1175
+ $Element = array(
1176
+ 'name' => 'a',
1177
+ 'handler' => 'line',
1178
+ 'text' => null,
1179
+ 'attributes' => array(
1180
+ 'href' => null,
1181
+ 'title' => null,
1182
+ ),
1183
+ );
1184
+
1185
+ $extent = 0;
1186
+
1187
+ $remainder = $Excerpt['text'];
1188
+
1189
+ if (preg_match('/\[((?:[^][]|(?R))*)\]/', $remainder, $matches))
1190
+ {
1191
+ $Element['text'] = $matches[1];
1192
+
1193
+ $extent += strlen($matches[0]);
1194
+
1195
+ $remainder = substr($remainder, $extent);
1196
+ }
1197
+ else
1198
+ {
1199
+ return;
1200
+ }
1201
+
1202
+ if (preg_match('/^[(]((?:[^ (]|[(][^ )]+[)])+)(?:[ ]+("[^"]+"|\'[^\']+\'))?[)]/', $remainder, $matches))
1203
+ {
1204
+ $Element['attributes']['href'] = $matches[1];
1205
+
1206
+ if (isset($matches[2]))
1207
+ {
1208
+ $Element['attributes']['title'] = substr($matches[2], 1, - 1);
1209
+ }
1210
+
1211
+ $extent += strlen($matches[0]);
1212
+ }
1213
+ else
1214
+ {
1215
+ if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
1216
+ {
1217
+ $definition = $matches[1] ? $matches[1] : $Element['text'];
1218
+ $definition = strtolower($definition);
1219
+
1220
+ $extent += strlen($matches[0]);
1221
+ }
1222
+ else
1223
+ {
1224
+ $definition = strtolower($Element['text']);
1225
+ }
1226
+
1227
+ if ( ! isset($this->DefinitionData['Reference'][$definition]))
1228
+ {
1229
+ return;
1230
+ }
1231
+
1232
+ $Definition = $this->DefinitionData['Reference'][$definition];
1233
+
1234
+ $Element['attributes']['href'] = $Definition['url'];
1235
+ $Element['attributes']['title'] = $Definition['title'];
1236
+ }
1237
+
1238
+ $Element['attributes']['href'] = str_replace(array('&', '<'), array('&amp;', '&lt;'), $Element['attributes']['href']);
1239
+
1240
+ return array(
1241
+ 'extent' => $extent,
1242
+ 'element' => $Element,
1243
+ );
1244
+ }
1245
+
1246
+ protected function inlineMarkup($Excerpt)
1247
+ {
1248
+ if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false)
1249
+ {
1250
+ return;
1251
+ }
1252
+
1253
+ if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches))
1254
+ {
1255
+ return array(
1256
+ 'markup' => $matches[0],
1257
+ 'extent' => strlen($matches[0]),
1258
+ );
1259
+ }
1260
+
1261
+ if ($Excerpt['text'][1] === '!' and preg_match('/^<!---?[^>-](?:-?[^-])*-->/s', $Excerpt['text'], $matches))
1262
+ {
1263
+ return array(
1264
+ 'markup' => $matches[0],
1265
+ 'extent' => strlen($matches[0]),
1266
+ );
1267
+ }
1268
+
1269
+ if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
1270
+ {
1271
+ return array(
1272
+ 'markup' => $matches[0],
1273
+ 'extent' => strlen($matches[0]),
1274
+ );
1275
+ }
1276
+ }
1277
+
1278
+ protected function inlineSpecialCharacter($Excerpt)
1279
+ {
1280
+ if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text']))
1281
+ {
1282
+ return array(
1283
+ 'markup' => '&amp;',
1284
+ 'extent' => 1,
1285
+ );
1286
+ }
1287
+
1288
+ $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
1289
+
1290
+ if (isset($SpecialCharacter[$Excerpt['text'][0]]))
1291
+ {
1292
+ return array(
1293
+ 'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';',
1294
+ 'extent' => 1,
1295
+ );
1296
+ }
1297
+ }
1298
+
1299
+ protected function inlineStrikethrough($Excerpt)
1300
+ {
1301
+ if ( ! isset($Excerpt['text'][1]))
1302
+ {
1303
+ return;
1304
+ }
1305
+
1306
+ if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
1307
+ {
1308
+ return array(
1309
+ 'extent' => strlen($matches[0]),
1310
+ 'element' => array(
1311
+ 'name' => 'del',
1312
+ 'text' => $matches[1],
1313
+ 'handler' => 'line',
1314
+ ),
1315
+ );
1316
+ }
1317
+ }
1318
+
1319
+ protected function inlineUrl($Excerpt)
1320
+ {
1321
+ if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
1322
+ {
1323
+ return;
1324
+ }
1325
+
1326
+ if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
1327
+ {
1328
+ $Inline = array(
1329
+ 'extent' => strlen($matches[0][0]),
1330
+ 'position' => $matches[0][1],
1331
+ 'element' => array(
1332
+ 'name' => 'a',
1333
+ 'text' => $matches[0][0],
1334
+ 'attributes' => array(
1335
+ 'href' => $matches[0][0],
1336
+ ),
1337
+ ),
1338
+ );
1339
+
1340
+ return $Inline;
1341
+ }
1342
+ }
1343
+
1344
+ protected function inlineUrlTag($Excerpt)
1345
+ {
1346
+ if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
1347
+ {
1348
+ $url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $matches[1]);
1349
+
1350
+ return array(
1351
+ 'extent' => strlen($matches[0]),
1352
+ 'element' => array(
1353
+ 'name' => 'a',
1354
+ 'text' => $url,
1355
+ 'attributes' => array(
1356
+ 'href' => $url,
1357
+ ),
1358
+ ),
1359
+ );
1360
+ }
1361
+ }
1362
+
1363
+ #
1364
+ # ~
1365
+
1366
+ protected $unmarkedInlineTypes = array("\n" => 'Break', '://' => 'Url');
1367
+
1368
+ # ~
1369
+
1370
+ protected function unmarkedText($text)
1371
+ {
1372
+ if ($this->breaksEnabled)
1373
+ {
1374
+ $text = preg_replace('/[ ]*\n/', "<br />\n", $text);
1375
+ }
1376
+ else
1377
+ {
1378
+ $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "<br />\n", $text);
1379
+ $text = str_replace(" \n", "\n", $text);
1380
+ }
1381
+
1382
+ return $text;
1383
+ }
1384
+
1385
+ #
1386
+ # Handlers
1387
+ #
1388
+
1389
+ protected function element(array $Element)
1390
+ {
1391
+ $markup = '<'.$Element['name'];
1392
+
1393
+ if (isset($Element['attributes']))
1394
+ {
1395
+ foreach ($Element['attributes'] as $name => $value)
1396
+ {
1397
+ if ($value === null)
1398
+ {
1399
+ continue;
1400
+ }
1401
+
1402
+ $markup .= ' '.$name.'="'.$value.'"';
1403
+ }
1404
+ }
1405
+
1406
+ if (isset($Element['text']))
1407
+ {
1408
+ $markup .= '>';
1409
+
1410
+ if (isset($Element['handler']))
1411
+ {
1412
+ $markup .= $this->{$Element['handler']}($Element['text']);
1413
+ }
1414
+ else
1415
+ {
1416
+ $markup .= $Element['text'];
1417
+ }
1418
+
1419
+ $markup .= '</'.$Element['name'].'>';
1420
+ }
1421
+ else
1422
+ {
1423
+ $markup .= ' />';
1424
+ }
1425
+
1426
+ return $markup;
1427
+ }
1428
+
1429
+ protected function elements(array $Elements)
1430
+ {
1431
+ $markup = '';
1432
+
1433
+ foreach ($Elements as $Element)
1434
+ {
1435
+ $markup .= "\n" . $this->element($Element);
1436
+ }
1437
+
1438
+ $markup .= "\n";
1439
+
1440
+ return $markup;
1441
+ }
1442
+
1443
+ # ~
1444
+
1445
+ protected function li($lines)
1446
+ {
1447
+ $markup = $this->lines($lines);
1448
+
1449
+ $trimmedMarkup = trim($markup);
1450
+
1451
+ if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '<p>')
1452
+ {
1453
+ $markup = $trimmedMarkup;
1454
+ $markup = substr($markup, 3);
1455
+
1456
+ $position = strpos($markup, "</p>");
1457
+
1458
+ $markup = substr_replace($markup, '', $position, 4);
1459
+ }
1460
+
1461
+ return $markup;
1462
+ }
1463
+
1464
+ #
1465
+ # Deprecated Methods
1466
+ #
1467
+
1468
+ function parse($text)
1469
+ {
1470
+ $markup = $this->text($text);
1471
+
1472
+ return $markup;
1473
+ }
1474
+
1475
+ #
1476
+ # Static Methods
1477
+ #
1478
+
1479
+ static function instance($name = 'default')
1480
+ {
1481
+ if (isset(self::$instances[$name]))
1482
+ {
1483
+ return self::$instances[$name];
1484
+ }
1485
+
1486
+ $instance = new self();
1487
+
1488
+ self::$instances[$name] = $instance;
1489
+
1490
+ return $instance;
1491
+ }
1492
+
1493
+ private static $instances = array();
1494
+
1495
+ #
1496
+ # Fields
1497
+ #
1498
+
1499
+ protected $DefinitionData;
1500
+
1501
+ #
1502
+ # Read-Only
1503
+
1504
+ protected $specialCharacters = array(
1505
+ '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|',
1506
+ );
1507
+
1508
+ protected $StrongRegex = array(
1509
+ '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s',
1510
+ '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us',
1511
+ );
1512
+
1513
+ protected $EmRegex = array(
1514
+ '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s',
1515
+ '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
1516
+ );
1517
+
1518
+ protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?';
1519
+
1520
+ protected $voidElements = array(
1521
+ 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
1522
+ );
1523
+
1524
+ protected $textLevelElements = array(
1525
+ 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont',
1526
+ 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing',
1527
+ 'i', 'rp', 'del', 'code', 'strike', 'marquee',
1528
+ 'q', 'rt', 'ins', 'font', 'strong',
1529
+ 's', 'tt', 'sub', 'mark',
1530
+ 'u', 'xm', 'sup', 'nobr',
1531
+ 'var', 'ruby',
1532
+ 'wbr', 'span',
1533
+ 'time',
1534
+ );
1535
+ }
app/core/puc/vendor/ParsedownModern.php ADDED
@@ -0,0 +1,1538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ #
4
+ #
5
+ # Parsedown
6
+ # http://parsedown.org
7
+ #
8
+ # (c) Emanuil Rusev
9
+ # http://erusev.com
10
+ #
11
+ # For the full license information, view the LICENSE file that was distributed
12
+ # with this source code.
13
+ #
14
+ #
15
+
16
+ class Parsedown
17
+ {
18
+ # ~
19
+
20
+ const version = '1.6.0';
21
+
22
+ # ~
23
+
24
+ function text($text)
25
+ {
26
+ # make sure no definitions are set
27
+ $this->DefinitionData = array();
28
+
29
+ # standardize line breaks
30
+ $text = str_replace(array("\r\n", "\r"), "\n", $text);
31
+
32
+ # remove surrounding line breaks
33
+ $text = trim($text, "\n");
34
+
35
+ # split text into lines
36
+ $lines = explode("\n", $text);
37
+
38
+ # iterate through lines to identify blocks
39
+ $markup = $this->lines($lines);
40
+
41
+ # trim line breaks
42
+ $markup = trim($markup, "\n");
43
+
44
+ return $markup;
45
+ }
46
+
47
+ #
48
+ # Setters
49
+ #
50
+
51
+ function setBreaksEnabled($breaksEnabled)
52
+ {
53
+ $this->breaksEnabled = $breaksEnabled;
54
+
55
+ return $this;
56
+ }
57
+
58
+ protected $breaksEnabled;
59
+
60
+ function setMarkupEscaped($markupEscaped)
61
+ {
62
+ $this->markupEscaped = $markupEscaped;
63
+
64
+ return $this;
65
+ }
66
+
67
+ protected $markupEscaped;
68
+
69
+ function setUrlsLinked($urlsLinked)
70
+ {
71
+ $this->urlsLinked = $urlsLinked;
72
+
73
+ return $this;
74
+ }
75
+
76
+ protected $urlsLinked = true;
77
+
78
+ #
79
+ # Lines
80
+ #
81
+
82
+ protected $BlockTypes = array(
83
+ '#' => array('Header'),
84
+ '*' => array('Rule', 'List'),
85
+ '+' => array('List'),
86
+ '-' => array('SetextHeader', 'Table', 'Rule', 'List'),
87
+ '0' => array('List'),
88
+ '1' => array('List'),
89
+ '2' => array('List'),
90
+ '3' => array('List'),
91
+ '4' => array('List'),
92
+ '5' => array('List'),
93
+ '6' => array('List'),
94
+ '7' => array('List'),
95
+ '8' => array('List'),
96
+ '9' => array('List'),
97
+ ':' => array('Table'),
98
+ '<' => array('Comment', 'Markup'),
99
+ '=' => array('SetextHeader'),
100
+ '>' => array('Quote'),
101
+ '[' => array('Reference'),
102
+ '_' => array('Rule'),
103
+ '`' => array('FencedCode'),
104
+ '|' => array('Table'),
105
+ '~' => array('FencedCode'),
106
+ );
107
+
108
+ # ~
109
+
110
+ protected $unmarkedBlockTypes = array(
111
+ 'Code',
112
+ );
113
+
114
+ #
115
+ # Blocks
116
+ #
117
+
118
+ protected function lines(array $lines)
119
+ {
120
+ $CurrentBlock = null;
121
+
122
+ foreach ($lines as $line)
123
+ {
124
+ if (chop($line) === '')
125
+ {
126
+ if (isset($CurrentBlock))
127
+ {
128
+ $CurrentBlock['interrupted'] = true;
129
+ }
130
+
131
+ continue;
132
+ }
133
+
134
+ if (strpos($line, "\t") !== false)
135
+ {
136
+ $parts = explode("\t", $line);
137
+
138
+ $line = $parts[0];
139
+
140
+ unset($parts[0]);
141
+
142
+ foreach ($parts as $part)
143
+ {
144
+ $shortage = 4 - mb_strlen($line, 'utf-8') % 4;
145
+
146
+ $line .= str_repeat(' ', $shortage);
147
+ $line .= $part;
148
+ }
149
+ }
150
+
151
+ $indent = 0;
152
+
153
+ while (isset($line[$indent]) and $line[$indent] === ' ')
154
+ {
155
+ $indent ++;
156
+ }
157
+
158
+ $text = $indent > 0 ? substr($line, $indent) : $line;
159
+
160
+ # ~
161
+
162
+ $Line = array('body' => $line, 'indent' => $indent, 'text' => $text);
163
+
164
+ # ~
165
+
166
+ if (isset($CurrentBlock['continuable']))
167
+ {
168
+ $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock);
169
+
170
+ if (isset($Block))
171
+ {
172
+ $CurrentBlock = $Block;
173
+
174
+ continue;
175
+ }
176
+ else
177
+ {
178
+ if ($this->isBlockCompletable($CurrentBlock['type']))
179
+ {
180
+ $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
181
+ }
182
+ }
183
+ }
184
+
185
+ # ~
186
+
187
+ $marker = $text[0];
188
+
189
+ # ~
190
+
191
+ $blockTypes = $this->unmarkedBlockTypes;
192
+
193
+ if (isset($this->BlockTypes[$marker]))
194
+ {
195
+ foreach ($this->BlockTypes[$marker] as $blockType)
196
+ {
197
+ $blockTypes []= $blockType;
198
+ }
199
+ }
200
+
201
+ #
202
+ # ~
203
+
204
+ foreach ($blockTypes as $blockType)
205
+ {
206
+ $Block = $this->{'block'.$blockType}($Line, $CurrentBlock);
207
+
208
+ if (isset($Block))
209
+ {
210
+ $Block['type'] = $blockType;
211
+
212
+ if ( ! isset($Block['identified']))
213
+ {
214
+ $Blocks []= $CurrentBlock;
215
+
216
+ $Block['identified'] = true;
217
+ }
218
+
219
+ if ($this->isBlockContinuable($blockType))
220
+ {
221
+ $Block['continuable'] = true;
222
+ }
223
+
224
+ $CurrentBlock = $Block;
225
+
226
+ continue 2;
227
+ }
228
+ }
229
+
230
+ # ~
231
+
232
+ if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
233
+ {
234
+ $CurrentBlock['element']['text'] .= "\n".$text;
235
+ }
236
+ else
237
+ {
238
+ $Blocks []= $CurrentBlock;
239
+
240
+ $CurrentBlock = $this->paragraph($Line);
241
+
242
+ $CurrentBlock['identified'] = true;
243
+ }
244
+ }
245
+
246
+ # ~
247
+
248
+ if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type']))
249
+ {
250
+ $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
251
+ }
252
+
253
+ # ~
254
+
255
+ $Blocks []= $CurrentBlock;
256
+
257
+ unset($Blocks[0]);
258
+
259
+ # ~
260
+
261
+ $markup = '';
262
+
263
+ foreach ($Blocks as $Block)
264
+ {
265
+ if (isset($Block['hidden']))
266
+ {
267
+ continue;
268
+ }
269
+
270
+ $markup .= "\n";
271
+ $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']);
272
+ }
273
+
274
+ $markup .= "\n";
275
+
276
+ # ~
277
+
278
+ return $markup;
279
+ }
280
+
281
+ protected function isBlockContinuable($Type)
282
+ {
283
+ return method_exists($this, 'block'.$Type.'Continue');
284
+ }
285
+
286
+ protected function isBlockCompletable($Type)
287
+ {
288
+ return method_exists($this, 'block'.$Type.'Complete');
289
+ }
290
+
291
+ #
292
+ # Code
293
+
294
+ protected function blockCode($Line, $Block = null)
295
+ {
296
+ if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted']))
297
+ {
298
+ return;
299
+ }
300
+
301
+ if ($Line['indent'] >= 4)
302
+ {
303
+ $text = substr($Line['body'], 4);
304
+
305
+ $Block = array(
306
+ 'element' => array(
307
+ 'name' => 'pre',
308
+ 'handler' => 'element',
309
+ 'text' => array(
310
+ 'name' => 'code',
311
+ 'text' => $text,
312
+ ),
313
+ ),
314
+ );
315
+
316
+ return $Block;
317
+ }
318
+ }
319
+
320
+ protected function blockCodeContinue($Line, $Block)
321
+ {
322
+ if ($Line['indent'] >= 4)
323
+ {
324
+ if (isset($Block['interrupted']))
325
+ {
326
+ $Block['element']['text']['text'] .= "\n";
327
+
328
+ unset($Block['interrupted']);
329
+ }
330
+
331
+ $Block['element']['text']['text'] .= "\n";
332
+
333
+ $text = substr($Line['body'], 4);
334
+
335
+ $Block['element']['text']['text'] .= $text;
336
+
337
+ return $Block;
338
+ }
339
+ }
340
+
341
+ protected function blockCodeComplete($Block)
342
+ {
343
+ $text = $Block['element']['text']['text'];
344
+
345
+ $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
346
+
347
+ $Block['element']['text']['text'] = $text;
348
+
349
+ return $Block;
350
+ }
351
+
352
+ #
353
+ # Comment
354
+
355
+ protected function blockComment($Line)
356
+ {
357
+ if ($this->markupEscaped)
358
+ {
359
+ return;
360
+ }
361
+
362
+ if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
363
+ {
364
+ $Block = array(
365
+ 'markup' => $Line['body'],
366
+ );
367
+
368
+ if (preg_match('/-->$/', $Line['text']))
369
+ {
370
+ $Block['closed'] = true;
371
+ }
372
+
373
+ return $Block;
374
+ }
375
+ }
376
+
377
+ protected function blockCommentContinue($Line, array $Block)
378
+ {
379
+ if (isset($Block['closed']))
380
+ {
381
+ return;
382
+ }
383
+
384
+ $Block['markup'] .= "\n" . $Line['body'];
385
+
386
+ if (preg_match('/-->$/', $Line['text']))
387
+ {
388
+ $Block['closed'] = true;
389
+ }
390
+
391
+ return $Block;
392
+ }
393
+
394
+ #
395
+ # Fenced Code
396
+
397
+ protected function blockFencedCode($Line)
398
+ {
399
+ if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches))
400
+ {
401
+ $Element = array(
402
+ 'name' => 'code',
403
+ 'text' => '',
404
+ );
405
+
406
+ if (isset($matches[1]))
407
+ {
408
+ $class = 'language-'.$matches[1];
409
+
410
+ $Element['attributes'] = array(
411
+ 'class' => $class,
412
+ );
413
+ }
414
+
415
+ $Block = array(
416
+ 'char' => $Line['text'][0],
417
+ 'element' => array(
418
+ 'name' => 'pre',
419
+ 'handler' => 'element',
420
+ 'text' => $Element,
421
+ ),
422
+ );
423
+
424
+ return $Block;
425
+ }
426
+ }
427
+
428
+ protected function blockFencedCodeContinue($Line, $Block)
429
+ {
430
+ if (isset($Block['complete']))
431
+ {
432
+ return;
433
+ }
434
+
435
+ if (isset($Block['interrupted']))
436
+ {
437
+ $Block['element']['text']['text'] .= "\n";
438
+
439
+ unset($Block['interrupted']);
440
+ }
441
+
442
+ if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text']))
443
+ {
444
+ $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1);
445
+
446
+ $Block['complete'] = true;
447
+
448
+ return $Block;
449
+ }
450
+
451
+ $Block['element']['text']['text'] .= "\n".$Line['body'];;
452
+
453
+ return $Block;
454
+ }
455
+
456
+ protected function blockFencedCodeComplete($Block)
457
+ {
458
+ $text = $Block['element']['text']['text'];
459
+
460
+ $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
461
+
462
+ $Block['element']['text']['text'] = $text;
463
+
464
+ return $Block;
465
+ }
466
+
467
+ #
468
+ # Header
469
+
470
+ protected function blockHeader($Line)
471
+ {
472
+ if (isset($Line['text'][1]))
473
+ {
474
+ $level = 1;
475
+
476
+ while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
477
+ {
478
+ $level ++;
479
+ }
480
+
481
+ if ($level > 6)
482
+ {
483
+ return;
484
+ }
485
+
486
+ $text = trim($Line['text'], '# ');
487
+
488
+ $Block = array(
489
+ 'element' => array(
490
+ 'name' => 'h' . min(6, $level),
491
+ 'text' => $text,
492
+ 'handler' => 'line',
493
+ ),
494
+ );
495
+
496
+ return $Block;
497
+ }
498
+ }
499
+
500
+ #
501
+ # List
502
+
503
+ protected function blockList($Line)
504
+ {
505
+ list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');
506
+
507
+ if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches))
508
+ {
509
+ $Block = array(
510
+ 'indent' => $Line['indent'],
511
+ 'pattern' => $pattern,
512
+ 'element' => array(
513
+ 'name' => $name,
514
+ 'handler' => 'elements',
515
+ ),
516
+ );
517
+
518
+ $Block['li'] = array(
519
+ 'name' => 'li',
520
+ 'handler' => 'li',
521
+ 'text' => array(
522
+ $matches[2],
523
+ ),
524
+ );
525
+
526
+ $Block['element']['text'] []= & $Block['li'];
527
+
528
+ return $Block;
529
+ }
530
+ }
531
+
532
+ protected function blockListContinue($Line, array $Block)
533
+ {
534
+ if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches))
535
+ {
536
+ if (isset($Block['interrupted']))
537
+ {
538
+ $Block['li']['text'] []= '';
539
+
540
+ unset($Block['interrupted']);
541
+ }
542
+
543
+ unset($Block['li']);
544
+
545
+ $text = isset($matches[1]) ? $matches[1] : '';
546
+
547
+ $Block['li'] = array(
548
+ 'name' => 'li',
549
+ 'handler' => 'li',
550
+ 'text' => array(
551
+ $text,
552
+ ),
553
+ );
554
+
555
+ $Block['element']['text'] []= & $Block['li'];
556
+
557
+ return $Block;
558
+ }
559
+
560
+ if ($Line['text'][0] === '[' and $this->blockReference($Line))
561
+ {
562
+ return $Block;
563
+ }
564
+
565
+ if ( ! isset($Block['interrupted']))
566
+ {
567
+ $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
568
+
569
+ $Block['li']['text'] []= $text;
570
+
571
+ return $Block;
572
+ }
573
+
574
+ if ($Line['indent'] > 0)
575
+ {
576
+ $Block['li']['text'] []= '';
577
+
578
+ $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
579
+
580
+ $Block['li']['text'] []= $text;
581
+
582
+ unset($Block['interrupted']);
583
+
584
+ return $Block;
585
+ }
586
+ }
587
+
588
+ #
589
+ # Quote
590
+
591
+ protected function blockQuote($Line)
592
+ {
593
+ if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
594
+ {
595
+ $Block = array(
596
+ 'element' => array(
597
+ 'name' => 'blockquote',
598
+ 'handler' => 'lines',
599
+ 'text' => (array) $matches[1],
600
+ ),
601
+ );
602
+
603
+ return $Block;
604
+ }
605
+ }
606
+
607
+ protected function blockQuoteContinue($Line, array $Block)
608
+ {
609
+ if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
610
+ {
611
+ if (isset($Block['interrupted']))
612
+ {
613
+ $Block['element']['text'] []= '';
614
+
615
+ unset($Block['interrupted']);
616
+ }
617
+
618
+ $Block['element']['text'] []= $matches[1];
619
+
620
+ return $Block;
621
+ }
622
+
623
+ if ( ! isset($Block['interrupted']))
624
+ {
625
+ $Block['element']['text'] []= $Line['text'];
626
+
627
+ return $Block;
628
+ }
629
+ }
630
+
631
+ #
632
+ # Rule
633
+
634
+ protected function blockRule($Line)
635
+ {
636
+ if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text']))
637
+ {
638
+ $Block = array(
639
+ 'element' => array(
640
+ 'name' => 'hr'
641
+ ),
642
+ );
643
+
644
+ return $Block;
645
+ }
646
+ }
647
+
648
+ #
649
+ # Setext
650
+
651
+ protected function blockSetextHeader($Line, array $Block = null)
652
+ {
653
+ if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
654
+ {
655
+ return;
656
+ }
657
+
658
+ if (chop($Line['text'], $Line['text'][0]) === '')
659
+ {
660
+ $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';
661
+
662
+ return $Block;
663
+ }
664
+ }
665
+
666
+ #
667
+ # Markup
668
+
669
+ protected function blockMarkup($Line)
670
+ {
671
+ if ($this->markupEscaped)
672
+ {
673
+ return;
674
+ }
675
+
676
+ if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
677
+ {
678
+ $element = strtolower($matches[1]);
679
+
680
+ if (in_array($element, $this->textLevelElements))
681
+ {
682
+ return;
683
+ }
684
+
685
+ $Block = array(
686
+ 'name' => $matches[1],
687
+ 'depth' => 0,
688
+ 'markup' => $Line['text'],
689
+ );
690
+
691
+ $length = strlen($matches[0]);
692
+
693
+ $remainder = substr($Line['text'], $length);
694
+
695
+ if (trim($remainder) === '')
696
+ {
697
+ if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
698
+ {
699
+ $Block['closed'] = true;
700
+
701
+ $Block['void'] = true;
702
+ }
703
+ }
704
+ else
705
+ {
706
+ if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
707
+ {
708
+ return;
709
+ }
710
+
711
+ if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
712
+ {
713
+ $Block['closed'] = true;
714
+ }
715
+ }
716
+
717
+ return $Block;
718
+ }
719
+ }
720
+
721
+ protected function blockMarkupContinue($Line, array $Block)
722
+ {
723
+ if (isset($Block['closed']))
724
+ {
725
+ return;
726
+ }
727
+
728
+ if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
729
+ {
730
+ $Block['depth'] ++;
731
+ }
732
+
733
+ if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
734
+ {
735
+ if ($Block['depth'] > 0)
736
+ {
737
+ $Block['depth'] --;
738
+ }
739
+ else
740
+ {
741
+ $Block['closed'] = true;
742
+ }
743
+ }
744
+
745
+ if (isset($Block['interrupted']))
746
+ {
747
+ $Block['markup'] .= "\n";
748
+
749
+ unset($Block['interrupted']);
750
+ }
751
+
752
+ $Block['markup'] .= "\n".$Line['body'];
753
+
754
+ return $Block;
755
+ }
756
+
757
+ #
758
+ # Reference
759
+
760
+ protected function blockReference($Line)
761
+ {
762
+ if (preg_match('/^\[(.+?)\]:[ ]*<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
763
+ {
764
+ $id = strtolower($matches[1]);
765
+
766
+ $Data = array(
767
+ 'url' => $matches[2],
768
+ 'title' => null,
769
+ );
770
+
771
+ if (isset($matches[3]))
772
+ {
773
+ $Data['title'] = $matches[3];
774
+ }
775
+
776
+ $this->DefinitionData['Reference'][$id] = $Data;
777
+
778
+ $Block = array(
779
+ 'hidden' => true,
780
+ );
781
+
782
+ return $Block;
783
+ }
784
+ }
785
+
786
+ #
787
+ # Table
788
+
789
+ protected function blockTable($Line, array $Block = null)
790
+ {
791
+ if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
792
+ {
793
+ return;
794
+ }
795
+
796
+ if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '')
797
+ {
798
+ $alignments = array();
799
+
800
+ $divider = $Line['text'];
801
+
802
+ $divider = trim($divider);
803
+ $divider = trim($divider, '|');
804
+
805
+ $dividerCells = explode('|', $divider);
806
+
807
+ foreach ($dividerCells as $dividerCell)
808
+ {
809
+ $dividerCell = trim($dividerCell);
810
+
811
+ if ($dividerCell === '')
812
+ {
813
+ continue;
814
+ }
815
+
816
+ $alignment = null;
817
+
818
+ if ($dividerCell[0] === ':')
819
+ {
820
+ $alignment = 'left';
821
+ }
822
+
823
+ if (substr($dividerCell, - 1) === ':')
824
+ {
825
+ $alignment = $alignment === 'left' ? 'center' : 'right';
826
+ }
827
+
828
+ $alignments []= $alignment;
829
+ }
830
+
831
+ # ~
832
+
833
+ $HeaderElements = array();
834
+
835
+ $header = $Block['element']['text'];
836
+
837
+ $header = trim($header);
838
+ $header = trim($header, '|');
839
+
840
+ $headerCells = explode('|', $header);
841
+
842
+ foreach ($headerCells as $index => $headerCell)
843
+ {
844
+ $headerCell = trim($headerCell);
845
+
846
+ $HeaderElement = array(
847
+ 'name' => 'th',
848
+ 'text' => $headerCell,
849
+ 'handler' => 'line',
850
+ );
851
+
852
+ if (isset($alignments[$index]))
853
+ {
854
+ $alignment = $alignments[$index];
855
+
856
+ $HeaderElement['attributes'] = array(
857
+ 'style' => 'text-align: '.$alignment.';',
858
+ );
859
+ }
860
+
861
+ $HeaderElements []= $HeaderElement;
862
+ }
863
+
864
+ # ~
865
+
866
+ $Block = array(
867
+ 'alignments' => $alignments,
868
+ 'identified' => true,
869
+ 'element' => array(
870
+ 'name' => 'table',
871
+ 'handler' => 'elements',
872
+ ),
873
+ );
874
+
875
+ $Block['element']['text'] []= array(
876
+ 'name' => 'thead',
877
+ 'handler' => 'elements',
878
+ );
879
+
880
+ $Block['element']['text'] []= array(
881
+ 'name' => 'tbody',
882
+ 'handler' => 'elements',
883
+ 'text' => array(),
884
+ );
885
+
886
+ $Block['element']['text'][0]['text'] []= array(
887
+ 'name' => 'tr',
888
+ 'handler' => 'elements',
889
+ 'text' => $HeaderElements,
890
+ );
891
+
892
+ return $Block;
893
+ }
894
+ }
895
+
896
+ protected function blockTableContinue($Line, array $Block)
897
+ {
898
+ if (isset($Block['interrupted']))
899
+ {
900
+ return;
901
+ }
902
+
903
+ if ($Line['text'][0] === '|' or strpos($Line['text'], '|'))
904
+ {
905
+ $Elements = array();
906
+
907
+ $row = $Line['text'];
908
+
909
+ $row = trim($row);
910
+ $row = trim($row, '|');
911
+
912
+ preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches);
913
+
914
+ foreach ($matches[0] as $index => $cell)
915
+ {
916
+ $cell = trim($cell);
917
+
918
+ $Element = array(
919
+ 'name' => 'td',
920
+ 'handler' => 'line',
921
+ 'text' => $cell,
922
+ );
923
+
924
+ if (isset($Block['alignments'][$index]))
925
+ {
926
+ $Element['attributes'] = array(
927
+ 'style' => 'text-align: '.$Block['alignments'][$index].';',
928
+ );
929
+ }
930
+
931
+ $Elements []= $Element;
932
+ }
933
+
934
+ $Element = array(
935
+ 'name' => 'tr',
936
+ 'handler' => 'elements',
937
+ 'text' => $Elements,
938
+ );
939
+
940
+ $Block['element']['text'][1]['text'] []= $Element;
941
+
942
+ return $Block;
943
+ }
944
+ }
945
+
946
+ #
947
+ # ~
948
+ #
949
+
950
+ protected function paragraph($Line)
951
+ {
952
+ $Block = array(
953
+ 'element' => array(
954
+ 'name' => 'p',
955
+ 'text' => $Line['text'],
956
+ 'handler' => 'line',
957
+ ),
958
+ );
959
+
960
+ return $Block;
961
+ }
962
+
963
+ #
964
+ # Inline Elements
965
+ #
966
+
967
+ protected $InlineTypes = array(
968
+ '"' => array('SpecialCharacter'),
969
+ '!' => array('Image'),
970
+ '&' => array('SpecialCharacter'),
971
+ '*' => array('Emphasis'),
972
+ ':' => array('Url'),
973
+ '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'),
974
+ '>' => array('SpecialCharacter'),
975
+ '[' => array('Link'),
976
+ '_' => array('Emphasis'),
977
+ '`' => array('Code'),
978
+ '~' => array('Strikethrough'),
979
+ '\\' => array('EscapeSequence'),
980
+ );
981
+
982
+ # ~
983
+
984
+ protected $inlineMarkerList = '!"*_&[:<>`~\\';
985
+
986
+ #
987
+ # ~
988
+ #
989
+
990
+ public function line($text)
991
+ {
992
+ $markup = '';
993
+
994
+ # $excerpt is based on the first occurrence of a marker
995
+
996
+ while ($excerpt = strpbrk($text, $this->inlineMarkerList))
997
+ {
998
+ $marker = $excerpt[0];
999
+
1000
+ $markerPosition = strpos($text, $marker);
1001
+
1002
+ $Excerpt = array('text' => $excerpt, 'context' => $text);
1003
+
1004
+ foreach ($this->InlineTypes[$marker] as $inlineType)
1005
+ {
1006
+ $Inline = $this->{'inline'.$inlineType}($Excerpt);
1007
+
1008
+ if ( ! isset($Inline))
1009
+ {
1010
+ continue;
1011
+ }
1012
+
1013
+ # makes sure that the inline belongs to "our" marker
1014
+
1015
+ if (isset($Inline['position']) and $Inline['position'] > $markerPosition)
1016
+ {
1017
+ continue;
1018
+ }
1019
+
1020
+ # sets a default inline position
1021
+
1022
+ if ( ! isset($Inline['position']))
1023
+ {
1024
+ $Inline['position'] = $markerPosition;
1025
+ }
1026
+
1027
+ # the text that comes before the inline
1028
+ $unmarkedText = substr($text, 0, $Inline['position']);
1029
+
1030
+ # compile the unmarked text
1031
+ $markup .= $this->unmarkedText($unmarkedText);
1032
+
1033
+ # compile the inline
1034
+ $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']);
1035
+
1036
+ # remove the examined text
1037
+ $text = substr($text, $Inline['position'] + $Inline['extent']);
1038
+
1039
+ continue 2;
1040
+ }
1041
+
1042
+ # the marker does not belong to an inline
1043
+
1044
+ $unmarkedText = substr($text, 0, $markerPosition + 1);
1045
+
1046
+ $markup .= $this->unmarkedText($unmarkedText);
1047
+
1048
+ $text = substr($text, $markerPosition + 1);
1049
+ }
1050
+
1051
+ $markup .= $this->unmarkedText($text);
1052
+
1053
+ return $markup;
1054
+ }
1055
+
1056
+ #
1057
+ # ~
1058
+ #
1059
+
1060
+ protected function inlineCode($Excerpt)
1061
+ {
1062
+ $marker = $Excerpt['text'][0];
1063
+
1064
+ if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
1065
+ {
1066
+ $text = $matches[2];
1067
+ $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
1068
+ $text = preg_replace("/[ ]*\n/", ' ', $text);
1069
+
1070
+ return array(
1071
+ 'extent' => strlen($matches[0]),
1072
+ 'element' => array(
1073
+ 'name' => 'code',
1074
+ 'text' => $text,
1075
+ ),
1076
+ );
1077
+ }
1078
+ }
1079
+
1080
+ protected function inlineEmailTag($Excerpt)
1081
+ {
1082
+ if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches))
1083
+ {
1084
+ $url = $matches[1];
1085
+
1086
+ if ( ! isset($matches[2]))
1087
+ {
1088
+ $url = 'mailto:' . $url;
1089
+ }
1090
+
1091
+ return array(
1092
+ 'extent' => strlen($matches[0]),
1093
+ 'element' => array(
1094
+ 'name' => 'a',
1095
+ 'text' => $matches[1],
1096
+ 'attributes' => array(
1097
+ 'href' => $url,
1098
+ ),
1099
+ ),
1100
+ );
1101
+ }
1102
+ }
1103
+
1104
+ protected function inlineEmphasis($Excerpt)
1105
+ {
1106
+ if ( ! isset($Excerpt['text'][1]))
1107
+ {
1108
+ return;
1109
+ }
1110
+
1111
+ $marker = $Excerpt['text'][0];
1112
+
1113
+ if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
1114
+ {
1115
+ $emphasis = 'strong';
1116
+ }
1117
+ elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
1118
+ {
1119
+ $emphasis = 'em';
1120
+ }
1121
+ else
1122
+ {
1123
+ return;
1124
+ }
1125
+
1126
+ return array(
1127
+ 'extent' => strlen($matches[0]),
1128
+ 'element' => array(
1129
+ 'name' => $emphasis,
1130
+ 'handler' => 'line',
1131
+ 'text' => $matches[1],
1132
+ ),
1133
+ );
1134
+ }
1135
+
1136
+ protected function inlineEscapeSequence($Excerpt)
1137
+ {
1138
+ if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters))
1139
+ {
1140
+ return array(
1141
+ 'markup' => $Excerpt['text'][1],
1142
+ 'extent' => 2,
1143
+ );
1144
+ }
1145
+ }
1146
+
1147
+ protected function inlineImage($Excerpt)
1148
+ {
1149
+ if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
1150
+ {
1151
+ return;
1152
+ }
1153
+
1154
+ $Excerpt['text']= substr($Excerpt['text'], 1);
1155
+
1156
+ $Link = $this->inlineLink($Excerpt);
1157
+
1158
+ if ($Link === null)
1159
+ {
1160
+ return;
1161
+ }
1162
+
1163
+ $Inline = array(
1164
+ 'extent' => $Link['extent'] + 1,
1165
+ 'element' => array(
1166
+ 'name' => 'img',
1167
+ 'attributes' => array(
1168
+ 'src' => $Link['element']['attributes']['href'],
1169
+ 'alt' => $Link['element']['text'],
1170
+ ),
1171
+ ),
1172
+ );
1173
+
1174
+ $Inline['element']['attributes'] += $Link['element']['attributes'];
1175
+
1176
+ unset($Inline['element']['attributes']['href']);
1177
+
1178
+ return $Inline;
1179
+ }
1180
+
1181
+ protected function inlineLink($Excerpt)
1182
+ {
1183
+ $Element = array(
1184
+ 'name' => 'a',
1185
+ 'handler' => 'line',
1186
+ 'text' => null,
1187
+ 'attributes' => array(
1188
+ 'href' => null,
1189
+ 'title' => null,
1190
+ ),
1191
+ );
1192
+
1193
+ $extent = 0;
1194
+
1195
+ $remainder = $Excerpt['text'];
1196
+
1197
+ if (preg_match('/\[((?:[^][]|(?R))*)\]/', $remainder, $matches))
1198
+ {
1199
+ $Element['text'] = $matches[1];
1200
+
1201
+ $extent += strlen($matches[0]);
1202
+
1203
+ $remainder = substr($remainder, $extent);
1204
+ }
1205
+ else
1206
+ {
1207
+ return;
1208
+ }
1209
+
1210
+ if (preg_match('/^[(]((?:[^ ()]|[(][^ )]+[)])+)(?:[ ]+("[^"]*"|\'[^\']*\'))?[)]/', $remainder, $matches))
1211
+ {
1212
+ $Element['attributes']['href'] = $matches[1];
1213
+
1214
+ if (isset($matches[2]))
1215
+ {
1216
+ $Element['attributes']['title'] = substr($matches[2], 1, - 1);
1217
+ }
1218
+
1219
+ $extent += strlen($matches[0]);
1220
+ }
1221
+ else
1222
+ {
1223
+ if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
1224
+ {
1225
+ $definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
1226
+ $definition = strtolower($definition);
1227
+
1228
+ $extent += strlen($matches[0]);
1229
+ }
1230
+ else
1231
+ {
1232
+ $definition = strtolower($Element['text']);
1233
+ }
1234
+
1235
+ if ( ! isset($this->DefinitionData['Reference'][$definition]))
1236
+ {
1237
+ return;
1238
+ }
1239
+
1240
+ $Definition = $this->DefinitionData['Reference'][$definition];
1241
+
1242
+ $Element['attributes']['href'] = $Definition['url'];
1243
+ $Element['attributes']['title'] = $Definition['title'];
1244
+ }
1245
+
1246
+ $Element['attributes']['href'] = str_replace(array('&', '<'), array('&amp;', '&lt;'), $Element['attributes']['href']);
1247
+
1248
+ return array(
1249
+ 'extent' => $extent,
1250
+ 'element' => $Element,
1251
+ );
1252
+ }
1253
+
1254
+ protected function inlineMarkup($Excerpt)
1255
+ {
1256
+ if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false)
1257
+ {
1258
+ return;
1259
+ }
1260
+
1261
+ if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches))
1262
+ {
1263
+ return array(
1264
+ 'markup' => $matches[0],
1265
+ 'extent' => strlen($matches[0]),
1266
+ );
1267
+ }
1268
+
1269
+ if ($Excerpt['text'][1] === '!' and preg_match('/^<!---?[^>-](?:-?[^-])*-->/s', $Excerpt['text'], $matches))
1270
+ {
1271
+ return array(
1272
+ 'markup' => $matches[0],
1273
+ 'extent' => strlen($matches[0]),
1274
+ );
1275
+ }
1276
+
1277
+ if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
1278
+ {
1279
+ return array(
1280
+ 'markup' => $matches[0],
1281
+ 'extent' => strlen($matches[0]),
1282
+ );
1283
+ }
1284
+ }
1285
+
1286
+ protected function inlineSpecialCharacter($Excerpt)
1287
+ {
1288
+ if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text']))
1289
+ {
1290
+ return array(
1291
+ 'markup' => '&amp;',
1292
+ 'extent' => 1,
1293
+ );
1294
+ }
1295
+
1296
+ $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
1297
+
1298
+ if (isset($SpecialCharacter[$Excerpt['text'][0]]))
1299
+ {
1300
+ return array(
1301
+ 'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';',
1302
+ 'extent' => 1,
1303
+ );
1304
+ }
1305
+ }
1306
+
1307
+ protected function inlineStrikethrough($Excerpt)
1308
+ {
1309
+ if ( ! isset($Excerpt['text'][1]))
1310
+ {
1311
+ return;
1312
+ }
1313
+
1314
+ if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
1315
+ {
1316
+ return array(
1317
+ 'extent' => strlen($matches[0]),
1318
+ 'element' => array(
1319
+ 'name' => 'del',
1320
+ 'text' => $matches[1],
1321
+ 'handler' => 'line',
1322
+ ),
1323
+ );
1324
+ }
1325
+ }
1326
+
1327
+ protected function inlineUrl($Excerpt)
1328
+ {
1329
+ if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
1330
+ {
1331
+ return;
1332
+ }
1333
+
1334
+ if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
1335
+ {
1336
+ $Inline = array(
1337
+ 'extent' => strlen($matches[0][0]),
1338
+ 'position' => $matches[0][1],
1339
+ 'element' => array(
1340
+ 'name' => 'a',
1341
+ 'text' => $matches[0][0],
1342
+ 'attributes' => array(
1343
+ 'href' => $matches[0][0],
1344
+ ),
1345
+ ),
1346
+ );
1347
+
1348
+ return $Inline;
1349
+ }
1350
+ }
1351
+
1352
+ protected function inlineUrlTag($Excerpt)
1353
+ {
1354
+ if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
1355
+ {
1356
+ $url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $matches[1]);
1357
+
1358
+ return array(
1359
+ 'extent' => strlen($matches[0]),
1360
+ 'element' => array(
1361
+ 'name' => 'a',
1362
+ 'text' => $url,
1363
+ 'attributes' => array(
1364
+ 'href' => $url,
1365
+ ),
1366
+ ),
1367
+ );
1368
+ }
1369
+ }
1370
+
1371
+ # ~
1372
+
1373
+ protected function unmarkedText($text)
1374
+ {
1375
+ if ($this->breaksEnabled)
1376
+ {
1377
+ $text = preg_replace('/[ ]*\n/', "<br />\n", $text);
1378
+ }
1379
+ else
1380
+ {
1381
+ $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "<br />\n", $text);
1382
+ $text = str_replace(" \n", "\n", $text);
1383
+ }
1384
+
1385
+ return $text;
1386
+ }
1387
+
1388
+ #
1389
+ # Handlers
1390
+ #
1391
+
1392
+ protected function element(array $Element)
1393
+ {
1394
+ $markup = '<'.$Element['name'];
1395
+
1396
+ if (isset($Element['attributes']))
1397
+ {
1398
+ foreach ($Element['attributes'] as $name => $value)
1399
+ {
1400
+ if ($value === null)
1401
+ {
1402
+ continue;
1403
+ }
1404
+
1405
+ $markup .= ' '.$name.'="'.$value.'"';
1406
+ }
1407
+ }
1408
+
1409
+ if (isset($Element['text']))
1410
+ {
1411
+ $markup .= '>';
1412
+
1413
+ if (isset($Element['handler']))
1414
+ {
1415
+ $markup .= $this->{$Element['handler']}($Element['text']);
1416
+ }
1417
+ else
1418
+ {
1419
+ $markup .= $Element['text'];
1420
+ }
1421
+
1422
+ $markup .= '</'.$Element['name'].'>';
1423
+ }
1424
+ else
1425
+ {
1426
+ $markup .= ' />';
1427
+ }
1428
+
1429
+ return $markup;
1430
+ }
1431
+
1432
+ protected function elements(array $Elements)
1433
+ {
1434
+ $markup = '';
1435
+
1436
+ foreach ($Elements as $Element)
1437
+ {
1438
+ $markup .= "\n" . $this->element($Element);
1439
+ }
1440
+
1441
+ $markup .= "\n";
1442
+
1443
+ return $markup;
1444
+ }
1445
+
1446
+ # ~
1447
+
1448
+ protected function li($lines)
1449
+ {
1450
+ $markup = $this->lines($lines);
1451
+
1452
+ $trimmedMarkup = trim($markup);
1453
+
1454
+ if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '<p>')
1455
+ {
1456
+ $markup = $trimmedMarkup;
1457
+ $markup = substr($markup, 3);
1458
+
1459
+ $position = strpos($markup, "</p>");
1460
+
1461
+ $markup = substr_replace($markup, '', $position, 4);
1462
+ }
1463
+
1464
+ return $markup;
1465
+ }
1466
+
1467
+ #
1468
+ # Deprecated Methods
1469
+ #
1470
+
1471
+ function parse($text)
1472
+ {
1473
+ $markup = $this->text($text);
1474
+
1475
+ return $markup;
1476
+ }
1477
+
1478
+ #
1479
+ # Static Methods
1480
+ #
1481
+
1482
+ static function instance($name = 'default')
1483
+ {
1484
+ if (isset(self::$instances[$name]))
1485
+ {
1486
+ return self::$instances[$name];
1487
+ }
1488
+
1489
+ $instance = new static();
1490
+
1491
+ self::$instances[$name] = $instance;
1492
+
1493
+ return $instance;
1494
+ }
1495
+
1496
+ private static $instances = array();
1497
+
1498
+ #
1499
+ # Fields
1500
+ #
1501
+
1502
+ protected $DefinitionData;
1503
+
1504
+ #
1505
+ # Read-Only
1506
+
1507
+ protected $specialCharacters = array(
1508
+ '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|',
1509
+ );
1510
+
1511
+ protected $StrongRegex = array(
1512
+ '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s',
1513
+ '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us',
1514
+ );
1515
+
1516
+ protected $EmRegex = array(
1517
+ '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s',
1518
+ '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
1519
+ );
1520
+
1521
+ protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?';
1522
+
1523
+ protected $voidElements = array(
1524
+ 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
1525
+ );
1526
+
1527
+ protected $textLevelElements = array(
1528
+ 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont',
1529
+ 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing',
1530
+ 'i', 'rp', 'del', 'code', 'strike', 'marquee',
1531
+ 'q', 'rt', 'ins', 'font', 'strong',
1532
+ 's', 'tt', 'sub', 'mark',
1533
+ 'u', 'xm', 'sup', 'nobr',
1534
+ 'var', 'ruby',
1535
+ 'wbr', 'span',
1536
+ 'time',
1537
+ );
1538
+ }
app/core/puc/vendor/PucReadmeParser.php ADDED
@@ -0,0 +1,348 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists('PucReadmeParser', false) ):
4
+
5
+ /**
6
+ * This is a slightly modified version of github.com/markjaquith/WordPress-Plugin-Readme-Parser
7
+ * It uses Parsedown instead of the "Markdown Extra" parser.
8
+ */
9
+
10
+ class PucReadmeParser {
11
+
12
+ function __construct() {
13
+ // This space intentionally blank
14
+ }
15
+
16
+ function parse_readme( $file ) {
17
+ $file_contents = @implode('', @file($file));
18
+ return $this->parse_readme_contents( $file_contents );
19
+ }
20
+
21
+ function parse_readme_contents( $file_contents ) {
22
+ $file_contents = str_replace(array("\r\n", "\r"), "\n", $file_contents);
23
+ $file_contents = trim($file_contents);
24
+ if ( 0 === strpos( $file_contents, "\xEF\xBB\xBF" ) )
25
+ $file_contents = substr( $file_contents, 3 );
26
+
27
+ // Markdown transformations
28
+ $file_contents = preg_replace( "|^###([^#]+)#*?\s*?\n|im", '=$1='."\n", $file_contents );
29
+ $file_contents = preg_replace( "|^##([^#]+)#*?\s*?\n|im", '==$1=='."\n", $file_contents );
30
+ $file_contents = preg_replace( "|^#([^#]+)#*?\s*?\n|im", '===$1==='."\n", $file_contents );
31
+
32
+ // === Plugin Name ===
33
+ // Must be the very first thing.
34
+ if ( !preg_match('|^===(.*)===|', $file_contents, $_name) )
35
+ return array(); // require a name
36
+ $name = trim($_name[1], '=');
37
+ $name = $this->sanitize_text( $name );
38
+
39
+ $file_contents = $this->chop_string( $file_contents, $_name[0] );
40
+
41
+
42
+ // Requires at least: 1.5
43
+ if ( preg_match('|Requires at least:(.*)|i', $file_contents, $_requires_at_least) )
44
+ $requires_at_least = $this->sanitize_text($_requires_at_least[1]);
45
+ else
46
+ $requires_at_least = NULL;
47
+
48
+
49
+ // Tested up to: 2.1
50
+ if ( preg_match('|Tested up to:(.*)|i', $file_contents, $_tested_up_to) )
51
+ $tested_up_to = $this->sanitize_text( $_tested_up_to[1] );
52
+ else
53
+ $tested_up_to = NULL;
54
+
55
+ // Requires PHP: 5.2.4
56
+ if ( preg_match('|Requires PHP:(.*)|i', $file_contents, $_requires_php) ) {
57
+ $requires_php = $this->sanitize_text( $_requires_php[1] );
58
+ } else {
59
+ $requires_php = null;
60
+ }
61
+
62
+ // Stable tag: 10.4-ride-the-fire-eagle-danger-day
63
+ if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) )
64
+ $stable_tag = $this->sanitize_text( $_stable_tag[1] );
65
+ else
66
+ $stable_tag = NULL; // we assume trunk, but don't set it here to tell the difference between specified trunk and default trunk
67
+
68
+
69
+ // Tags: some tag, another tag, we like tags
70
+ if ( preg_match('|Tags:(.*)|i', $file_contents, $_tags) ) {
71
+ $tags = preg_split('|,[\s]*?|', trim($_tags[1]));
72
+ foreach ( array_keys($tags) as $t )
73
+ $tags[$t] = $this->sanitize_text( $tags[$t] );
74
+ } else {
75
+ $tags = array();
76
+ }
77
+
78
+
79
+ // Contributors: markjaquith, mdawaffe, zefrank
80
+ $contributors = array();
81
+ if ( preg_match('|Contributors:(.*)|i', $file_contents, $_contributors) ) {
82
+ $temp_contributors = preg_split('|,[\s]*|', trim($_contributors[1]));
83
+ foreach ( array_keys($temp_contributors) as $c ) {
84
+ $tmp_sanitized = $this->user_sanitize( $temp_contributors[$c] );
85
+ if ( strlen(trim($tmp_sanitized)) > 0 )
86
+ $contributors[$c] = $tmp_sanitized;
87
+ unset($tmp_sanitized);
88
+ }
89
+ }
90
+
91
+
92
+ // Donate Link: URL
93
+ if ( preg_match('|Donate link:(.*)|i', $file_contents, $_donate_link) )
94
+ $donate_link = esc_url( $_donate_link[1] );
95
+ else
96
+ $donate_link = NULL;
97
+
98
+
99
+ // togs, conts, etc are optional and order shouldn't matter. So we chop them only after we've grabbed their values.
100
+ foreach ( array('tags', 'contributors', 'requires_at_least', 'tested_up_to', 'stable_tag', 'donate_link') as $chop ) {
101
+ if ( $$chop ) {
102
+ $_chop = '_' . $chop;
103
+ $file_contents = $this->chop_string( $file_contents, ${$_chop}[0] );
104
+ }
105
+ }
106
+
107
+ $file_contents = trim($file_contents);
108
+
109
+
110
+ // short-description fu
111
+ if ( !preg_match('/(^(.*?))^[\s]*=+?[\s]*.+?[\s]*=+?/ms', $file_contents, $_short_description) )
112
+ $_short_description = array( 1 => &$file_contents, 2 => &$file_contents );
113
+ $short_desc_filtered = $this->sanitize_text( $_short_description[2] );
114
+ $short_desc_length = strlen($short_desc_filtered);
115
+ $short_description = substr($short_desc_filtered, 0, 150);
116
+ if ( $short_desc_length > strlen($short_description) )
117
+ $truncated = true;
118
+ else
119
+ $truncated = false;
120
+ if ( $_short_description[1] )
121
+ $file_contents = $this->chop_string( $file_contents, $_short_description[1] ); // yes, the [1] is intentional
122
+
123
+ // == Section ==
124
+ // Break into sections
125
+ // $_sections[0] will be the title of the first section, $_sections[1] will be the content of the first section
126
+ // the array alternates from there: title2, content2, title3, content3... and so forth
127
+ $_sections = preg_split('/^[\s]*==[\s]*(.+?)[\s]*==/m', $file_contents, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
128
+
129
+ $sections = array();
130
+ for ( $i=0; $i < count($_sections); $i +=2 ) {
131
+ $title = $this->sanitize_text( $_sections[$i] );
132
+ if ( isset($_sections[$i+1]) ) {
133
+ $content = preg_replace('/(^[\s]*)=[\s]+(.+?)[\s]+=/m', '$1<h4>$2</h4>', $_sections[$i+1]);
134
+ $content = $this->filter_text( $content, true );
135
+ } else {
136
+ $content = '';
137
+ }
138
+ $sections[str_replace(' ', '_', strtolower($title))] = array('title' => $title, 'content' => $content);
139
+ }
140
+
141
+
142
+ // Special sections
143
+ // This is where we nab our special sections, so we can enforce their order and treat them differently, if needed
144
+ // upgrade_notice is not a section, but parse it like it is for now
145
+ $final_sections = array();
146
+ foreach ( array('description', 'installation', 'frequently_asked_questions', 'screenshots', 'changelog', 'change_log', 'upgrade_notice') as $special_section ) {
147
+ if ( isset($sections[$special_section]) ) {
148
+ $final_sections[$special_section] = $sections[$special_section]['content'];
149
+ unset($sections[$special_section]);
150
+ }
151
+ }
152
+ if ( isset($final_sections['change_log']) && empty($final_sections['changelog']) )
153
+ $final_sections['changelog'] = $final_sections['change_log'];
154
+
155
+
156
+ $final_screenshots = array();
157
+ if ( isset($final_sections['screenshots']) ) {
158
+ preg_match_all('|<li>(.*?)</li>|s', $final_sections['screenshots'], $screenshots, PREG_SET_ORDER);
159
+ if ( $screenshots ) {
160
+ foreach ( (array) $screenshots as $ss )
161
+ $final_screenshots[] = $ss[1];
162
+ }
163
+ }
164
+
165
+ // Parse the upgrade_notice section specially:
166
+ // 1.0 => blah, 1.1 => fnord
167
+ $upgrade_notice = array();
168
+ if ( isset($final_sections['upgrade_notice']) ) {
169
+ $split = preg_split( '#<h4>(.*?)</h4>#', $final_sections['upgrade_notice'], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
170
+ if ( count($split) >= 2 ) {
171
+ for ( $i = 0; $i < count( $split ); $i += 2 ) {
172
+ $upgrade_notice[$this->sanitize_text( $split[$i] )] = substr( $this->sanitize_text( $split[$i + 1] ), 0, 300 );
173
+ }
174
+ }
175
+ unset( $final_sections['upgrade_notice'] );
176
+ }
177
+
178
+ // No description?
179
+ // No problem... we'll just fall back to the old style of description
180
+ // We'll even let you use markup this time!
181
+ $excerpt = false;
182
+ if ( !isset($final_sections['description']) ) {
183
+ $final_sections = array_merge(array('description' => $this->filter_text( $_short_description[2], true )), $final_sections);
184
+ $excerpt = true;
185
+ }
186
+
187
+
188
+ // dump the non-special sections into $remaining_content
189
+ // their order will be determined by their original order in the readme.txt
190
+ $remaining_content = '';
191
+ foreach ( $sections as $s_name => $s_data ) {
192
+ $remaining_content .= "\n<h3>{$s_data['title']}</h3>\n{$s_data['content']}";
193
+ }
194
+ $remaining_content = trim($remaining_content);
195
+
196
+
197
+ // All done!
198
+ // $r['tags'] and $r['contributors'] are simple arrays
199
+ // $r['sections'] is an array with named elements
200
+ $r = array(
201
+ 'name' => $name,
202
+ 'tags' => $tags,
203
+ 'requires_at_least' => $requires_at_least,
204
+ 'tested_up_to' => $tested_up_to,
205
+ 'requires_php' => $requires_php,
206
+ 'stable_tag' => $stable_tag,
207
+ 'contributors' => $contributors,
208
+ 'donate_link' => $donate_link,
209
+ 'short_description' => $short_description,
210
+ 'screenshots' => $final_screenshots,
211
+ 'is_excerpt' => $excerpt,
212
+ 'is_truncated' => $truncated,
213
+ 'sections' => $final_sections,
214
+ 'remaining_content' => $remaining_content,
215
+ 'upgrade_notice' => $upgrade_notice
216
+ );
217
+
218
+ return $r;
219
+ }
220
+
221
+ function chop_string( $string, $chop ) { // chop a "prefix" from a string: Agressive! uses strstr not 0 === strpos
222
+ if ( $_string = strstr($string, $chop) ) {
223
+ $_string = substr($_string, strlen($chop));
224
+ return trim($_string);
225
+ } else {
226
+ return trim($string);
227
+ }
228
+ }
229
+
230
+ function user_sanitize( $text, $strict = false ) { // whitelisted chars
231
+ if ( function_exists('user_sanitize') ) // bbPress native
232
+ return user_sanitize( $text, $strict );
233
+
234
+ if ( $strict ) {
235
+ $text = preg_replace('/[^a-z0-9-]/i', '', $text);
236
+ $text = preg_replace('|-+|', '-', $text);
237
+ } else {
238
+ $text = preg_replace('/[^a-z0-9_-]/i', '', $text);
239
+ }
240
+ return $text;
241
+ }
242
+
243
+ function sanitize_text( $text ) { // not fancy
244
+ $text = strip_tags($text);
245
+ $text = esc_html($text);
246
+ $text = trim($text);
247
+ return $text;
248
+ }
249
+
250
+ function filter_text( $text, $markdown = false ) { // fancy, Markdown
251
+ $text = trim($text);
252
+
253
+ $text = call_user_func( array( __CLASS__, 'code_trick' ), $text, $markdown ); // A better parser than Markdown's for: backticks -> CODE
254
+
255
+ if ( $markdown ) { // Parse markdown.
256
+ if ( !class_exists('Parsedown', false) ) {
257
+ /** @noinspection PhpIncludeInspection */
258
+ require_once(dirname(__FILE__) . '/Parsedown' . (version_compare(PHP_VERSION, '5.3.0', '>=') ? '' : 'Legacy') . '.php');
259
+ }
260
+ $instance = Parsedown::instance();
261
+ $text = $instance->text($text);
262
+ }
263
+
264
+ $allowed = array(
265
+ 'a' => array(
266
+ 'href' => array(),
267
+ 'title' => array(),
268
+ 'rel' => array()),
269
+ 'blockquote' => array('cite' => array()),
270
+ 'br' => array(),
271
+ 'p' => array(),
272
+ 'code' => array(),
273
+ 'pre' => array(),
274
+ 'em' => array(),
275
+ 'strong' => array(),
276
+ 'ul' => array(),
277
+ 'ol' => array(),
278
+ 'li' => array(),
279
+ 'h3' => array(),
280
+ 'h4' => array()
281
+ );
282
+
283
+ $text = balanceTags($text);
284
+
285
+ $text = wp_kses( $text, $allowed );
286
+ $text = trim($text);
287
+ return $text;
288
+ }
289
+
290
+ function code_trick( $text, $markdown ) { // Don't use bbPress native function - it's incompatible with Markdown
291
+ // If doing markdown, first take any user formatted code blocks and turn them into backticks so that
292
+ // markdown will preserve things like underscores in code blocks
293
+ if ( $markdown )
294
+ $text = preg_replace_callback("!(<pre><code>|<code>)(.*?)(</code></pre>|</code>)!s", array( __CLASS__,'decodeit'), $text);
295
+
296
+ $text = str_replace(array("\r\n", "\r"), "\n", $text);
297
+ if ( !$markdown ) {
298
+ // This gets the "inline" code blocks, but can't be used with Markdown.
299
+ $text = preg_replace_callback("|(`)(.*?)`|", array( __CLASS__, 'encodeit'), $text);
300
+ // This gets the "block level" code blocks and converts them to PRE CODE
301
+ $text = preg_replace_callback("!(^|\n)`(.*?)`!s", array( __CLASS__, 'encodeit'), $text);
302
+ } else {
303
+ // Markdown can do inline code, we convert bbPress style block level code to Markdown style
304
+ $text = preg_replace_callback("!(^|\n)([ \t]*?)`(.*?)`!s", array( __CLASS__, 'indent'), $text);
305
+ }
306
+ return $text;
307
+ }
308
+
309
+ function indent( $matches ) {
310
+ $text = $matches[3];
311
+ $text = preg_replace('|^|m', $matches[2] . ' ', $text);
312
+ return $matches[1] . $text;
313
+ }
314
+
315
+ function encodeit( $matches ) {
316
+ if ( function_exists('encodeit') ) // bbPress native
317
+ return encodeit( $matches );
318
+
319
+ $text = trim($matches[2]);
320
+ $text = htmlspecialchars($text, ENT_QUOTES);
321
+ $text = str_replace(array("\r\n", "\r"), "\n", $text);
322
+ $text = preg_replace("|\n\n\n+|", "\n\n", $text);
323
+ $text = str_replace('&amp;lt;', '&lt;', $text);
324
+ $text = str_replace('&amp;gt;', '&gt;', $text);
325
+ $text = "<code>$text</code>";
326
+ if ( "`" != $matches[1] )
327
+ $text = "<pre>$text</pre>";
328
+ return $text;
329
+ }
330
+
331
+ function decodeit( $matches ) {
332
+ if ( function_exists('decodeit') ) // bbPress native
333
+ return decodeit( $matches );
334
+
335
+ $text = $matches[2];
336
+ $trans_table = array_flip(get_html_translation_table(HTML_ENTITIES));
337
+ $text = strtr($text, $trans_table);
338
+ $text = str_replace('<br />', '', $text);
339
+ $text = str_replace('&#38;', '&', $text);
340
+ $text = str_replace('&#39;', "'", $text);
341
+ if ( '<pre><code>' == $matches[1] )
342
+ $text = "\n$text\n";
343
+ return "`$text`";
344
+ }
345
+
346
+ } // end class
347
+
348
+ endif;
app/features/dlfile.php CHANGED
@@ -231,6 +231,9 @@ class MEC_feature_dlfile extends MEC_base
231
  if(trim($file_id) == '') $file_id = '';
232
 
233
  $file_url = $file_id ? wp_get_attachment_url($file_id) : '';
 
 
 
234
  ?>
235
  <script>
236
  jQuery(document).ready(function()
@@ -290,6 +293,14 @@ class MEC_feature_dlfile extends MEC_base
290
  <button type="button" id="mec_public_download_module_file_remove_image_button" class="<?php echo (trim($file_id) ? '' : 'mec-util-hidden'); ?>"><?php _e('Remove File', 'modern-events-calendar-lite'); ?></button>
291
  <div class="mec-error mec-util-hidden" id="mec_public_download_module_file_error"></div>
292
  </div>
 
 
 
 
 
 
 
 
293
  </div>
294
  <?php
295
  }
231
  if(trim($file_id) == '') $file_id = '';
232
 
233
  $file_url = $file_id ? wp_get_attachment_url($file_id) : '';
234
+
235
+ $title = get_post_meta($post->ID, 'mec_public_dl_title', true);
236
+ $description = get_post_meta($post->ID, 'mec_public_dl_description', true);
237
  ?>
238
  <script>
239
  jQuery(document).ready(function()
293
  <button type="button" id="mec_public_download_module_file_remove_image_button" class="<?php echo (trim($file_id) ? '' : 'mec-util-hidden'); ?>"><?php _e('Remove File', 'modern-events-calendar-lite'); ?></button>
294
  <div class="mec-error mec-util-hidden" id="mec_public_download_module_file_error"></div>
295
  </div>
296
+ <div class="mec-form-row" style="margin-top: 30px;">
297
+ <label for="mec_public_download_module_title" class="mec-col-2"><?php _e('Title', 'modern-events-calendar-lite'); ?></label>
298
+ <input class="mec-col-5" type="text" id="mec_public_download_module_title" name="mec[public_download_module_title]" value="<?php echo esc_attr($title); ?>">
299
+ </div>
300
+ <div class="mec-form-row">
301
+ <label for="mec_public_download_module_description" class="mec-col-2"><?php _e('Description', 'modern-events-calendar-lite'); ?></label>
302
+ <textarea class="mec-col-5" id="mec_public_download_module_description" name="mec[public_download_module_description]" rows="5"><?php echo esc_textarea($description); ?></textarea>
303
+ </div>
304
  </div>
305
  <?php
306
  }
app/features/events.php CHANGED
@@ -482,14 +482,14 @@ class MEC_feature_events extends MEC_base
482
 
483
  <?php if(isset($this->settings['display_event_fields_backend']) and $this->settings['display_event_fields_backend'] == 1): ?>
484
  <script>
485
- jQuery("#publish").on("click", function()
486
- {
487
- var xdf = jQuery("#mec_metabox_details .mec-add-event-tabs-left .mec-add-event-tabs-link[data-href='mec-event-data']");
488
- jQuery("#mec_metabox_details .mec-add-event-tabs-left .mec-add-event-tabs-link").removeClass("mec-tab-active");
489
- jQuery("#mec_metabox_details .mec-add-event-tabs-right .mec-event-tab-content").removeClass("mec-tab-active");
490
- jQuery(xdf).addClass("mec-tab-active");
491
- jQuery(".mec-add-event-tabs-right #mec-event-data").addClass("mec-tab-active");
492
- });
493
  </script>
494
  <?php
495
  endif;
@@ -2011,7 +2011,7 @@ class MEC_feature_events extends MEC_base
2011
  <span class="mec-col-4">
2012
  <input type="number" min="0" step="0.01" name="mec[tickets][<?php echo $key; ?>][price]"
2013
  placeholder="<?php esc_attr_e('Price', 'modern-events-calendar-lite'); ?>"
2014
- value="<?php echo(isset($ticket['price']) ? esc_attr($ticket['price']) : ''); ?>"/>
2015
  <span class="mec-tooltip">
2016
  <div class="box top">
2017
  <h5 class="title"><?php _e('Price', 'modern-events-calendar-lite'); ?></h5>
@@ -2268,8 +2268,7 @@ class MEC_feature_events extends MEC_base
2268
  <?php endif; ?>
2269
  <div class="mec-form-row">
2270
  <span class="mec-col-4">
2271
- <input type="number" min="0" step="0.01" name="mec[tickets][:i:][price]"
2272
- placeholder="<?php esc_attr_e('Price', 'modern-events-calendar-lite'); ?>"/>
2273
  <span class="mec-tooltip">
2274
  <div class="box top">
2275
  <h5 class="title"><?php _e('Price', 'modern-events-calendar-lite'); ?></h5>
@@ -2281,8 +2280,7 @@ class MEC_feature_events extends MEC_base
2281
  </span>
2282
  </span>
2283
  <span class="mec-col-8">
2284
- <input type="text" name="mec[tickets][:i:][price_label]"
2285
- placeholder="<?php esc_attr_e('Price Label', 'modern-events-calendar-lite'); ?>" class="mec-col-12"/>
2286
  <span class="mec-tooltip">
2287
  <div class="box top">
2288
  <h5 class="title"><?php _e('Price Label', 'modern-events-calendar-lite'); ?></h5>
@@ -3573,9 +3571,9 @@ class MEC_feature_events extends MEC_base
3573
  {
3574
  unset($ticket['dates'][':j:']);
3575
  $ticket_start_time_ampm = ((isset($ticket['ticket_start_time_hour']) and (intval($ticket['ticket_start_time_hour']) > 0 and intval($ticket['ticket_start_time_hour']) < 13) and isset($ticket['ticket_start_time_ampm'])) ? $ticket['ticket_start_time_ampm'] : '');
3576
- $ticket_render_start_time = ($ticket['ticket_start_time_hour'] ? date('h:ia', strtotime(sprintf('%02d', $ticket['ticket_start_time_hour']) . ':' . sprintf('%02d', $ticket['ticket_start_time_minute']) . $ticket_start_time_ampm)) : '');
3577
  $ticket_end_time_ampm = ((isset($ticket['ticket_end_time_hour']) and (intval($ticket['ticket_end_time_hour']) > 0 and intval($ticket['ticket_end_time_hour']) < 13) and isset($ticket['ticket_end_time_ampm'])) ? $ticket['ticket_end_time_ampm'] : '');
3578
- $ticket_render_end_time = ($ticket['ticket_end_time_hour'] ? date('h:ia', strtotime(sprintf('%02d', $ticket['ticket_end_time_hour']) . ':' . sprintf('%02d', $ticket['ticket_end_time_minute']) . $ticket_end_time_ampm)) : '');
3579
 
3580
  $ticket['ticket_start_time_hour'] = substr($ticket_render_start_time, 0, 2);
3581
  $ticket['ticket_start_time_ampm'] = strtoupper(substr($ticket_render_start_time, 5, 6));
@@ -3666,6 +3664,12 @@ class MEC_feature_events extends MEC_base
3666
  {
3667
  $public_dl_file = isset($_mec['public_download_module_file']) ? $_mec['public_download_module_file'] : '';
3668
  update_post_meta($post_id, 'mec_public_dl_file', $public_dl_file);
 
 
 
 
 
 
3669
  }
3670
 
3671
  // Notifications
482
 
483
  <?php if(isset($this->settings['display_event_fields_backend']) and $this->settings['display_event_fields_backend'] == 1): ?>
484
  <script>
485
+ jQuery("#publish").on("click", function()
486
+ {
487
+ var xdf = jQuery("#mec_metabox_details .mec-add-event-tabs-left .mec-add-event-tabs-link[data-href='mec-event-data']");
488
+ jQuery("#mec_metabox_details .mec-add-event-tabs-left .mec-add-event-tabs-link").removeClass("mec-tab-active");
489
+ jQuery("#mec_metabox_details .mec-add-event-tabs-right .mec-event-tab-content").removeClass("mec-tab-active");
490
+ jQuery(xdf).addClass("mec-tab-active");
491
+ jQuery(".mec-add-event-tabs-right #mec-event-data").addClass("mec-tab-active");
492
+ });
493
  </script>
494
  <?php
495
  endif;
2011
  <span class="mec-col-4">
2012
  <input type="number" min="0" step="0.01" name="mec[tickets][<?php echo $key; ?>][price]"
2013
  placeholder="<?php esc_attr_e('Price', 'modern-events-calendar-lite'); ?>"
2014
+ value="<?php echo ((isset($ticket['price']) and trim($ticket['price'])) ? esc_attr($ticket['price']) : 0); ?>"/>
2015
  <span class="mec-tooltip">
2016
  <div class="box top">
2017
  <h5 class="title"><?php _e('Price', 'modern-events-calendar-lite'); ?></h5>
2268
  <?php endif; ?>
2269
  <div class="mec-form-row">
2270
  <span class="mec-col-4">
2271
+ <input type="number" min="0" step="0.01" name="mec[tickets][:i:][price]" placeholder="<?php esc_attr_e('Price', 'modern-events-calendar-lite'); ?>" value="0">
 
2272
  <span class="mec-tooltip">
2273
  <div class="box top">
2274
  <h5 class="title"><?php _e('Price', 'modern-events-calendar-lite'); ?></h5>
2280
  </span>
2281
  </span>
2282
  <span class="mec-col-8">
2283
+ <input type="text" name="mec[tickets][:i:][price_label]" placeholder="<?php esc_attr_e('Price Label', 'modern-events-calendar-lite'); ?>" class="mec-col-12">
 
2284
  <span class="mec-tooltip">
2285
  <div class="box top">
2286
  <h5 class="title"><?php _e('Price Label', 'modern-events-calendar-lite'); ?></h5>
3571
  {
3572
  unset($ticket['dates'][':j:']);
3573
  $ticket_start_time_ampm = ((isset($ticket['ticket_start_time_hour']) and (intval($ticket['ticket_start_time_hour']) > 0 and intval($ticket['ticket_start_time_hour']) < 13) and isset($ticket['ticket_start_time_ampm'])) ? $ticket['ticket_start_time_ampm'] : '');
3574
+ $ticket_render_start_time = ((isset($ticket['ticket_start_time_hour']) and $ticket['ticket_start_time_hour']) ? date('h:ia', strtotime(sprintf('%02d', $ticket['ticket_start_time_hour']) . ':' . sprintf('%02d', $ticket['ticket_start_time_minute']) . $ticket_start_time_ampm)) : '');
3575
  $ticket_end_time_ampm = ((isset($ticket['ticket_end_time_hour']) and (intval($ticket['ticket_end_time_hour']) > 0 and intval($ticket['ticket_end_time_hour']) < 13) and isset($ticket['ticket_end_time_ampm'])) ? $ticket['ticket_end_time_ampm'] : '');
3576
+ $ticket_render_end_time = ((isset($ticket['ticket_end_time_hour']) and $ticket['ticket_end_time_hour']) ? date('h:ia', strtotime(sprintf('%02d', $ticket['ticket_end_time_hour']) . ':' . sprintf('%02d', $ticket['ticket_end_time_minute']) . $ticket_end_time_ampm)) : '');
3577
 
3578
  $ticket['ticket_start_time_hour'] = substr($ticket_render_start_time, 0, 2);
3579
  $ticket['ticket_start_time_ampm'] = strtoupper(substr($ticket_render_start_time, 5, 6));
3664
  {
3665
  $public_dl_file = isset($_mec['public_download_module_file']) ? $_mec['public_download_module_file'] : '';
3666
  update_post_meta($post_id, 'mec_public_dl_file', $public_dl_file);
3667
+
3668
+ $public_dl_title = isset($_mec['public_download_module_title']) ? $_mec['public_download_module_title'] : '';
3669
+ update_post_meta($post_id, 'mec_public_dl_title', $public_dl_title);
3670
+
3671
+ $public_dl_description = isset($_mec['public_download_module_description']) ? $_mec['public_download_module_description'] : '';
3672
+ update_post_meta($post_id, 'mec_public_dl_description', $public_dl_description);
3673
  }
3674
 
3675
  // Notifications
app/features/fes.php CHANGED
@@ -1359,6 +1359,12 @@ class MEC_feature_fes extends MEC_base
1359
  {
1360
  $public_dl_file = isset($mec['public_download_module_file']) ? $mec['public_download_module_file'] : '';
1361
  update_post_meta($post_id, 'mec_public_dl_file', $public_dl_file);
 
 
 
 
 
 
1362
  }
1363
 
1364
  do_action('save_fes_meta_action', $post_id, $mec);
1359
  {
1360
  $public_dl_file = isset($mec['public_download_module_file']) ? $mec['public_download_module_file'] : '';
1361
  update_post_meta($post_id, 'mec_public_dl_file', $public_dl_file);
1362
+
1363
+ $public_dl_title = isset($mec['public_download_module_title']) ? $mec['public_download_module_title'] : '';
1364
+ update_post_meta($post_id, 'mec_public_dl_title', $public_dl_title);
1365
+
1366
+ $public_dl_description = isset($mec['public_download_module_description']) ? $mec['public_download_module_description'] : '';
1367
+ update_post_meta($post_id, 'mec_public_dl_description', $public_dl_description);
1368
  }
1369
 
1370
  do_action('save_fes_meta_action', $post_id, $mec);
app/features/gateways.php ADDED
@@ -0,0 +1,6631 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** no direct access **/
3
+ defined('MECEXEC') or die();
4
+
5
+ /**
6
+ * Webnus MEC gateways class.
7
+ *
8
+ * @author Webnus <info@webnus.biz>
9
+ */
10
+ class MEC_feature_gateways extends MEC_base
11
+ {
12
+ /**
13
+ * @var MEC_factory
14
+ */
15
+ public $factory;
16
+
17
+ /**
18
+ * @var MEC_main
19
+ */
20
+ public $main;
21
+
22
+ /**
23
+ * Constructor method
24
+ *
25
+ * @author Webnus <info@webnus.biz>
26
+ */
27
+ public function __construct()
28
+ {
29
+ // Import MEC Factory
30
+ $this->factory = $this->getFactory();
31
+
32
+ // Import MEC Main
33
+ $this->main = $this->getMain();
34
+ }
35
+
36
+ /**
37
+ * Initialize colors feature
38
+ *
39
+ * @author Webnus <info@webnus.biz>
40
+ */
41
+ public function init()
42
+ {
43
+ // PRO Version is required
44
+ if(!$this->getPRO()) return false;
45
+
46
+ // MEC Settings
47
+ $settings = $this->main->get_settings();
48
+
49
+ // Booking is disabled
50
+ if(!isset($settings['booking_status']) or (isset($settings['booking_status']) and !$settings['booking_status'])) return false;
51
+
52
+ // WC System
53
+ $WC_status = (isset($settings['wc_status']) and $settings['wc_status'] and class_exists('WooCommerce')) ? true : false;
54
+
55
+ // WC system is enabled so we will skip MEC gateways
56
+ if($WC_status) return false;
57
+
58
+ $this->factory->action('mec_gateways', array($this, 'register_gateways'));
59
+ $this->factory->action('wp_ajax_mec_do_transaction_free', array($this, 'do_free_booking'));
60
+ $this->factory->action('wp_ajax_nopriv_mec_do_transaction_free', array($this, 'do_free_booking'));
61
+
62
+ new MEC_gateway_pay_locally();
63
+ new MEC_gateway_paypal_express();
64
+ new MEC_gateway_paypal_credit_card();
65
+ new MEC_gateway_stripe();
66
+ new MEC_gateway_woocommerce();
67
+ new MEC_gateway_stripe_connect();
68
+ new MEC_gateway_bank_transfer();
69
+
70
+ do_action('MEC_feature_gateways_init');
71
+ }
72
+
73
+ public function register_gateways($gateways = array())
74
+ {
75
+ $gateways['pay_locally'] = new MEC_gateway_pay_locally();
76
+ $gateways['paypal_express'] = new MEC_gateway_paypal_express();
77
+ $gateways['paypal_credit_card'] = new MEC_gateway_paypal_credit_card();
78
+ $gateways['stripe'] = new MEC_gateway_stripe();
79
+ $gateways['woocommerce'] = new MEC_gateway_woocommerce();
80
+ $gateways['stripe_connect'] = new MEC_gateway_stripe_connect();
81
+ $gateways['bank_transfer'] = new MEC_gateway_bank_transfer();
82
+
83
+ usort($gateways, function($a, $b)
84
+ {
85
+ $a_index = (isset($a->options) and isset($a->options['index'])) ? $a->options['index'] : 9999999999;
86
+ $b_index = (isset($b->options) and isset($b->options['index'])) ? $b->options['index'] : 9999999999;
87
+
88
+ if($a_index == $b_index) return 0;
89
+ return ($a_index < $b_index) ? -1 : 1;
90
+ });
91
+
92
+ return apply_filters('MEC_register_gateways', $gateways);
93
+ }
94
+
95
+ public function do_free_booking()
96
+ {
97
+ $transaction_id = isset($_POST['transaction_id']) ? sanitize_text_field($_POST['transaction_id']) : '';
98
+
99
+ // Verify that the nonce is valid.
100
+ if(!wp_verify_nonce(sanitize_text_field($_POST['_wpnonce']), 'mec_transaction_form_' . $transaction_id))
101
+ {
102
+ $this->main->response(array(
103
+ 'success' => 0,
104
+ 'code' => 'NONCE_IS_INVALID',
105
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
106
+ ));
107
+ }
108
+
109
+ $free_gateway = new MEC_gateway_free();
110
+ $results = $free_gateway->do_transaction($transaction_id);
111
+
112
+ $results['output'] = '<h4>' . __('Thanks for your booking.', 'modern-events-calendar-lite') . '</h4>
113
+ <div class="mec-event-book-message">
114
+ <div class="' . ($results['success'] ? 'mec-success' : 'mec-error') . '">' . $results['message'] . '</div>
115
+ </div>';
116
+
117
+ $this->main->response($results);
118
+ }
119
+ }
120
+
121
+ do_action('after_MEC_feature_gateways');
122
+
123
+ interface MEC_gateway_interface
124
+ {
125
+ public function id();
126
+ public function label();
127
+ public function options_form();
128
+ public function op_form();
129
+ public function options($transaction_id);
130
+ public function checkout_form($transaction_id, $params = array());
131
+ public function enabled();
132
+ public function op_enabled();
133
+ public function comment();
134
+ public function do_transaction();
135
+ public function register_user($ticket, $args);
136
+ }
137
+
138
+ class MEC_gateway extends MEC_base implements MEC_gateway_interface
139
+ {
140
+ /**
141
+ * @var MEC_main
142
+ */
143
+ public $main;
144
+
145
+ /**
146
+ * @var MEC_book
147
+ */
148
+ public $book;
149
+
150
+ /**
151
+ * @var MEC_factory
152
+ */
153
+ public $factory;
154
+
155
+ public $settings;
156
+ public $gateways_options;
157
+ public $PT;
158
+ public $id;
159
+ public $options;
160
+
161
+ public function __construct()
162
+ {
163
+ // MEC Main library
164
+ $this->main = $this->getMain();
165
+
166
+ // MEC Main library
167
+ $this->book = $this->getBook();
168
+
169
+ // Import MEC Factory
170
+ $this->factory = $this->getFactory();
171
+
172
+ // MEC settings
173
+ $this->settings = $this->main->get_settings();
174
+
175
+ // MEC gateways options
176
+ $this->gateways_options = $this->main->get_gateways_options();
177
+
178
+ // MEC Book Post Type Name
179
+ $this->PT = $this->main->get_book_post_type();
180
+ }
181
+
182
+ public function id()
183
+ {
184
+ return $this->id;
185
+ }
186
+
187
+ public function label()
188
+ {
189
+ return __('Gateway', 'modern-events-calendar-lite');
190
+ }
191
+
192
+ public function color()
193
+ {
194
+ return '#E7E9ED';
195
+ }
196
+
197
+ public function title()
198
+ {
199
+ return (isset($this->options['title']) and trim($this->options['title'])) ? $this->options['title'] : $this->label();
200
+ }
201
+
202
+ public function options_form()
203
+ {
204
+ }
205
+
206
+ public function op_form()
207
+ {
208
+ }
209
+
210
+ public function options($transaction_id = NULL)
211
+ {
212
+ $options = isset($this->gateways_options[$this->id]) ? $this->gateways_options[$this->id] : array();
213
+ return apply_filters('mec_gateway_options', $options, $this->id, $transaction_id);
214
+ }
215
+
216
+ public function checkout_form($transaction_id, $params = array())
217
+ {
218
+ }
219
+
220
+ public function enabled()
221
+ {
222
+ return ((isset($this->options['status']) and $this->options['status']) ? true : false);
223
+ }
224
+
225
+ public function op_enabled()
226
+ {
227
+ return false;
228
+ }
229
+
230
+ public function comment()
231
+ {
232
+ return ((isset($this->options['comment']) and trim($this->options['comment'])) ? '<p class="mec-gateway-comment">' . __(stripslashes($this->options['comment']), 'modern-events-calendar-lite') . '</p>' : '');
233
+ }
234
+
235
+ public function do_transaction($transaction_id = null)
236
+ {
237
+ }
238
+
239
+ public function response($response)
240
+ {
241
+ $this->main->response($response);
242
+ }
243
+
244
+ public function register_user($attendee, $args = array())
245
+ {
246
+ $user = $this->getUser();
247
+ return $user->register($attendee, $args);
248
+ }
249
+
250
+ public function get_request_string($vars)
251
+ {
252
+ $string = '';
253
+ foreach($vars as $var => $val) $string .= '&' . $var . '=' . urlencode(stripslashes($val));
254
+
255
+ return $string;
256
+ }
257
+
258
+ public function decode_custom($encoded)
259
+ {
260
+ $base64 = urldecode($encoded);
261
+ $json = base64_decode($base64);
262
+
263
+ return json_decode($json, true);
264
+ }
265
+
266
+ public function get_paypal_response($request_str, $url)
267
+ {
268
+ $results = null;
269
+
270
+ $api_url = $url;
271
+ $parsed_url = parse_url($api_url);
272
+ $fp = fsockopen('ssl://' . $parsed_url['host'], '443', $errNum, $errStr, 30);
273
+
274
+ if(!$fp)
275
+ {
276
+ // @TODO log error here
277
+ return '';
278
+ }
279
+ else
280
+ {
281
+ fputs($fp, 'POST ' . $parsed_url['path'] . " HTTP/1.1\r\n");
282
+ fputs($fp, 'Host: ' . $parsed_url['host'] . "\r\n");
283
+ fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
284
+ fputs($fp, 'Content-length: ' . strlen($request_str) . "\r\n");
285
+ fputs($fp, "Connection: close\r\n\r\n");
286
+ fputs($fp, $request_str . "\r\n\r\n");
287
+
288
+ $results = '';
289
+ while(!feof($fp)) $results .= fgets($fp, 1024);
290
+
291
+ fclose($fp);
292
+
293
+ list($header, $body) = preg_split('/\R\R/', $results, 2);
294
+ $results = $body;
295
+ }
296
+
297
+ return $results;
298
+ }
299
+
300
+ public function get_cancel_url($event_id)
301
+ {
302
+ return trim(get_permalink($event_id), '/') . '/gateway-cancel/';
303
+ }
304
+
305
+ public function get_return_url($event_id, $thankyou = true)
306
+ {
307
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
308
+ if($thankyou_page_id and $thankyou)
309
+ {
310
+ return $this->book->get_thankyou_page($thankyou_page_id, NULL);
311
+ }
312
+
313
+ return trim(get_permalink($event_id), '/') . '/gateway-return/';
314
+ }
315
+
316
+ public function validate($transaction_id)
317
+ {
318
+ $transaction = $this->book->get_transaction($transaction_id);
319
+
320
+ // Check Transaction State
321
+ if(isset($transaction['booking_id']) and trim($transaction['booking_id'])) return true;
322
+
323
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
324
+ $date = isset($transaction['date']) ? $transaction['date'] : '';
325
+ $timestamps = explode(':', $date);
326
+
327
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
328
+ if(!$event_id) return true;
329
+
330
+ $tickets = array();
331
+ foreach($attendees as $attendee)
332
+ {
333
+ $ticket_id = (isset($attendee['id']) ? $attendee['id'] : 0);
334
+ if(!$ticket_id) continue;
335
+
336
+ if(!isset($tickets[$ticket_id])) $tickets[$ticket_id] = 1;
337
+ else $tickets[$ticket_id]++;
338
+ }
339
+
340
+ $availability = $this->book->get_tickets_availability($event_id, $timestamps[0]);
341
+ $event_tickets = get_post_meta($event_id, 'mec_tickets', true);
342
+
343
+ foreach($tickets as $ticket_id => $quantity)
344
+ {
345
+ // Ticket is not available
346
+ if(!isset($availability[$ticket_id]) or (isset($availability[$ticket_id]) and $availability[$ticket_id] != '-1' and $availability[$ticket_id] < $quantity))
347
+ {
348
+ if($availability[$ticket_id] == '0') $this->response(array('success' => 0, 'code' => 'SOLDOUT', 'message' => sprintf(__('%s ticket is sold out! Please go back and select another ticket if available.', 'modern-events-calendar-lite'), $event_tickets[$ticket_id]['name'])));
349
+ else $this->response(array('success' => 0, 'code' => 'SOLDOUT', 'message' => sprintf(__('Only %s slots remained for %s ticket so you cannot book %s ones.', 'modern-events-calendar-lite'), $availability[$ticket_id], $event_tickets[$ticket_id]['name'], $quantity)));
350
+ }
351
+ }
352
+
353
+ return true;
354
+ }
355
+
356
+ public function stripe_multiply($amount, $currency = NULL)
357
+ {
358
+ if(is_null($currency)) $currency = $this->main->get_currency_code();
359
+
360
+ // Zero Decimal Currencies
361
+ if(in_array($currency, array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'))) return (int) $amount;
362
+ else return (int) ($amount * 100);
363
+ }
364
+
365
+ public function get_stripe_charge_description($transaction_id)
366
+ {
367
+ $transaction = $this->book->get_transaction($transaction_id);
368
+ $event_title = (isset($transaction['event_id']) ? get_the_title($transaction['event_id']) : 'N/A');
369
+
370
+ return sprintf(__('MEC Transaction ID: %s, Event Title: %s', 'modern-events-calendar-lite'), $transaction_id, $event_title);
371
+ }
372
+
373
+ public function cart_validate($cart_id)
374
+ {
375
+ // Cart Library
376
+ $c = $this->getCart();
377
+
378
+ $cart = $c->get_cart($cart_id);
379
+
380
+ $validity = true;
381
+ $messages = array();
382
+
383
+ foreach($cart as $transaction_id)
384
+ {
385
+ $transaction = $this->book->get_transaction($transaction_id);
386
+
387
+ // Check Transaction State
388
+ if(isset($transaction['booking_id']) and trim($transaction['booking_id'])) continue;
389
+
390
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
391
+ $date = isset($transaction['date']) ? $transaction['date'] : '';
392
+ $timestamps = explode(':', $date);
393
+
394
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
395
+ if(!$event_id) continue;
396
+
397
+ $tickets = array();
398
+ foreach($attendees as $attendee)
399
+ {
400
+ $ticket_id = (isset($attendee['id']) ? $attendee['id'] : 0);
401
+ if(!$ticket_id) continue;
402
+
403
+ if(!isset($tickets[$ticket_id])) $tickets[$ticket_id] = 1;
404
+ else $tickets[$ticket_id]++;
405
+ }
406
+
407
+ $availability = $this->book->get_tickets_availability($event_id, $timestamps[0]);
408
+ $event_tickets = get_post_meta($event_id, 'mec_tickets', true);
409
+
410
+ foreach($tickets as $ticket_id => $quantity)
411
+ {
412
+ // Ticket is not available
413
+ if(!isset($availability[$ticket_id]) or (isset($availability[$ticket_id]) and $availability[$ticket_id] != '-1' and $availability[$ticket_id] < $quantity))
414
+ {
415
+ $validity = false;
416
+
417
+ if($availability[$ticket_id] == '0') $messages[] = sprintf(__('%s Transaction: %s ticket is sold out! Please remove it and book another ticket if available.', 'modern-events-calendar-lite'), $transaction_id, $event_tickets[$ticket_id]['name']);
418
+ else $messages[] = sprintf(__('%s Transaction: Only %s slots remained for %s ticket so you cannot book %s ones.', 'modern-events-calendar-lite'), $transaction_id, $availability[$ticket_id], $event_tickets[$ticket_id]['name'], $quantity);
419
+ }
420
+ }
421
+ }
422
+
423
+ if(!$validity)
424
+ {
425
+ $this->response(array(
426
+ 'success' => 0,
427
+ 'code' => 'SOLDOUT',
428
+ 'message' => implode('<br>', $messages)
429
+ ));
430
+ }
431
+
432
+ return true;
433
+ }
434
+
435
+ public function do_cart_transaction($cart_id, $params = array())
436
+ {
437
+ $gateway_key = ((isset($params['gateway']) and trim($params['gateway'])) ? $params['gateway'] : '');
438
+
439
+ // Cart Library
440
+ $c = $this->getCart();
441
+
442
+ $cart = $c->get_cart($cart_id);
443
+
444
+ $book_ids = array();
445
+ foreach($cart as $transaction_id)
446
+ {
447
+ $transaction = $this->book->get_transaction($transaction_id);
448
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
449
+
450
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
451
+ $attention_times = explode(':', $attention_date);
452
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
453
+
454
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
455
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
456
+
457
+ $ticket_ids = '';
458
+ $attendees_info = array();
459
+
460
+ foreach($attendees as $i => $attendee)
461
+ {
462
+ if(!is_numeric($i)) continue;
463
+
464
+ $ticket_ids .= $attendee['id'] . ',';
465
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
466
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
467
+ }
468
+
469
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
470
+ $user_id = $this->register_user($main_attendee, $transaction);
471
+
472
+ // Remove Sensitive Data
473
+ if(isset($transaction['username']) or isset($transaction['password']))
474
+ {
475
+ unset($transaction['username']);
476
+ unset($transaction['password']);
477
+
478
+ $this->book->update_transaction($transaction_id, $transaction);
479
+ }
480
+
481
+ // MEC User
482
+ $u = $this->getUser();
483
+
484
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
485
+ $book_id = $this->book->add(
486
+ array(
487
+ 'post_author' => $user_id,
488
+ 'post_type' => $this->PT,
489
+ 'post_title' => $book_subject,
490
+ 'post_date' => $date,
491
+ 'attendees_info' => $attendees_info,
492
+ 'mec_attendees' => $attendees,
493
+ 'mec_gateway' => $gateway_key,
494
+ 'mec_gateway_label' => $this->title()
495
+ ),
496
+ $transaction_id,
497
+ $ticket_ids
498
+ );
499
+
500
+ if(!$book_id) $book_id = $this->book->get_book_id_transaction_id($transaction_id);
501
+
502
+ // Assign User
503
+ $u->assign($book_id, $user_id);
504
+
505
+ // Fires after completely creating a new booking
506
+ do_action('mec_booking_completed', $book_id);
507
+
508
+ $book_ids[] = $book_id;
509
+ }
510
+
511
+ $invoice_status = (isset($this->settings['mec_cart_invoice']) and $this->settings['mec_cart_invoice']);
512
+ $invoice_link = (!$invoice_status) ? '' : $c->get_invoice_link($cart_id);
513
+
514
+ $message = stripslashes($this->main->m('cart_success_message', __('Thank you for your booking. Your bookings are made, booking verification might be needed, please check your email.', 'modern-events-calendar-lite')));
515
+ if(trim($invoice_link)) $message .= ' <a class="mec-invoice-download" href="'.esc_url($invoice_link).'">'.__('Download Invoice', 'modern-events-calendar-lite').'</a>';
516
+
517
+ // Make the Cart Empty
518
+ $c->clear($cart_id);
519
+
520
+ return array(
521
+ 'success' => 1,
522
+ 'message' => $message,
523
+ 'data' => array(
524
+ 'book_ids' => $book_ids,
525
+ 'invoice_link' => $invoice_link,
526
+ ),
527
+ );
528
+ }
529
+ }
530
+
531
+ class MEC_gateway_stripe extends MEC_gateway
532
+ {
533
+ public $id = 5;
534
+ public $options;
535
+
536
+ public function __construct()
537
+ {
538
+ parent::__construct();
539
+
540
+ // Gateway options
541
+ $this->options = $this->options();
542
+
543
+ $this->factory->action('init', array($this, 'include_api'));
544
+
545
+ // Register actions
546
+ $this->factory->action('wp_ajax_mec_do_transaction_stripe', array($this, 'do_transaction'));
547
+ $this->factory->action('wp_ajax_nopriv_mec_do_transaction_stripe', array($this, 'do_transaction'));
548
+
549
+ // Add Stripe JS Library
550
+ if($this->enabled() and !is_admin()) $this->factory->action('wp_enqueue_scripts', array($this, 'frontend_assets'));
551
+
552
+ // iDEAL verification
553
+ $this->factory->action('init', array($this, 'do_ideal_transaction'));
554
+
555
+ // MEC Cart
556
+ $this->factory->action('wp_ajax_mec_cart_do_transaction_stripe', array($this, 'cart_do_transaction'));
557
+ $this->factory->action('wp_ajax_nopriv_mec_cart_do_transaction_stripe', array($this, 'cart_do_transaction'));
558
+ $this->factory->action('init', array($this, 'cart_do_ideal_transaction'));
559
+ }
560
+
561
+ public function frontend_assets()
562
+ {
563
+ $stripe_js = apply_filters('mec_gateways_stripe_js', true);
564
+ if($stripe_js) wp_enqueue_script('mec-stripe', 'https://js.stripe.com/v3/');
565
+ }
566
+
567
+ public function label()
568
+ {
569
+ return __('Stripe', 'modern-events-calendar-lite');
570
+ }
571
+
572
+ public function color()
573
+ {
574
+ return '#FF7D51';
575
+ }
576
+
577
+ public function include_api()
578
+ {
579
+ if(class_exists('Stripe')) return;
580
+
581
+ MEC::import('app.api.Stripe.autoload', false);
582
+ }
583
+
584
+ public function do_transaction($transaction_id = null)
585
+ {
586
+ if(!trim($transaction_id)) $transaction_id = isset($_GET['transaction_id']) ? sanitize_text_field($_GET['transaction_id']) : 0;
587
+
588
+ // Verify that the nonce is valid.
589
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_transaction_form_' . $transaction_id))
590
+ {
591
+ $this->response(array(
592
+ 'success' => 0,
593
+ 'code' => 'NONCE_IS_INVALID',
594
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
595
+ ));
596
+ }
597
+
598
+ // Validate Ticket Availability
599
+ $this->validate($transaction_id);
600
+
601
+ $transaction = $this->book->get_transaction($transaction_id);
602
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
603
+
604
+ // Invalid Transaction
605
+ if(!is_array($transaction) or (is_array($transaction) and !isset($transaction['price']))) return false;
606
+
607
+ // Is there any attendee?
608
+ if(!count($attendees))
609
+ {
610
+ $this->response(
611
+ array(
612
+ 'success' => 0,
613
+ 'code' => 'NO_TICKET',
614
+ 'message' => __(
615
+ 'There is no attendee for booking!',
616
+ 'mec'
617
+ ),
618
+ )
619
+ );
620
+ }
621
+
622
+ // Transaction is not done
623
+ if(!isset($transaction['done']))
624
+ {
625
+ // Stripe Payment Details
626
+ $payment_method_id = isset($_GET['payment_method_id']) ? sanitize_text_field($_GET['payment_method_id']) : '';
627
+ $payment_intent_id = isset($_GET['payment_intent_id']) ? sanitize_text_field($_GET['payment_intent_id']) : '';
628
+
629
+ // Pay
630
+ $results = $this->pay($payment_method_id, $payment_intent_id, $transaction_id);
631
+
632
+ // Payment is invalid
633
+ if(!$results['success'])
634
+ {
635
+ $this->response(
636
+ array(
637
+ 'success' => 0,
638
+ 'code' => 'INVALID_PAYMENT',
639
+ 'message' => $results['message'],
640
+ )
641
+ );
642
+ }
643
+
644
+ // Payment requires more actions
645
+ if($results['success'] == 2)
646
+ {
647
+ $this->response(
648
+ array(
649
+ 'success' => 2,
650
+ 'requires_action' => 1,
651
+ 'code' => 'REQUIRES_ACTION',
652
+ 'payment_intent_client_secret' => $results['payment_intent_client_secret'],
653
+ )
654
+ );
655
+ }
656
+
657
+ // Get Options Compatible with Organizer Payment
658
+ $options = $this->options($transaction_id);
659
+
660
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
661
+ $attention_times = explode(':', $attention_date);
662
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
663
+
664
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
665
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
666
+
667
+ $ticket_ids = '';
668
+ $attendees_info = array();
669
+
670
+ foreach($attendees as $i => $attendee)
671
+ {
672
+ if(!is_numeric($i)) continue;
673
+
674
+ $ticket_ids .= $attendee['id'] . ',';
675
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
676
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
677
+ }
678
+
679
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
680
+ $user_id = $this->register_user($main_attendee, $transaction);
681
+
682
+ // Remove Sensitive Data
683
+ if(isset($transaction['username']) or isset($transaction['password']))
684
+ {
685
+ unset($transaction['username']);
686
+ unset($transaction['password']);
687
+ }
688
+
689
+ $transaction['done'] = 1;
690
+ $this->book->update_transaction($transaction_id, $transaction);
691
+
692
+ // MEC User
693
+ $u = $this->getUser();
694
+
695
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
696
+ $book_id = $this->book->add(
697
+ array(
698
+ 'post_author' => $user_id,
699
+ 'post_type' => $this->PT,
700
+ 'post_title' => $book_subject,
701
+ 'post_date' => $date,
702
+ 'attendees_info' => $attendees_info,
703
+ 'mec_attendees' => $attendees,
704
+ 'mec_gateway' => 'MEC_gateway_stripe',
705
+ 'mec_gateway_label' => $this->title()
706
+ ),
707
+ $transaction_id,
708
+ $ticket_ids
709
+ );
710
+
711
+ // Assign User
712
+ $u->assign($book_id, $user_id);
713
+
714
+ // Gateway Referrer
715
+ update_post_meta($book_id, 'mec_gateway_ref_type', 'intent');
716
+ update_post_meta($book_id, 'mec_gateway_ref_id', (isset($results['id']) ? $results['id'] : ''));
717
+
718
+ // Fires after completely creating a new booking
719
+ do_action('mec_booking_completed', $book_id);
720
+
721
+ // Create Stripe Customer
722
+ if(isset($results['id']))
723
+ {
724
+ $user_email = $u->get($user_id)->user_email;
725
+
726
+ $stripe = new \Stripe\StripeClient($options['secret_key']);
727
+
728
+ // Search Customers
729
+ $customers = $stripe->customers->all([
730
+ 'email' => $user_email,
731
+ 'limit' => 1,
732
+ ]);
733
+
734
+ if($customers->count()) $customer = $customers->first();
735
+ else
736
+ {
737
+ $customer = $stripe->customers->create([
738
+ 'name' => $name,
739
+ 'email' => $user_email,
740
+ ]);
741
+ }
742
+
743
+ if($customer and isset($customer->id)) $stripe->paymentIntents->update($results['id'], ['customer' => $customer->id, 'receipt_email' => $user_email]);
744
+ }
745
+ }
746
+ else $book_id = (isset($transaction['booking_id']) ? $transaction['booking_id'] : 0);
747
+
748
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
749
+ $redirect_to = '';
750
+
751
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
752
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
753
+
754
+ // Invoice Link
755
+ $mec_confirmed = get_post_meta($book_id, 'mec_confirmed', true);
756
+ $invoice_link = (!$mec_confirmed) ? '' : $this->book->get_invoice_link($transaction_id);
757
+ $dl_file_link = (!$mec_confirmed) ? '' : $this->book->get_dl_file_link($book_id);
758
+
759
+ $extra_info = apply_filters('MEC_extra_info_gateways', '', $this->book->get_event_id_by_transaction_id($transaction_id), $book_id);
760
+
761
+ $this->response(
762
+ array(
763
+ 'success' => 1,
764
+ 'message' => stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite'))),
765
+ 'data' => array(
766
+ 'book_id' => $book_id,
767
+ 'redirect_to' => $redirect_to,
768
+ 'invoice_link' => $invoice_link,
769
+ 'dl_file_link' => $dl_file_link,
770
+ 'extra_info' => $extra_info,
771
+ ),
772
+ )
773
+ );
774
+ }
775
+
776
+ public function pay($payment_method_id, $payment_intent_id, $transaction_id)
777
+ {
778
+ $transaction = $this->book->get_transaction($transaction_id);
779
+
780
+ // Get Options Compatible with Organizer Payment
781
+ $options = $this->options($transaction_id);
782
+
783
+ // Set Stripe Secret Key
784
+ \Stripe\Stripe::setApiKey($options['secret_key']);
785
+
786
+ // Get Status of Payment Intent
787
+ if($payment_intent_id)
788
+ {
789
+ $intent = \Stripe\PaymentIntent::retrieve($payment_intent_id);
790
+ $intent->confirm();
791
+
792
+ if($intent->status == 'succeeded') return array('success' => 1, 'id' => $intent->id);
793
+ else if($intent->status == 'requires_confirmation') return array('success' => 0, 'message' => __('Your payment needs to be confirmed!', 'modern-events-calendar-lite'));
794
+ else return array('success' => 0, 'message' => __('Unknown Error!', 'modern-events-calendar-lite'));
795
+ }
796
+
797
+ try
798
+ {
799
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
800
+ $currency_code = $this->main->get_currency_code($event_id);
801
+
802
+ $intent = \Stripe\PaymentIntent::create(
803
+ array(
804
+ 'payment_method' => $payment_method_id,
805
+ 'amount' => (isset($transaction['price']) ? ((int) $this->stripe_multiply($transaction['price'], $currency_code)) : 0),
806
+ 'currency' => $currency_code,
807
+ 'description' => $this->get_stripe_charge_description($transaction_id),
808
+ 'confirmation_method' => 'manual',
809
+ 'confirm' => true,
810
+ )
811
+ );
812
+ }
813
+ catch(Exception $e)
814
+ {
815
+ return array(
816
+ 'success' => 0,
817
+ 'message' => $e->getMessage(),
818
+ );
819
+ }
820
+
821
+ if($intent->status == 'requires_action' and $intent->next_action->type == 'use_stripe_sdk')
822
+ {
823
+ # Tell the client to handle the action
824
+ return array(
825
+ 'success' => 2,
826
+ 'requires_action' => true,
827
+ 'payment_intent_client_secret' => $intent->client_secret
828
+ );
829
+ }
830
+ elseif($intent->status == 'succeeded') return array('success' => 1, 'id' => $intent->id);
831
+ else return array('success' => 0, 'message' => __('Unknown Error!', 'modern-events-calendar-lite'));
832
+ }
833
+
834
+ public function do_ideal_transaction()
835
+ {
836
+ $transaction_id = isset($_GET['mec_ideal_transaction_id']) ? sanitize_text_field($_GET['mec_ideal_transaction_id']) : NULL;
837
+ if(!trim($transaction_id)) return false;
838
+
839
+ $source = isset($_GET['source']) ? sanitize_text_field($_GET['source']) : NULL;
840
+ if(!trim($source)) return false;
841
+
842
+ $transaction = $this->book->get_transaction($transaction_id);
843
+
844
+ // Invalid Transaction
845
+ if(!is_array($transaction) or (is_array($transaction) and !isset($transaction['price']))) return false;
846
+
847
+ // Transaction is done
848
+ if(isset($transaction['done']) and $transaction['done'] == '1') return false;
849
+
850
+ // Get Options Compatible with Organizer Payment
851
+ $options = $this->options($transaction_id);
852
+
853
+ try
854
+ {
855
+ // Set Stripe Secret Key
856
+ \Stripe\Stripe::setApiKey($options['secret_key']);
857
+
858
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
859
+ $currency_code = $this->main->get_currency_code($event_id);
860
+
861
+ $charge = \Stripe\Charge::create([
862
+ 'amount' => (isset($transaction['price']) ? ((int) $this->stripe_multiply($transaction['price'], $currency_code)) : 0),
863
+ 'currency' => $currency_code,
864
+ 'source' => $source,
865
+ ]);
866
+ }
867
+ catch(Exception $e)
868
+ {
869
+ return false;
870
+ }
871
+
872
+ // Payment Invalid
873
+ if(!$charge->captured or !$charge->paid) return false;
874
+
875
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
876
+
877
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
878
+ $attention_times = explode(':', $attention_date);
879
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
880
+
881
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
882
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
883
+
884
+ $ticket_ids = '';
885
+ $attendees_info = array();
886
+
887
+ foreach($attendees as $i => $attendee)
888
+ {
889
+ if(!is_numeric($i)) continue;
890
+
891
+ $ticket_ids .= $attendee['id'] . ',';
892
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
893
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
894
+ }
895
+
896
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
897
+ $user_id = $this->register_user($main_attendee, $transaction);
898
+
899
+ // Remove Sensitive Data
900
+ if(isset($transaction['username']) or isset($transaction['password']))
901
+ {
902
+ unset($transaction['username']);
903
+ unset($transaction['password']);
904
+ }
905
+
906
+ $transaction['done'] = 1;
907
+ $this->book->update_transaction($transaction_id, $transaction);
908
+
909
+ // MEC User
910
+ $u = $this->getUser();
911
+
912
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
913
+ $book_id = $this->book->add(
914
+ array(
915
+ 'post_author' => $user_id,
916
+ 'post_type' => $this->PT,
917
+ 'post_title' => $book_subject,
918
+ 'post_date' => $date,
919
+ 'attendees_info' => $attendees_info,
920
+ 'mec_attendees' => $attendees,
921
+ 'mec_gateway' => 'MEC_gateway_stripe',
922
+ 'mec_gateway_label' => $this->title()
923
+ ),
924
+ $transaction_id,
925
+ $ticket_ids
926
+ );
927
+
928
+ // Assign User
929
+ $u->assign($book_id, $user_id);
930
+
931
+ // Gateway Referrer
932
+ update_post_meta($book_id, 'mec_gateway_ref_type', 'charge');
933
+ update_post_meta($book_id, 'mec_gateway_ref_id', (isset($charge->id) ? $charge->id : ''));
934
+
935
+ // Fires after completely creating a new booking
936
+ do_action('mec_booking_completed', $book_id);
937
+
938
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
939
+ $redirect_to = '';
940
+
941
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
942
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
943
+
944
+ // Create Stripe Customer
945
+ if($charge and $charge->id)
946
+ {
947
+ $user_email = $u->get($user_id)->user_email;
948
+
949
+ $stripe = new \Stripe\StripeClient($options['secret_key']);
950
+
951
+ // Search Customers
952
+ $customers = $stripe->customers->all([
953
+ 'email' => $user_email,
954
+ 'limit' => 1,
955
+ ]);
956
+
957
+ if($customers->count()) $customer = $customers->first();
958
+ else
959
+ {
960
+ $customer = $stripe->customers->create([
961
+ 'name' => $name,
962
+ 'email' => $user_email,
963
+ ]);
964
+ }
965
+
966
+ if($customer and isset($customer->id)) $stripe->charges->update($charge->id, ['customer' => $customer->id]);
967
+ }
968
+
969
+ // Redirect
970
+ if(trim($redirect_to))
971
+ {
972
+ wp_redirect($redirect_to);
973
+ exit;
974
+ }
975
+ }
976
+
977
+ public function refund($booking_id, $amount = NULL)
978
+ {
979
+ $gateway_ref_type = get_post_meta($booking_id, 'mec_gateway_ref_type', true);
980
+ $gateway_ref_id = get_post_meta($booking_id, 'mec_gateway_ref_id', true);
981
+
982
+ // Amount
983
+ if(trim($amount) == '') $amount = get_post_meta($booking_id, 'mec_price', true);
984
+
985
+ // Transaction ID
986
+ $transaction_id = $this->book->get_transaction_id_book_id($booking_id);
987
+
988
+ // Get Options Compatible with Organizer Payment
989
+ $options = $this->options($transaction_id);
990
+
991
+ // Set Stripe Secret Key
992
+ \Stripe\Stripe::setApiKey($options['secret_key']);
993
+
994
+ try
995
+ {
996
+ if($gateway_ref_type == 'intent')
997
+ {
998
+ $args = array(
999
+ 'payment_intent' => $gateway_ref_id,
1000
+ 'amount' => ((int) $this->stripe_multiply($amount))
1001
+ );
1002
+ }
1003
+ else
1004
+ {
1005
+ $args = array(
1006
+ 'charge' => $gateway_ref_id,
1007
+ 'amount' => ((int) $this->stripe_multiply($amount))
1008
+ );
1009
+ }
1010
+
1011
+ // Refund
1012
+ $results = \Stripe\Refund::create($args);
1013
+
1014
+ // Refund ID
1015
+ update_post_meta($booking_id, 'mec_refund_ref_id', (isset($results->id) ? $results->id : NULL));
1016
+
1017
+ if($results and isset($results->id)) return true;
1018
+ else return false;
1019
+ }
1020
+ catch(Exception $e)
1021
+ {
1022
+ return false;
1023
+ }
1024
+ }
1025
+
1026
+ public function checkout_form($transaction_id, $params = array())
1027
+ {
1028
+ // Get Options Compatible with Organizer Payment
1029
+ $options = $this->options($transaction_id);
1030
+
1031
+ // Payment Method
1032
+ $payment_method = (isset($options['payment_method']) and trim($options['payment_method'])) ? $options['payment_method'] : 'cc';
1033
+
1034
+ if($payment_method == 'cc') $this->checkout_form_cc($transaction_id, $options, $params);
1035
+ elseif($payment_method == 'ideal') $this->checkout_form_ideal($transaction_id, $options, $params);
1036
+ }
1037
+
1038
+ public function checkout_form_cc($transaction_id, $options, $params = array())
1039
+ {
1040
+ $transaction = $this->book->get_transaction($transaction_id);
1041
+
1042
+ $main_attendee_name = ((isset($transaction['tickets']) and isset($transaction['tickets'][0]) and isset($transaction['tickets'][0]['name'])) ? $transaction['tickets'][0]['name'] : '');
1043
+ $main_attendee_email = ((isset($transaction['tickets']) and isset($transaction['tickets'][0]) and isset($transaction['tickets'][0]['email'])) ? $transaction['tickets'][0]['email'] : '');
1044
+ ?>
1045
+ <script type="text/javascript">
1046
+ var stripe = Stripe("<?php echo(isset($options['publishable_key']) ? $options['publishable_key'] : ''); ?>");
1047
+ var elements = stripe.elements();
1048
+ var style = {
1049
+ base: {
1050
+ color: '#32325d',
1051
+ fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
1052
+ fontSmoothing: 'antialiased',
1053
+ fontSize: '16px',
1054
+ minHeight: '40px',
1055
+ '::placeholder': {
1056
+ color: '#aab7c4'
1057
+ },
1058
+ },
1059
+ invalid: {
1060
+ color: '#fa755a',
1061
+ iconColor: '#fa755a'
1062
+ }
1063
+ };
1064
+
1065
+ var card = elements.create('card');
1066
+ card.mount('#mec_card_element_stripe_<?php echo $transaction_id; ?>');
1067
+
1068
+ // Validation
1069
+ card.addEventListener('change', function(event)
1070
+ {
1071
+ // Show the Error
1072
+ if(event.error) jQuery('#mec_do_transaction_stripe_message<?php echo $transaction_id; ?>').text(event.error.message).addClass('mec-error').show();
1073
+ // Hide the Message
1074
+ else jQuery("#mec_do_transaction_stripe_message<?php echo $transaction_id; ?>").removeClass("mec-success mec-error").hide();
1075
+ });
1076
+
1077
+ jQuery('#mec_do_transaction_stripe_form<?php echo $transaction_id; ?>').on('submit', function(e)
1078
+ {
1079
+ // Prevent the form from submitting
1080
+ e.preventDefault();
1081
+
1082
+ var form = jQuery(this);
1083
+ var transaction_id = '<?php echo $transaction_id; ?>';
1084
+
1085
+ // No pressing the buy now button more than once
1086
+ form.find('button').prop('disabled', true);
1087
+
1088
+ // Hide the Message
1089
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).removeClass("mec-success mec-error").hide();
1090
+
1091
+ // Add loading Class to the button
1092
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").addClass("loading");
1093
+
1094
+ var payer_name = jQuery("#mec_name_stripe_" + transaction_id).val();
1095
+ var payer_email = jQuery("#mec_email_stripe_" + transaction_id).val();
1096
+ var payer_details = {
1097
+ billing_details: {}
1098
+ };
1099
+
1100
+ if(payer_name !== '') payer_details.billing_details.name = payer_name;
1101
+ if(payer_email !== '') payer_details.billing_details.email = payer_email;
1102
+
1103
+ stripe.createPaymentMethod('card', card, payer_details).then(function(result)
1104
+ {
1105
+ if(result.error)
1106
+ {
1107
+ // Remove the loading Class from the button
1108
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").removeClass("loading");
1109
+
1110
+ // Show the user what they did wrong
1111
+ jQuery('#mec_do_transaction_stripe_message' + transaction_id).text(result.error.message).addClass('mec-error').show();
1112
+
1113
+ // Make the submit clickable again
1114
+ form.find('button').prop('disabled', false);
1115
+ }
1116
+ else
1117
+ {
1118
+ // Hide the Message
1119
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).removeClass("mec-success mec-error").hide();
1120
+
1121
+ // Set Payment Method ID
1122
+ jQuery("#mec_do_transaction_stripe_payment_method_id" + transaction_id).val(result.paymentMethod.id);
1123
+
1124
+ var data = form.serialize();
1125
+ jQuery.ajax(
1126
+ {
1127
+ type: "GET",
1128
+ url: "<?php echo admin_url('admin-ajax.php', NULL); ?>",
1129
+ data: data,
1130
+ dataType: "JSON",
1131
+ success: function(data)
1132
+ {
1133
+ if(data.success === 1)
1134
+ {
1135
+ // Remove the loading Class from the button
1136
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").removeClass("loading");
1137
+
1138
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id).hide();
1139
+ jQuery(".mec-book-form-gateway-label").remove();
1140
+ jQuery(".mec-book-form-coupon").hide();
1141
+ jQuery(".mec-gateway-comment").hide();
1142
+
1143
+ jQuery("#mec-book-form-back-btn-step-3").remove();
1144
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).addClass("mec-success").html(data.message).show();
1145
+
1146
+ // Show Invoice Link
1147
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
1148
+ {
1149
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
1150
+ }
1151
+
1152
+ // Show Downloadable Link
1153
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
1154
+ {
1155
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
1156
+ }
1157
+
1158
+ // Show Extra info
1159
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
1160
+ {
1161
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).append('<div>' + data.data.extra_info+'</div>');
1162
+ }
1163
+
1164
+ // Redirect to thank you page
1165
+ if(typeof data.data.redirect_to !== "undefined" && data.data.redirect_to !== "")
1166
+ {
1167
+ setTimeout(function()
1168
+ {
1169
+ window.location.href = data.data.redirect_to;
1170
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
1171
+ }
1172
+ }
1173
+ else if(data.requires_action)
1174
+ {
1175
+ stripe.handleCardAction(data.payment_intent_client_secret).then(function(result)
1176
+ {
1177
+ if(result.error)
1178
+ {
1179
+ // Show the user what they did wrong
1180
+ jQuery('#mec_do_transaction_stripe_message' + transaction_id).text(result.error.message).addClass('mec-error').show();
1181
+
1182
+ // Remove the loading Class from the button
1183
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").removeClass("loading");
1184
+
1185
+ // Make the submit clickable again
1186
+ form.find('button').prop('disabled', false);
1187
+ }
1188
+ else
1189
+ {
1190
+ // Set Payment Intent ID
1191
+ jQuery("#mec_do_transaction_stripe_payment_intent_id" + transaction_id).val(result.paymentIntent.id);
1192
+
1193
+ var data = form.serialize();
1194
+ jQuery.ajax(
1195
+ {
1196
+ type: "GET",
1197
+ url: "<?php echo admin_url('admin-ajax.php', NULL); ?>",
1198
+ data: data,
1199
+ dataType: "JSON",
1200
+ success: function(data)
1201
+ {
1202
+ if(data.success === 1)
1203
+ {
1204
+ // Remove the loading Class from the button
1205
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").removeClass("loading");
1206
+
1207
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id).hide();
1208
+ jQuery(".mec-book-form-gateway-label").remove();
1209
+ jQuery(".mec-book-form-coupon").hide();
1210
+ jQuery(".mec-gateway-comment").hide();
1211
+
1212
+ jQuery("#mec-book-form-back-btn-step-3").remove();
1213
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).addClass("mec-success").html(data.message).show();
1214
+
1215
+ // Show Invoice Link
1216
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
1217
+ {
1218
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
1219
+ }
1220
+
1221
+ // Show Downloadable Link
1222
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
1223
+ {
1224
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
1225
+ }
1226
+
1227
+ // Show Extra info
1228
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
1229
+ {
1230
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).append('<div>' + data.data.extra_info+'</div>');
1231
+ }
1232
+
1233
+ // Redirect to thank you page
1234
+ if(typeof data.data.redirect_to !== "undefined" && data.data.redirect_to !== "")
1235
+ {
1236
+ setTimeout(function()
1237
+ {
1238
+ window.location.href = data.data.redirect_to;
1239
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
1240
+ }
1241
+ }
1242
+ else
1243
+ {
1244
+ // Remove the loading Class from the button
1245
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").removeClass("loading");
1246
+
1247
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).addClass("mec-error").html(data.message).show();
1248
+ }
1249
+ },
1250
+ error: function(jqXHR, textStatus, errorThrown)
1251
+ {
1252
+ // Remove the loading Class from the button
1253
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").removeClass("loading");
1254
+ }
1255
+ });
1256
+ }
1257
+ });
1258
+ }
1259
+ else
1260
+ {
1261
+ // Remove the loading Class from the button
1262
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").removeClass("loading");
1263
+
1264
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).addClass("mec-error").html(data.message).show();
1265
+ }
1266
+ },
1267
+ error: function(jqXHR, textStatus, errorThrown)
1268
+ {
1269
+ // Remove the loading Class from the button
1270
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").removeClass("loading");
1271
+ }
1272
+ });
1273
+ }
1274
+ });
1275
+ });
1276
+ </script>
1277
+ <div class="mec-gateway-message mec-util-hidden"
1278
+ id="mec_do_transaction_stripe_message<?php echo $transaction_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
1279
+ <form id="mec_do_transaction_stripe_form<?php echo $transaction_id; ?>">
1280
+ <div class="mec-form-row mec-name-stripe">
1281
+ <label for="mec_name_stripe_<?php echo $transaction_id; ?>">
1282
+ <?php _e('Name', 'modern-events-calendar-lite'); ?>
1283
+ </label>
1284
+ <input id="mec_name_stripe_<?php echo $transaction_id; ?>" type="text" value="<?php echo esc_attr($main_attendee_name); ?>">
1285
+ </div>
1286
+ <div class="mec-form-row mec-email-stripe">
1287
+ <label for="mec_email_stripe_<?php echo $transaction_id; ?>">
1288
+ <?php _e('Email', 'modern-events-calendar-lite'); ?>
1289
+ </label>
1290
+ <input id="mec_email_stripe_<?php echo $transaction_id; ?>" type="email" value="<?php echo esc_attr($main_attendee_email); ?>">
1291
+ </div>
1292
+ <div class="mec-form-row mec-card-element-stripe">
1293
+ <label for="mec_card_element_stripe_<?php echo $transaction_id; ?>">
1294
+ <?php _e('Credit or debit card', 'modern-events-calendar-lite'); ?>
1295
+ </label>
1296
+ <div id="mec_card_element_stripe_<?php echo $transaction_id; ?>">
1297
+ </div>
1298
+ </div>
1299
+ <div class="mec-form-row mec-click-pay">
1300
+ <input type="hidden" name="action" value="mec_do_transaction_stripe"/>
1301
+ <input type="hidden" name="transaction_id" value="<?php echo $transaction_id; ?>"/>
1302
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
1303
+ <input type="hidden" name="payment_method_id" value="" id="mec_do_transaction_stripe_payment_method_id<?php echo $transaction_id; ?>"/>
1304
+ <input type="hidden" name="payment_intent_id" value="" id="mec_do_transaction_stripe_payment_intent_id<?php echo $transaction_id; ?>"/>
1305
+ <?php wp_nonce_field('mec_transaction_form_' . $transaction_id); ?>
1306
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
1307
+ </div>
1308
+ </form>
1309
+ <?php
1310
+ }
1311
+
1312
+ public function checkout_form_ideal($transaction_id, $options, $params = array())
1313
+ {
1314
+ $transaction = $this->book->get_transaction($transaction_id);
1315
+
1316
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
1317
+ $main_attendee_name = ((isset($transaction['tickets']) and isset($transaction['tickets'][0]) and isset($transaction['tickets'][0]['name'])) ? $transaction['tickets'][0]['name'] : '');
1318
+ ?>
1319
+ <script type="text/javascript">
1320
+ var stripe = Stripe("<?php echo(isset($options['publishable_key']) ? $options['publishable_key'] : ''); ?>");
1321
+ var elements = stripe.elements();
1322
+
1323
+ var idealBank = elements.create('idealBank');
1324
+ idealBank.mount('#mec_card_element_stripe_<?php echo $transaction_id; ?>');
1325
+
1326
+ jQuery('#mec_do_transaction_stripe_form<?php echo $transaction_id; ?>').on('submit', function(e)
1327
+ {
1328
+ // Prevent the form from submitting
1329
+ e.preventDefault();
1330
+
1331
+ var form = jQuery(this);
1332
+ var transaction_id = '<?php echo $transaction_id; ?>';
1333
+
1334
+ // No pressing the buy now button more than once
1335
+ form.find('button').prop('disabled', true);
1336
+
1337
+ // Hide the Message
1338
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).removeClass("mec-success mec-error").hide();
1339
+
1340
+ // Add loading Class to the button
1341
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").addClass("loading");
1342
+
1343
+ var payer_name = jQuery("#mec_name_stripe_" + transaction_id).val();
1344
+ var payable = jQuery("#mec_ideal_stripe_amount").val();
1345
+ var source = {
1346
+ type: 'ideal',
1347
+ amount: payable,
1348
+ currency: '<?php echo $this->main->get_currency_code($event_id); ?>',
1349
+ owner:
1350
+ {
1351
+ name: payer_name,
1352
+ },
1353
+ redirect:
1354
+ {
1355
+ return_url: '<?php echo $this->main->add_qs_var('mec_ideal_transaction_id', $transaction_id, $this->get_return_url($event_id, false)); ?>',
1356
+ }
1357
+ };
1358
+
1359
+ stripe.createSource(idealBank, source).then(function(result)
1360
+ {
1361
+ if(result.error) jQuery("#mec_do_transaction_stripe_message" + transaction_id).addClass("mec-error").html(result.error.message).show();
1362
+ else document.location.href = result.source.redirect.url;
1363
+ });
1364
+ });
1365
+ </script>
1366
+ <div class="mec-gateway-message mec-util-hidden"
1367
+ id="mec_do_transaction_stripe_message<?php echo $transaction_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
1368
+ <form id="mec_do_transaction_stripe_form<?php echo $transaction_id; ?>">
1369
+ <div class="info-msg"><?php esc_html_e("You should complete the payment by returning back to the website.", 'modern-events-calendar-lite'); ?></div>
1370
+ <div class="mec-form-row mec-name-stripe">
1371
+ <label for="mec_name_stripe_<?php echo $transaction_id; ?>">
1372
+ <?php _e('Name', 'modern-events-calendar-lite'); ?>
1373
+ </label>
1374
+ <input id="mec_name_stripe_<?php echo $transaction_id; ?>" type="text" value="<?php echo esc_attr($main_attendee_name); ?>" required>
1375
+ </div>
1376
+ <div class="mec-form-row mec-ideal-element-stripe">
1377
+ <label for="mec_card_element_stripe_<?php echo $transaction_id; ?>">
1378
+ <?php _e('iDEAL Bank', 'modern-events-calendar-lite'); ?>
1379
+ </label>
1380
+ <div id="mec_card_element_stripe_<?php echo $transaction_id; ?>">
1381
+ </div>
1382
+ </div>
1383
+ <div class="mec-form-row mec-click-pay">
1384
+ <input type="hidden" id="mec_ideal_stripe_amount" value="<?php echo (isset($transaction['price']) ? ((int) $this->stripe_multiply($transaction['price'], $this->main->get_currency_code($event_id))) : 0); ?>">
1385
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
1386
+ </div>
1387
+ </form>
1388
+ <?php
1389
+ }
1390
+
1391
+ public function options_form()
1392
+ {
1393
+ ?>
1394
+ <div class="mec-form-row">
1395
+ <label>
1396
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][status]" value="0"/>
1397
+ <input onchange="jQuery('#mec_gateways<?php echo $this->id(); ?>_container_toggle').toggle();" value="1"
1398
+ type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][status]"
1399
+ <?php
1400
+ if (isset($this->options['status']) and $this->options['status']) {
1401
+ echo 'checked="checked"';
1402
+ }
1403
+ ?>
1404
+ /> <?php _e('Stripe', 'modern-events-calendar-lite'); ?>
1405
+ </label>
1406
+ </div>
1407
+ <div id="mec_gateways<?php echo $this->id(); ?>_container_toggle" class="mec-gateway-options-form <?php
1408
+ if ((isset($this->options['status']) and !$this->options['status']) or !isset($this->options['status'])) {
1409
+ echo 'mec-util-hidden';
1410
+ }
1411
+ ?>">
1412
+ <div class="mec-form-row">
1413
+ <label class="mec-col-3"
1414
+ for="mec_gateways<?php echo $this->id(); ?>_title"><?php _e('Title', 'modern-events-calendar-lite'); ?></label>
1415
+ <div class="mec-col-9">
1416
+ <input type="text" id="mec_gateways<?php echo $this->id(); ?>_title"
1417
+ name="mec[gateways][<?php echo $this->id(); ?>][title]"
1418
+ value="<?php echo (isset($this->options['title']) and trim($this->options['title'])) ? $this->options['title'] : ''; ?>"
1419
+ placeholder="<?php echo $this->label(); ?>"/>
1420
+ </div>
1421
+ </div>
1422
+ <div class="mec-form-row">
1423
+ <label class="mec-col-3"
1424
+ for="mec_gateways<?php echo $this->id(); ?>_comment"><?php _e('Comment', 'modern-events-calendar-lite'); ?></label>
1425
+ <div class="mec-col-9">
1426
+ <textarea id="mec_gateways<?php echo $this->id(); ?>_comment"
1427
+ name="mec[gateways][<?php echo $this->id(); ?>][comment]"><?php echo (isset($this->options['comment']) and trim($this->options['comment'])) ? stripslashes($this->options['comment']) : esc_html__('Stripe Gateway Description', 'modern-events-calendar-lite'); ?></textarea>
1428
+ <span class="mec-tooltip">
1429
+ <div class="box left">
1430
+ <h5 class="title"><?php _e('Comment', 'modern-events-calendar-lite'); ?></h5>
1431
+ <div class="content"><p><?php esc_attr_e('HTML allowed.', 'modern-events-calendar-lite'); ?><a
1432
+ href="https://webnus.net/dox/modern-events-calendar/booking/"
1433
+ target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
1434
+ </div>
1435
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
1436
+ </span>
1437
+ </div>
1438
+ </div>
1439
+ <div class="mec-form-row">
1440
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_payment_method"><?php _e('Payment Method', 'modern-events-calendar-lite'); ?></label>
1441
+ <div class="mec-col-9">
1442
+ <select name="mec[gateways][<?php echo $this->id(); ?>][payment_method]" id="mec_gateways<?php echo $this->id(); ?>_comment">
1443
+ <option value="cc" <?php echo (isset($this->options['payment_method']) and $this->options['payment_method'] == 'cc') ? 'selected="selected"' : ''; ?>><?php esc_html_e('Credit Card', 'modern-events-calendar-lite'); ?></option>
1444
+ <option value="ideal" <?php echo (isset($this->options['payment_method']) and $this->options['payment_method'] == 'ideal') ? 'selected="selected"' : ''; ?>><?php esc_html_e('iDEAL', 'modern-events-calendar-lite'); ?></option>
1445
+ </select>
1446
+ </div>
1447
+ </div>
1448
+ <div class="mec-form-row">
1449
+ <label class="mec-col-3"
1450
+ for="mec_gateways<?php echo $this->id(); ?>_secret_key"><?php _e('Secret Key', 'modern-events-calendar-lite'); ?></label>
1451
+ <div class="mec-col-9">
1452
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_secret_key"
1453
+ name="mec[gateways][<?php echo $this->id(); ?>][secret_key]"
1454
+ value="<?php echo isset($this->options['secret_key']) ? $this->options['secret_key'] : ''; ?>"/>
1455
+ </div>
1456
+ </div>
1457
+ <div class="mec-form-row">
1458
+ <label class="mec-col-3"
1459
+ for="mec_gateways<?php echo $this->id(); ?>_publishable_key"><?php _e('Publishable Key', 'modern-events-calendar-lite'); ?></label>
1460
+ <div class="mec-col-9">
1461
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_publishable_key"
1462
+ name="mec[gateways][<?php echo $this->id(); ?>][publishable_key]"
1463
+ value="<?php echo isset($this->options['publishable_key']) ? $this->options['publishable_key'] : ''; ?>"/>
1464
+ </div>
1465
+ </div>
1466
+ <div class="mec-form-row">
1467
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_index"><?php _e('Position', 'modern-events-calendar-lite'); ?></label>
1468
+ <div class="mec-col-9">
1469
+ <input type="number" min="0" step="1" id="mec_gateways<?php echo $this->id(); ?>_index"
1470
+ name="mec[gateways][<?php echo $this->id(); ?>][index]"
1471
+ value="<?php echo (isset($this->options['index']) and trim($this->options['index'])) ? $this->options['index'] : 4; ?>"
1472
+ placeholder="<?php echo esc_attr__('Position', 'modern-events-calendar-lite'); ?>"/>
1473
+ </div>
1474
+ </div>
1475
+ </div>
1476
+ <?php
1477
+ }
1478
+
1479
+ public function op_enabled()
1480
+ {
1481
+ return true;
1482
+ }
1483
+
1484
+ public function op_form($options = array())
1485
+ {
1486
+ ?>
1487
+ <h4><?php echo $this->label(); ?></h4>
1488
+ <div class="mec-gateway-options-form">
1489
+ <div class="mec-form-row">
1490
+ <label class="mec-col-3" for="mec_op<?php echo $this->id(); ?>_secret_key"><?php _e('Secret Key', 'modern-events-calendar-lite'); ?></label>
1491
+ <div class="mec-col-9">
1492
+ <input type="text" id="mec_op<?php echo $this->id(); ?>_secret_key" name="mec[op][<?php echo $this->id(); ?>][secret_key]" value="<?php echo isset($options['secret_key']) ? $options['secret_key'] : ''; ?>" />
1493
+ </div>
1494
+ </div>
1495
+ <div class="mec-form-row">
1496
+ <label class="mec-col-3" for="mec_op<?php echo $this->id(); ?>_publishable_key"><?php _e('Publishable Key', 'modern-events-calendar-lite'); ?></label>
1497
+ <div class="mec-col-9">
1498
+ <input type="text" id="mec_op<?php echo $this->id(); ?>_publishable_key" name="mec[op][<?php echo $this->id(); ?>][publishable_key]" value="<?php echo isset($options['publishable_key']) ? $options['publishable_key'] : ''; ?>"/>
1499
+ </div>
1500
+ </div>
1501
+ </div>
1502
+ <?php
1503
+ }
1504
+
1505
+ public function cart_checkout_form($cart_id, $params = array())
1506
+ {
1507
+ // Get Options
1508
+ $options = $this->options();
1509
+
1510
+ // Payment Method
1511
+ $payment_method = (isset($options['payment_method']) and trim($options['payment_method'])) ? $options['payment_method'] : 'cc';
1512
+
1513
+ if($payment_method == 'cc') $this->cart_checkout_form_cc($cart_id, $options, $params);
1514
+ elseif($payment_method == 'ideal') $this->cart_checkout_form_ideal($cart_id, $options, $params);
1515
+ }
1516
+
1517
+ public function cart_checkout_form_cc($cart_id, $options, $params = array())
1518
+ {
1519
+ ?>
1520
+ <div class="mec-gateway-message mec-util-hidden"
1521
+ id="mec_do_transaction_stripe_message<?php echo $cart_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
1522
+ <form id="mec_do_transaction_stripe_form<?php echo $cart_id; ?>">
1523
+ <div class="mec-form-row mec-name-stripe">
1524
+ <label for="mec_name_stripe_<?php echo $cart_id; ?>">
1525
+ <?php _e('Name', 'modern-events-calendar-lite'); ?>
1526
+ </label>
1527
+ <input id="mec_name_stripe_<?php echo $cart_id; ?>" type="text" value="">
1528
+ </div>
1529
+ <div class="mec-form-row mec-email-stripe">
1530
+ <label for="mec_email_stripe_<?php echo $cart_id; ?>">
1531
+ <?php _e('Email', 'modern-events-calendar-lite'); ?>
1532
+ </label>
1533
+ <input id="mec_email_stripe_<?php echo $cart_id; ?>" type="email" value="">
1534
+ </div>
1535
+ <div class="mec-form-row mec-card-element-stripe">
1536
+ <label for="mec_card_element_stripe_<?php echo $cart_id; ?>">
1537
+ <?php _e('Credit or debit card', 'modern-events-calendar-lite'); ?>
1538
+ </label>
1539
+ <div id="mec_card_element_stripe_<?php echo $cart_id; ?>">
1540
+ </div>
1541
+ </div>
1542
+ <div class="mec-form-row mec-click-pay">
1543
+ <input type="hidden" name="action" value="mec_cart_do_transaction_stripe"/>
1544
+ <input type="hidden" name="cart_id" value="<?php echo $cart_id; ?>"/>
1545
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
1546
+ <input type="hidden" name="payment_method_id" value="" id="mec_do_transaction_stripe_payment_method_id<?php echo $cart_id; ?>"/>
1547
+ <input type="hidden" name="payment_intent_id" value="" id="mec_do_transaction_stripe_payment_intent_id<?php echo $cart_id; ?>"/>
1548
+ <?php wp_nonce_field('mec_transaction_form_' . $cart_id); ?>
1549
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
1550
+ </div>
1551
+ </form>
1552
+ <script type="text/javascript">
1553
+ var stripe = Stripe("<?php echo(isset($options['publishable_key']) ? $options['publishable_key'] : ''); ?>");
1554
+ var elements = stripe.elements();
1555
+ var style = {
1556
+ base: {
1557
+ color: '#32325d',
1558
+ fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
1559
+ fontSmoothing: 'antialiased',
1560
+ fontSize: '16px',
1561
+ minHeight: '40px',
1562
+ '::placeholder': {
1563
+ color: '#aab7c4'
1564
+ },
1565
+ },
1566
+ invalid: {
1567
+ color: '#fa755a',
1568
+ iconColor: '#fa755a'
1569
+ }
1570
+ };
1571
+
1572
+ var card = elements.create('card');
1573
+ card.mount('#mec_card_element_stripe_<?php echo $cart_id; ?>');
1574
+
1575
+ // Validation
1576
+ card.addEventListener('change', function(event)
1577
+ {
1578
+ // Show the Error
1579
+ if(event.error) jQuery('#mec_do_transaction_stripe_message<?php echo $cart_id; ?>').text(event.error.message).addClass('mec-error').show();
1580
+ // Hide the Message
1581
+ else jQuery("#mec_do_transaction_stripe_message<?php echo $cart_id; ?>").removeClass("mec-success mec-error").hide();
1582
+ });
1583
+
1584
+ jQuery('#mec_do_transaction_stripe_form<?php echo $cart_id; ?>').on('submit', function(e)
1585
+ {
1586
+ // Prevent the form from submitting
1587
+ e.preventDefault();
1588
+
1589
+ var form = jQuery(this);
1590
+ var cart_id = '<?php echo $cart_id; ?>';
1591
+
1592
+ // No pressing the buy now button more than once
1593
+ form.find('button').prop('disabled', true);
1594
+
1595
+ // Hide the Message
1596
+ jQuery("#mec_do_transaction_stripe_message" + cart_id).removeClass("mec-success mec-error").hide();
1597
+
1598
+ // Add loading Class to the button
1599
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").addClass("loading");
1600
+
1601
+ var payer_name = jQuery("#mec_name_stripe_" + cart_id).val();
1602
+ var payer_email = jQuery("#mec_email_stripe_" + cart_id).val();
1603
+ var payer_details = {
1604
+ billing_details: {}
1605
+ };
1606
+
1607
+ if(payer_name !== '') payer_details.billing_details.name = payer_name;
1608
+ if(payer_email !== '') payer_details.billing_details.email = payer_email;
1609
+
1610
+ stripe.createPaymentMethod('card', card, payer_details).then(function(result)
1611
+ {
1612
+ if(result.error)
1613
+ {
1614
+ // Remove the loading Class from the button
1615
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").removeClass("loading");
1616
+
1617
+ // Show the user what they did wrong
1618
+ jQuery('#mec_do_transaction_stripe_message' + cart_id).text(result.error.message).addClass('mec-error').show();
1619
+
1620
+ // Make the submit clickable again
1621
+ form.find('button').prop('disabled', false);
1622
+ }
1623
+ else
1624
+ {
1625
+ // Hide the Message
1626
+ jQuery("#mec_do_transaction_stripe_message" + cart_id).removeClass("mec-success mec-error").hide();
1627
+
1628
+ // Set Payment Method ID
1629
+ jQuery("#mec_do_transaction_stripe_payment_method_id" + cart_id).val(result.paymentMethod.id);
1630
+
1631
+ var data = form.serialize();
1632
+ jQuery.ajax(
1633
+ {
1634
+ type: "GET",
1635
+ url: "<?php echo admin_url('admin-ajax.php', NULL); ?>",
1636
+ data: data,
1637
+ dataType: "JSON",
1638
+ success: function(data)
1639
+ {
1640
+ if(data.success === 1)
1641
+ {
1642
+ // Remove the loading Class from the button
1643
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").removeClass("loading");
1644
+
1645
+ jQuery("#mec_do_transaction_stripe_form" + cart_id).hide();
1646
+ jQuery(".mec-checkout-form-gateway-label").remove();
1647
+ jQuery(".mec-gateway-comment").hide();
1648
+
1649
+ jQuery("#mec_do_transaction_stripe_message" + cart_id).addClass("mec-success").html(data.message).show();
1650
+ }
1651
+ else if(data.requires_action)
1652
+ {
1653
+ stripe.handleCardAction(data.payment_intent_client_secret).then(function(result)
1654
+ {
1655
+ if(result.error)
1656
+ {
1657
+ // Show the user what they did wrong
1658
+ jQuery('#mec_do_transaction_stripe_message' + cart_id).text(result.error.message).addClass('mec-error').show();
1659
+
1660
+ // Remove the loading Class from the button
1661
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").removeClass("loading");
1662
+
1663
+ // Make the submit clickable again
1664
+ form.find('button').prop('disabled', false);
1665
+ }
1666
+ else
1667
+ {
1668
+ // Set Payment Intent ID
1669
+ jQuery("#mec_do_transaction_stripe_payment_intent_id" + cart_id).val(result.paymentIntent.id);
1670
+
1671
+ var data = form.serialize();
1672
+ jQuery.ajax(
1673
+ {
1674
+ type: "GET",
1675
+ url: "<?php echo admin_url('admin-ajax.php', NULL); ?>",
1676
+ data: data,
1677
+ dataType: "JSON",
1678
+ success: function(data)
1679
+ {
1680
+ if(data.success === 1)
1681
+ {
1682
+ // Remove the loading Class from the button
1683
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").removeClass("loading");
1684
+
1685
+ jQuery("#mec_do_transaction_stripe_form" + cart_id).hide();
1686
+ jQuery(".mec-checkout-form-gateway-label").remove();
1687
+ jQuery(".mec-gateway-comment").hide();
1688
+
1689
+ jQuery("#mec_do_transaction_stripe_message" + cart_id).addClass("mec-success").html(data.message).show();
1690
+ }
1691
+ else
1692
+ {
1693
+ // Remove the loading Class from the button
1694
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").removeClass("loading");
1695
+
1696
+ jQuery("#mec_do_transaction_stripe_message" + cart_id).addClass("mec-error").html(data.message).show();
1697
+ }
1698
+ },
1699
+ error: function(jqXHR, textStatus, errorThrown)
1700
+ {
1701
+ // Remove the loading Class from the button
1702
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").removeClass("loading");
1703
+ }
1704
+ });
1705
+ }
1706
+ });
1707
+ }
1708
+ else
1709
+ {
1710
+ // Remove the loading Class from the button
1711
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").removeClass("loading");
1712
+
1713
+ jQuery("#mec_do_transaction_stripe_message" + cart_id).addClass("mec-error").html(data.message).show();
1714
+ }
1715
+ },
1716
+ error: function(jqXHR, textStatus, errorThrown)
1717
+ {
1718
+ // Remove the loading Class from the button
1719
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").removeClass("loading");
1720
+ }
1721
+ });
1722
+ }
1723
+ });
1724
+ });
1725
+ </script>
1726
+ <?php
1727
+ }
1728
+
1729
+ public function cart_checkout_form_ideal($cart_id, $options, $params = array())
1730
+ {
1731
+ $c = $this->getCart();
1732
+ $cart = $c->get_cart($cart_id);
1733
+
1734
+ $payable = $c->get_payable($cart);
1735
+ $event_id = $c->get_first_event_id($cart);
1736
+ ?>
1737
+ <div class="mec-gateway-message mec-util-hidden"
1738
+ id="mec_do_transaction_stripe_message<?php echo $cart_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
1739
+ <form id="mec_do_transaction_stripe_form<?php echo $cart_id; ?>">
1740
+ <div class="info-msg"><?php esc_html_e("You should complete the payment by returning back to the website.", 'modern-events-calendar-lite'); ?></div>
1741
+ <div class="mec-form-row mec-name-stripe">
1742
+ <label for="mec_name_stripe_<?php echo $cart_id; ?>">
1743
+ <?php _e('Name', 'modern-events-calendar-lite'); ?> <span class="mec-required">*</span>
1744
+ </label>
1745
+ <input id="mec_name_stripe_<?php echo $cart_id; ?>" type="text" value="" required>
1746
+ </div>
1747
+ <div class="mec-form-row mec-ideal-element-stripe">
1748
+ <label for="mec_card_element_stripe_<?php echo $cart_id; ?>">
1749
+ <?php _e('iDEAL Bank', 'modern-events-calendar-lite'); ?>
1750
+ </label>
1751
+ <div id="mec_card_element_stripe_<?php echo $cart_id; ?>">
1752
+ </div>
1753
+ </div>
1754
+ <div class="mec-form-row mec-click-pay">
1755
+ <input type="hidden" id="mec_ideal_stripe_amount" value="<?php echo ((int) $this->stripe_multiply($payable, $this->main->get_currency_code())); ?>">
1756
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
1757
+ </div>
1758
+ </form>
1759
+ <script type="text/javascript">
1760
+ var stripe = Stripe("<?php echo(isset($options['publishable_key']) ? $options['publishable_key'] : ''); ?>");
1761
+ var elements = stripe.elements();
1762
+
1763
+ var idealBank = elements.create('idealBank');
1764
+ idealBank.mount('#mec_card_element_stripe_<?php echo $cart_id; ?>');
1765
+
1766
+ jQuery('#mec_do_transaction_stripe_form<?php echo $cart_id; ?>').on('submit', function(e)
1767
+ {
1768
+ // Prevent the form from submitting
1769
+ e.preventDefault();
1770
+
1771
+ var form = jQuery(this);
1772
+ var cart_id = '<?php echo $cart_id; ?>';
1773
+
1774
+ // No pressing the buy now button more than once
1775
+ form.find('button').prop('disabled', true);
1776
+
1777
+ // Hide the Message
1778
+ jQuery("#mec_do_transaction_stripe_message" + cart_id).removeClass("mec-success mec-error").hide();
1779
+
1780
+ // Add loading Class to the button
1781
+ jQuery("#mec_do_transaction_stripe_form" + cart_id + " button[type=submit]").addClass("loading");
1782
+
1783
+ var payer_name = jQuery("#mec_name_stripe_" + cart_id).val();
1784
+ var payable = jQuery("#mec_ideal_stripe_amount").val();
1785
+ var source = {
1786
+ type: 'ideal',
1787
+ amount: payable,
1788
+ currency: '<?php echo $this->main->get_currency_code(); ?>',
1789
+ owner:
1790
+ {
1791
+ name: payer_name,
1792
+ },
1793
+ redirect:
1794
+ {
1795
+ return_url: '<?php echo $this->main->add_qs_var('mec_ideal_cart_id', $cart_id, $this->get_return_url($event_id, false)); ?>',
1796
+ }
1797
+ };
1798
+
1799
+ stripe.createSource(idealBank, source).then(function(result)
1800
+ {
1801
+ if(result.error) jQuery("#mec_do_transaction_stripe_message" + cart_id).addClass("mec-error").html(result.error.message).show();
1802
+ else document.location.href = result.source.redirect.url;
1803
+ });
1804
+ });
1805
+ </script>
1806
+ <?php
1807
+ }
1808
+
1809
+ public function cart_pay($payment_method_id, $payment_intent_id, $cart_id)
1810
+ {
1811
+ // Get Options Compatible with Organizer Payment
1812
+ $options = $this->options();
1813
+
1814
+ // Set Stripe Secret Key
1815
+ \Stripe\Stripe::setApiKey($options['secret_key']);
1816
+
1817
+ // Get Status of Payment Intent
1818
+ if($payment_intent_id)
1819
+ {
1820
+ $intent = \Stripe\PaymentIntent::retrieve($payment_intent_id);
1821
+ $intent->confirm();
1822
+
1823
+ if($intent->status == 'succeeded') return array('success' => 1, 'id' => $intent->id);
1824
+ else if($intent->status == 'requires_confirmation') return array('success' => 0, 'message' => __('Your payment needs to be confirmed!', 'modern-events-calendar-lite'));
1825
+ else return array('success' => 0, 'message' => __('Unknown Error!', 'modern-events-calendar-lite'));
1826
+ }
1827
+
1828
+ try
1829
+ {
1830
+ $c = $this->getCart();
1831
+ $cart = $c->get_cart($cart_id);
1832
+
1833
+ $payable = $c->get_payable($cart);
1834
+ $currency_code = $this->main->get_currency_code();
1835
+
1836
+ $intent = \Stripe\PaymentIntent::create(array(
1837
+ 'payment_method' => $payment_method_id,
1838
+ 'amount' => ((int) $this->stripe_multiply($payable, $currency_code)),
1839
+ 'currency' => $currency_code,
1840
+ 'description' => sprintf(__('Transaction IDs: %s', 'modern-events-calendar-lite'), implode(', ', $cart)),
1841
+ 'confirmation_method' => 'manual',
1842
+ 'confirm' => true,
1843
+ ));
1844
+ }
1845
+ catch(Exception $e)
1846
+ {
1847
+ return array(
1848
+ 'success' => 0,
1849
+ 'message' => $e->getMessage(),
1850
+ );
1851
+ }
1852
+
1853
+ if($intent->status == 'requires_action' and $intent->next_action->type == 'use_stripe_sdk')
1854
+ {
1855
+ # Tell the client to handle the action
1856
+ return array(
1857
+ 'success' => 2,
1858
+ 'requires_action' => true,
1859
+ 'payment_intent_client_secret' => $intent->client_secret
1860
+ );
1861
+ }
1862
+ elseif($intent->status == 'succeeded') return array('success' => 1, 'id' => $intent->id);
1863
+ else return array('success' => 0, 'message' => __('Unknown Error!', 'modern-events-calendar-lite'));
1864
+ }
1865
+
1866
+ public function cart_do_transaction()
1867
+ {
1868
+ $cart_id = isset($_GET['cart_id']) ? sanitize_text_field($_GET['cart_id']) : 0;
1869
+
1870
+ // Verify that the nonce is valid.
1871
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_transaction_form_' . $cart_id))
1872
+ {
1873
+ $this->response(array(
1874
+ 'success' => 0,
1875
+ 'code' => 'NONCE_IS_INVALID',
1876
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
1877
+ ));
1878
+ }
1879
+
1880
+ // Validate Ticket Availability
1881
+ $this->cart_validate($cart_id);
1882
+
1883
+ // Cart Library
1884
+ $c = $this->getCart();
1885
+
1886
+ $cart = $c->get_cart($cart_id);
1887
+
1888
+ /**
1889
+ * Payment
1890
+ */
1891
+ $payment_method_id = isset($_GET['payment_method_id']) ? sanitize_text_field($_GET['payment_method_id']) : '';
1892
+ $payment_intent_id = isset($_GET['payment_intent_id']) ? sanitize_text_field($_GET['payment_intent_id']) : '';
1893
+
1894
+ // Pay
1895
+ $results = $this->cart_pay($payment_method_id, $payment_intent_id, $cart_id);
1896
+
1897
+ // Payment is invalid
1898
+ if(!$results['success'])
1899
+ {
1900
+ $this->response(array(
1901
+ 'success' => 0,
1902
+ 'code' => 'INVALID_PAYMENT',
1903
+ 'message' => $results['message'],
1904
+ ));
1905
+ }
1906
+
1907
+ // Payment requires more actions
1908
+ if($results['success'] == 2)
1909
+ {
1910
+ $this->response(array(
1911
+ 'success' => 2,
1912
+ 'requires_action' => 1,
1913
+ 'code' => 'REQUIRES_ACTION',
1914
+ 'payment_intent_client_secret' => $results['payment_intent_client_secret'],
1915
+ ));
1916
+ }
1917
+
1918
+ $book_ids = array();
1919
+ foreach($cart as $transaction_id)
1920
+ {
1921
+ $transaction = $this->book->get_transaction($transaction_id);
1922
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
1923
+
1924
+ // Transaction is not done
1925
+ if(!isset($transaction['done']))
1926
+ {
1927
+ // Get Options
1928
+ $options = $this->options();
1929
+
1930
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
1931
+ $attention_times = explode(':', $attention_date);
1932
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
1933
+
1934
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
1935
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
1936
+
1937
+ $ticket_ids = '';
1938
+ $attendees_info = array();
1939
+
1940
+ foreach($attendees as $i => $attendee)
1941
+ {
1942
+ if(!is_numeric($i)) continue;
1943
+
1944
+ $ticket_ids .= $attendee['id'] . ',';
1945
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
1946
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
1947
+ }
1948
+
1949
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
1950
+ $user_id = $this->register_user($main_attendee, $transaction);
1951
+
1952
+ // Remove Sensitive Data
1953
+ if(isset($transaction['username']) or isset($transaction['password']))
1954
+ {
1955
+ unset($transaction['username']);
1956
+ unset($transaction['password']);
1957
+ }
1958
+
1959
+ $transaction['done'] = 1;
1960
+ $this->book->update_transaction($transaction_id, $transaction);
1961
+
1962
+ // MEC User
1963
+ $u = $this->getUser();
1964
+
1965
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
1966
+ $book_id = $this->book->add(
1967
+ array(
1968
+ 'post_author' => $user_id,
1969
+ 'post_type' => $this->PT,
1970
+ 'post_title' => $book_subject,
1971
+ 'post_date' => $date,
1972
+ 'attendees_info' => $attendees_info,
1973
+ 'mec_attendees' => $attendees,
1974
+ 'mec_gateway' => 'MEC_gateway_stripe',
1975
+ 'mec_gateway_label' => $this->title()
1976
+ ),
1977
+ $transaction_id,
1978
+ $ticket_ids
1979
+ );
1980
+
1981
+ // Assign User
1982
+ $u->assign($book_id, $user_id);
1983
+
1984
+ // Gateway Referrer
1985
+ update_post_meta($book_id, 'mec_gateway_ref_type', 'intent');
1986
+ update_post_meta($book_id, 'mec_gateway_ref_id', (isset($results['id']) ? $results['id'] : ''));
1987
+
1988
+ // Fires after completely creating a new booking
1989
+ do_action('mec_booking_completed', $book_id);
1990
+
1991
+ // Create Stripe Customer
1992
+ if(isset($results['id']))
1993
+ {
1994
+ $user_email = $u->get($user_id)->user_email;
1995
+
1996
+ $stripe = new \Stripe\StripeClient($options['secret_key']);
1997
+
1998
+ // Search Customers
1999
+ $customers = $stripe->customers->all([
2000
+ 'email' => $user_email,
2001
+ 'limit' => 1,
2002
+ ]);
2003
+
2004
+ if($customers->count()) $customer = $customers->first();
2005
+ else
2006
+ {
2007
+ $customer = $stripe->customers->create([
2008
+ 'name' => $name,
2009
+ 'email' => $user_email,
2010
+ ]);
2011
+ }
2012
+
2013
+ if($customer and isset($customer->id)) $stripe->paymentIntents->update($results['id'], ['customer' => $customer->id, 'receipt_email' => $user_email]);
2014
+ }
2015
+ }
2016
+ else $book_id = (isset($transaction['booking_id']) ? $transaction['booking_id'] : 0);
2017
+
2018
+ $book_ids[] = $book_id;
2019
+ }
2020
+
2021
+ $invoice_status = (isset($this->settings['mec_cart_invoice']) and $this->settings['mec_cart_invoice']);
2022
+ $invoice_link = (!$invoice_status) ? '' : $c->get_invoice_link($cart_id);
2023
+
2024
+ $message = stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite')));
2025
+ if(trim($invoice_link)) $message .= ' <a class="mec-invoice-download" href="'.esc_url($invoice_link).'">'.__('Download Invoice', 'modern-events-calendar-lite').'</a>';
2026
+
2027
+ // Make the Cart Empty
2028
+ $c->clear($cart_id);
2029
+
2030
+ $this->response(
2031
+ array(
2032
+ 'success' => 1,
2033
+ 'message' => $message,
2034
+ 'data' => array(
2035
+ 'book_ids' => $book_ids,
2036
+ 'invoice_link' => $invoice_link,
2037
+ ),
2038
+ )
2039
+ );
2040
+ }
2041
+
2042
+ public function cart_do_ideal_transaction()
2043
+ {
2044
+ $cart_id = isset($_GET['mec_ideal_cart_id']) ? sanitize_text_field($_GET['mec_ideal_cart_id']) : NULL;
2045
+ if(!trim($cart_id)) return false;
2046
+
2047
+ $source = isset($_GET['source']) ? sanitize_text_field($_GET['source']) : NULL;
2048
+ if(!trim($source)) return false;
2049
+
2050
+ // Cart Library
2051
+ $c = $this->getCart();
2052
+
2053
+ $cart = $c->get_cart($cart_id);
2054
+
2055
+ // Get Options
2056
+ $options = $this->options();
2057
+
2058
+ /**
2059
+ * Payment
2060
+ */
2061
+
2062
+ try
2063
+ {
2064
+ // Set Stripe Secret Key
2065
+ \Stripe\Stripe::setApiKey($options['secret_key']);
2066
+
2067
+ $payable = $c->get_payable($cart);
2068
+ $currency_code = $this->main->get_currency_code();
2069
+
2070
+ $charge = \Stripe\Charge::create([
2071
+ 'amount' => ((int) $this->stripe_multiply($payable, $currency_code)),
2072
+ 'currency' => $currency_code,
2073
+ 'source' => $source,
2074
+ ]);
2075
+ }
2076
+ catch(Exception $e)
2077
+ {
2078
+ return false;
2079
+ }
2080
+
2081
+ // Payment Invalid
2082
+ if(!$charge->captured or !$charge->paid) return false;
2083
+
2084
+ foreach($cart as $transaction_id)
2085
+ {
2086
+ $transaction = $this->book->get_transaction($transaction_id);
2087
+
2088
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
2089
+
2090
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
2091
+ $attention_times = explode(':', $attention_date);
2092
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
2093
+
2094
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
2095
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
2096
+
2097
+ $ticket_ids = '';
2098
+ $attendees_info = array();
2099
+
2100
+ foreach($attendees as $i => $attendee)
2101
+ {
2102
+ if(!is_numeric($i)) continue;
2103
+
2104
+ $ticket_ids .= $attendee['id'] . ',';
2105
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
2106
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
2107
+ }
2108
+
2109
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
2110
+ $user_id = $this->register_user($main_attendee, $transaction);
2111
+
2112
+ // Remove Sensitive Data
2113
+ if(isset($transaction['username']) or isset($transaction['password']))
2114
+ {
2115
+ unset($transaction['username']);
2116
+ unset($transaction['password']);
2117
+ }
2118
+
2119
+ $transaction['done'] = 1;
2120
+ $this->book->update_transaction($transaction_id, $transaction);
2121
+
2122
+ // MEC User
2123
+ $u = $this->getUser();
2124
+
2125
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
2126
+ $book_id = $this->book->add(
2127
+ array(
2128
+ 'post_author' => $user_id,
2129
+ 'post_type' => $this->PT,
2130
+ 'post_title' => $book_subject,
2131
+ 'post_date' => $date,
2132
+ 'attendees_info' => $attendees_info,
2133
+ 'mec_attendees' => $attendees,
2134
+ 'mec_gateway' => 'MEC_gateway_stripe',
2135
+ 'mec_gateway_label' => $this->title()
2136
+ ),
2137
+ $transaction_id,
2138
+ $ticket_ids
2139
+ );
2140
+
2141
+ // Assign User
2142
+ $u->assign($book_id, $user_id);
2143
+
2144
+ // Gateway Referrer
2145
+ update_post_meta($book_id, 'mec_gateway_ref_type', 'charge');
2146
+ update_post_meta($book_id, 'mec_gateway_ref_id', (isset($charge->id) ? $charge->id : ''));
2147
+
2148
+ // Fires after completely creating a new booking
2149
+ do_action('mec_booking_completed', $book_id);
2150
+
2151
+ // Create Stripe Customer
2152
+ if($charge and $charge->id)
2153
+ {
2154
+ $user_email = $u->get($user_id)->user_email;
2155
+
2156
+ $stripe = new \Stripe\StripeClient($options['secret_key']);
2157
+
2158
+ // Search Customers
2159
+ $customers = $stripe->customers->all([
2160
+ 'email' => $user_email,
2161
+ 'limit' => 1,
2162
+ ]);
2163
+
2164
+ if($customers->count()) $customer = $customers->first();
2165
+ else
2166
+ {
2167
+ $customer = $stripe->customers->create([
2168
+ 'name' => $name,
2169
+ 'email' => $user_email,
2170
+ ]);
2171
+ }
2172
+
2173
+ if($customer and isset($customer->id)) $stripe->charges->update($charge->id, ['customer' => $customer->id]);
2174
+ }
2175
+ }
2176
+
2177
+ // Make the Cart Empty
2178
+ $c->clear($cart_id);
2179
+
2180
+ return true;
2181
+ }
2182
+ }
2183
+
2184
+ class MEC_gateway_stripe_connect extends MEC_gateway
2185
+ {
2186
+ public $id = 7;
2187
+ public $options;
2188
+
2189
+ public function __construct()
2190
+ {
2191
+ parent::__construct();
2192
+
2193
+ // Gateway options
2194
+ $this->options = $this->options();
2195
+
2196
+ $this->factory->action('init', array($this, 'include_api'));
2197
+ $this->factory->action('init', array($this, 'authenticate'));
2198
+ $this->factory->action('init', array($this, 'express_redirect'));
2199
+ $this->factory->action('init', array($this, 'express_refresh'));
2200
+ $this->factory->action('init', array($this, 'express_return'));
2201
+ $this->factory->action('init', array($this, 'express_dashboard'));
2202
+
2203
+ // Register actions
2204
+ $this->factory->action('wp_ajax_mec_check_stripe_connection', array($this, 'check_connection'));
2205
+ $this->factory->action('wp_ajax_nopriv_mec_check_stripe_connection', array($this, 'check_connection'));
2206
+
2207
+ $this->factory->action('wp_ajax_mec_do_transaction_stripe_connect', array($this, 'do_transaction'));
2208
+ $this->factory->action('wp_ajax_nopriv_mec_do_transaction_stripe_connect', array($this, 'do_transaction'));
2209
+
2210
+ // Add Stripe JS Library
2211
+ if($this->enabled() and !is_admin()) $this->factory->action('wp_enqueue_scripts', array($this, 'frontend_assets'));
2212
+
2213
+ // iDEAL verification
2214
+ $this->factory->action('init', array($this, 'do_ideal_transaction'));
2215
+ }
2216
+
2217
+ public function frontend_assets()
2218
+ {
2219
+ $stripe_js = apply_filters('mec_gateways_stripe_js', true);
2220
+ if($stripe_js) wp_enqueue_script('mec-stripe', 'https://js.stripe.com/v3/');
2221
+ }
2222
+
2223
+ public function label()
2224
+ {
2225
+ return __('Stripe Connect', 'modern-events-calendar-lite');
2226
+ }
2227
+
2228
+ public function color()
2229
+ {
2230
+ return '#FFBE0C';
2231
+ }
2232
+
2233
+ public function get_connection_method()
2234
+ {
2235
+ return ((isset($this->options['connection_method']) and trim($this->options['connection_method'])) ? $this->options['connection_method'] : 'standard');
2236
+ }
2237
+
2238
+ public function include_api()
2239
+ {
2240
+ if(class_exists('Stripe')) return;
2241
+
2242
+ MEC::import('app.api.Stripe.autoload', false);
2243
+ }
2244
+
2245
+ /**
2246
+ * It run after come back from Stripe
2247
+ */
2248
+ public function authenticate()
2249
+ {
2250
+ // Is it a request to autheticate?
2251
+ $called = (isset($_GET['mec-stripe-connect']) and $_GET['mec-stripe-connect'] == 1) ? true : false;
2252
+ if(!$called) return;
2253
+
2254
+ $code = (isset($_GET['code']) and trim($_GET['code'])) ? $_GET['code'] : NULL;
2255
+ if(!$code) return;
2256
+
2257
+ $current_user_id = get_current_user_id();
2258
+ if(!$current_user_id) return;
2259
+
2260
+ // Call Stripe API to validate the request
2261
+ $post = array(
2262
+ 'client_secret' => $this->options['secret_key'],
2263
+ 'code' => $code,
2264
+ 'grant_type' => 'authorization_code'
2265
+ );
2266
+
2267
+ $ch = curl_init('https://connect.stripe.com/oauth/token');
2268
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
2269
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
2270
+
2271
+ $JSON = curl_exec($ch);
2272
+ curl_close($ch);
2273
+
2274
+ // Get Stripe Account ID
2275
+ $response = json_decode($JSON);
2276
+ $stripe_user_id = isset($response->stripe_user_id) ? $response->stripe_user_id : NULL;
2277
+
2278
+ // Stripe Account ID not found!
2279
+ if(!$stripe_user_id) return;
2280
+
2281
+ // Save User ID
2282
+ update_user_meta($current_user_id, 'mec_stripe_id', $stripe_user_id);
2283
+
2284
+ // Redirect
2285
+ $redirect_to = (isset($this->options['redirection_page']) and trim($this->options['redirection_page'])) ? get_permalink($this->options['redirection_page']) : get_home_url();
2286
+
2287
+ wp_redirect($redirect_to);
2288
+ exit;
2289
+ }
2290
+
2291
+ /**
2292
+ * It redirects the user to stripe for onboarding
2293
+ */
2294
+ public function express_redirect()
2295
+ {
2296
+ // Is it a request to redirect?
2297
+ $called = (isset($_GET['mec-stripe-connect-express-redirect']) and $_GET['mec-stripe-connect-express-redirect'] == 1) ? true : false;
2298
+ if(!$called) return;
2299
+
2300
+ // Is Nonce Valid?
2301
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_stripe_connect_express_redirect')) return;
2302
+
2303
+ // Do the Redirect
2304
+ $this->express_do_redirect();
2305
+ }
2306
+
2307
+ /**
2308
+ * It calls whenever use came back to refresh URL
2309
+ */
2310
+ public function express_refresh()
2311
+ {
2312
+ // Is it a request to refresh?
2313
+ $called = (isset($_GET['mec-stripe-connect-express-refresh']) and $_GET['mec-stripe-connect-express-refresh'] == 1) ? true : false;
2314
+ if(!$called) return;
2315
+
2316
+ // Do the Redirect
2317
+ $this->express_do_redirect();
2318
+ }
2319
+
2320
+ /**
2321
+ * It calls whenever use came back to refresh URL
2322
+ */
2323
+ public function express_return()
2324
+ {
2325
+ // Is user returned?
2326
+ $called = (isset($_GET['mec-stripe-connect-express-return']) and $_GET['mec-stripe-connect-express-return'] == 1) ? true : false;
2327
+ if(!$called) return;
2328
+
2329
+ $current_user_id = get_current_user_id();
2330
+ if(!$current_user_id) return;
2331
+
2332
+ $strip_account_id_temp = get_user_meta($current_user_id, 'mec_stripe_id_temp', true);
2333
+ if(!$strip_account_id_temp) return;
2334
+
2335
+ // Set Stripe Secret Key
2336
+ \Stripe\Stripe::setApiKey($this->options['secret_key']);
2337
+ $account = \Stripe\Account::retrieve($strip_account_id_temp);
2338
+
2339
+ // A problem occurred in getting account
2340
+ if(!$account or (is_object($account) and !isset($account->id)))
2341
+ {
2342
+ wp_redirect($this->main->URL('site'));
2343
+ exit;
2344
+ }
2345
+
2346
+ // Onboarding Completed ...
2347
+ if($account->charges_enabled) update_user_meta($current_user_id, 'mec_stripe_id', $account->id);
2348
+
2349
+ // Redirect
2350
+ $redirect_to = (isset($this->options['redirection_page']) and trim($this->options['redirection_page'])) ? get_permalink($this->options['redirection_page']) : get_home_url();
2351
+
2352
+ wp_redirect($redirect_to);
2353
+ exit;
2354
+ }
2355
+
2356
+ public function express_do_redirect()
2357
+ {
2358
+ $current_user_id = get_current_user_id();
2359
+ if(!$current_user_id) return;
2360
+
2361
+ // Set Stripe Secret Key
2362
+ \Stripe\Stripe::setApiKey($this->options['secret_key']);
2363
+
2364
+ $temp_account_id = get_user_meta($current_user_id, 'mec_stripe_id_temp', true);
2365
+ if(!$temp_account_id)
2366
+ {
2367
+ try
2368
+ {
2369
+ // Account
2370
+ $account = \Stripe\Account::create([
2371
+ 'type' => 'express',
2372
+ ]);
2373
+
2374
+ // A problem occurred in account creation
2375
+ if(!$account or (is_object($account) and !isset($account->id)))
2376
+ {
2377
+ wp_redirect($this->main->URL('site'));
2378
+ exit;
2379
+ }
2380
+
2381
+ // Save User ID
2382
+ update_user_meta($current_user_id, 'mec_stripe_id_temp', $account->id);
2383
+ $temp_account_id = $account->id;
2384
+ }
2385
+ catch(Exception $e)
2386
+ {
2387
+ wp_die($e->getMessage(), 'Stripe Error');
2388
+ exit;
2389
+ }
2390
+ }
2391
+
2392
+ $account_link = \Stripe\AccountLink::create([
2393
+ 'account' => $temp_account_id,
2394
+ 'refresh_url' => $this->main->URL('site').'?mec-stripe-connect-express-refresh=1',
2395
+ 'return_url' => $this->main->URL('site').'?mec-stripe-connect-express-return=1',
2396
+ 'type' => 'account_onboarding',
2397
+ ]);
2398
+
2399
+ // A problem occurred in account creation
2400
+ if(!$account_link or (is_object($account_link) and !isset($account_link->url)))
2401
+ {
2402
+ wp_redirect($this->main->URL('site'));
2403
+ exit;
2404
+ }
2405
+
2406
+ wp_redirect($account_link->url);
2407
+ exit;
2408
+ }
2409
+
2410
+ /**
2411
+ * It redirects the user to stripe dashboard
2412
+ */
2413
+ public function express_dashboard()
2414
+ {
2415
+ $current_user_id = get_current_user_id();
2416
+ if(!$current_user_id) return;
2417
+
2418
+ // Is it a request to redirect?
2419
+ $called = (isset($_GET['mec-stripe-connect-express-dashboard']) and $_GET['mec-stripe-connect-express-dashboard'] == 1) ? true : false;
2420
+ if(!$called) return;
2421
+
2422
+ // Is Nonce Valid?
2423
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_stripe_connect_express_dashboard')) return;
2424
+
2425
+ try
2426
+ {
2427
+ // Set Stripe Secret Key
2428
+ \Stripe\Stripe::setApiKey($this->options['secret_key']);
2429
+
2430
+ $account_id = get_user_meta($current_user_id, 'mec_stripe_id', true);
2431
+ $dashboard = \Stripe\Account::createLoginLink($account_id);
2432
+
2433
+ wp_redirect($dashboard->url);
2434
+ exit;
2435
+ }
2436
+ catch(Exception $e)
2437
+ {
2438
+ delete_user_meta($current_user_id, 'mec_stripe_id');
2439
+ }
2440
+ }
2441
+
2442
+ public function do_transaction($transaction_id = null)
2443
+ {
2444
+ if(!trim($transaction_id)) $transaction_id = isset($_GET['transaction_id']) ? sanitize_text_field($_GET['transaction_id']) : 0;
2445
+
2446
+ // Verify that the nonce is valid.
2447
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_transaction_form_' . $transaction_id))
2448
+ {
2449
+ $this->response(array(
2450
+ 'success' => 0,
2451
+ 'code' => 'NONCE_IS_INVALID',
2452
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
2453
+ ));
2454
+ }
2455
+
2456
+ // Validate Ticket Availability
2457
+ $this->validate($transaction_id);
2458
+
2459
+ $transaction = $this->book->get_transaction($transaction_id);
2460
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
2461
+
2462
+ // Invalid Transaction
2463
+ if(!is_array($transaction) or (is_array($transaction) and !isset($transaction['price']))) return false;
2464
+
2465
+ // Is there any attendee?
2466
+ if(!count($attendees))
2467
+ {
2468
+ $this->response(
2469
+ array(
2470
+ 'success' => 0,
2471
+ 'code' => 'NO_TICKET',
2472
+ 'message' => __(
2473
+ 'There is no attendee for booking!',
2474
+ 'mec'
2475
+ ),
2476
+ )
2477
+ );
2478
+ }
2479
+
2480
+ // Transaction is not done
2481
+ if(!isset($transaction['done']))
2482
+ {
2483
+ // Stripe Payment Details
2484
+ $payment_method_id = isset($_GET['payment_method_id']) ? sanitize_text_field($_GET['payment_method_id']) : '';
2485
+ $payment_intent_id = isset($_GET['payment_intent_id']) ? sanitize_text_field($_GET['payment_intent_id']) : '';
2486
+
2487
+ // Pay by Stripe Token
2488
+ $results = $this->pay($payment_method_id, $payment_intent_id, $transaction_id);
2489
+
2490
+ // Payment is invalid
2491
+ if(!$results['success'])
2492
+ {
2493
+ $this->response(
2494
+ array(
2495
+ 'success' => 0,
2496
+ 'code' => 'INVALID_PAYMENT',
2497
+ 'message' => $results['message'],
2498
+ )
2499
+ );
2500
+ }
2501
+
2502
+ // Payment requires more actions
2503
+ if($results['success'] == 2)
2504
+ {
2505
+ $this->response(
2506
+ array(
2507
+ 'success' => 2,
2508
+ 'requires_action' => 1,
2509
+ 'code' => 'REQUIRES_ACTION',
2510
+ 'payment_intent_client_secret' => $results['payment_intent_client_secret'],
2511
+ )
2512
+ );
2513
+ }
2514
+
2515
+ // Get Options Compatible with Organizer Payment
2516
+ $options = $this->options($transaction_id);
2517
+
2518
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
2519
+ $attention_times = explode(':', $attention_date);
2520
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
2521
+
2522
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
2523
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
2524
+
2525
+ $ticket_ids = '';
2526
+ $attendees_info = array();
2527
+
2528
+ foreach($attendees as $i => $attendee)
2529
+ {
2530
+ if(!is_numeric($i)) continue;
2531
+
2532
+ $ticket_ids .= $attendee['id'] . ',';
2533
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
2534
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
2535
+ }
2536
+
2537
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
2538
+ $user_id = $this->register_user($main_attendee, $transaction);
2539
+
2540
+ // Remove Sensitive Data
2541
+ if(isset($transaction['username']) or isset($transaction['password']))
2542
+ {
2543
+ unset($transaction['username']);
2544
+ unset($transaction['password']);
2545
+
2546
+ $this->book->update_transaction($transaction_id, $transaction);
2547
+ }
2548
+
2549
+ // MEC User
2550
+ $u = $this->getUser();
2551
+
2552
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
2553
+ $book_id = $this->book->add(
2554
+ array(
2555
+ 'post_author' => $user_id,
2556
+ 'post_type' => $this->PT,
2557
+ 'post_title' => $book_subject,
2558
+ 'post_date' => $date,
2559
+ 'attendees_info' => $attendees_info,
2560
+ 'mec_attendees' => $attendees,
2561
+ 'mec_gateway' => 'MEC_gateway_stripe',
2562
+ 'mec_gateway_label' => $this->title()
2563
+ ),
2564
+ $transaction_id,
2565
+ $ticket_ids
2566
+ );
2567
+
2568
+ // Assign User
2569
+ $u->assign($book_id, $user_id);
2570
+
2571
+ // Gateway Referrer
2572
+ update_post_meta($book_id, 'mec_gateway_ref_type', 'intent');
2573
+ update_post_meta($book_id, 'mec_gateway_ref_id', (isset($results['id']) ? $results['id'] : ''));
2574
+
2575
+ // Fires after completely creating a new booking
2576
+ do_action('mec_booking_completed', $book_id);
2577
+
2578
+ // Create Stripe Customer
2579
+ if(isset($results['id']))
2580
+ {
2581
+ $user_email = $u->get($user_id)->user_email;
2582
+
2583
+ $stripe = new \Stripe\StripeClient($options['secret_key']);
2584
+
2585
+ // Search Customers
2586
+ $customers = $stripe->customers->all([
2587
+ 'email' => $user_email,
2588
+ 'limit' => 1,
2589
+ ]);
2590
+
2591
+ if($customers->count()) $customer = $customers->first();
2592
+ else
2593
+ {
2594
+ $customer = $stripe->customers->create([
2595
+ 'name' => $name,
2596
+ 'email' => $user_email,
2597
+ ]);
2598
+ }
2599
+
2600
+ if($customer and isset($customer->id)) $stripe->paymentIntents->update($results['id'], ['customer' => $customer->id, 'receipt_email' => $user_email]);
2601
+ }
2602
+ }
2603
+ else $book_id = (isset($transaction['booking_id']) ? $transaction['booking_id'] : 0);
2604
+
2605
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
2606
+ $redirect_to = '';
2607
+
2608
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
2609
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
2610
+
2611
+ // Invoice Link
2612
+ $mec_confirmed = get_post_meta($book_id, 'mec_confirmed', true);
2613
+ $invoice_link = (!$mec_confirmed) ? '' : $this->book->get_invoice_link($transaction_id);
2614
+ $dl_file_link = (!$mec_confirmed) ? '' : $this->book->get_dl_file_link($book_id);
2615
+
2616
+ $extra_info = apply_filters('MEC_extra_info_gateways', '', $this->book->get_event_id_by_transaction_id($transaction_id), $book_id);
2617
+
2618
+ $this->response(
2619
+ array(
2620
+ 'success' => 1,
2621
+ 'message' => stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite'))),
2622
+ 'data' => array(
2623
+ 'book_id' => $book_id,
2624
+ 'redirect_to' => $redirect_to,
2625
+ 'invoice_link' => $invoice_link,
2626
+ 'dl_file_link' => $dl_file_link,
2627
+ 'extra_info' => $extra_info,
2628
+ ),
2629
+ )
2630
+ );
2631
+ }
2632
+
2633
+ public function pay($payment_method_id, $payment_intent_id, $transaction_id)
2634
+ {
2635
+ $transaction = $this->book->get_transaction($transaction_id);
2636
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : NULL;
2637
+ $event = get_post($event_id);
2638
+
2639
+ $author_id = $event->post_author;
2640
+ $stripe_user_id = get_user_meta($author_id, 'mec_stripe_id', true);
2641
+
2642
+ if($stripe_user_id) $charge_options = array('stripe_account' => $stripe_user_id);
2643
+ else $charge_options = NULL;
2644
+
2645
+ // Set Stripe Secret Key
2646
+ \Stripe\Stripe::setApiKey($this->options['secret_key']);
2647
+
2648
+ // Get Status of Payment Intent
2649
+ if($payment_intent_id)
2650
+ {
2651
+ $intent = \Stripe\PaymentIntent::retrieve($payment_intent_id, $charge_options);
2652
+ $intent->confirm();
2653
+
2654
+ if($intent->status == 'succeeded') return array('success' => 1, 'id' => $intent->id);
2655
+ else if($intent->status == 'requires_confirmation') return array('success' => 0, 'message' => __('Your payment needs to be confirmed!', 'modern-events-calendar-lite'));
2656
+ else return array('success' => 0, 'message' => __('Unknown Error!', 'modern-events-calendar-lite'));
2657
+ }
2658
+
2659
+ try
2660
+ {
2661
+ if($stripe_user_id)
2662
+ {
2663
+ $application_fee_amount = $this->get_fee_amount($transaction);
2664
+ $currency_code = $this->main->get_currency_code($event_id);
2665
+
2666
+ $charge = array(
2667
+ 'payment_method' => $payment_method_id,
2668
+ 'amount' => (isset($transaction['price']) ? ((int) $this->stripe_multiply($transaction['price'], $currency_code)) : 0),
2669
+ 'currency' => $currency_code,
2670
+ 'description' => $this->get_stripe_charge_description($transaction_id),
2671
+ 'application_fee_amount' => (int) $this->stripe_multiply($application_fee_amount, $currency_code),
2672
+ 'confirmation_method' => 'manual',
2673
+ 'confirm' => true,
2674
+ );
2675
+ }
2676
+ else
2677
+ {
2678
+ $currency_code = $this->main->get_currency_code($event_id);
2679
+ $charge = array(
2680
+ 'payment_method' => $payment_method_id,
2681
+ 'amount' => (isset($transaction['price']) ? ((int) $this->stripe_multiply($transaction['price'], $currency_code)) : 0),
2682
+ 'currency' => $currency_code,
2683
+ 'description' => $this->get_stripe_charge_description($transaction_id),
2684
+ 'confirmation_method' => 'manual',
2685
+ 'confirm' => true,
2686
+ );
2687
+ }
2688
+
2689
+ $intent = \Stripe\PaymentIntent::create($charge, $charge_options);
2690
+ }
2691
+ catch(Exception $e)
2692
+ {
2693
+ return array(
2694
+ 'success' => 0,
2695
+ 'message' => $e->getMessage(),
2696
+ );
2697
+ }
2698
+
2699
+ if($intent->status == 'requires_action' and $intent->next_action->type == 'use_stripe_sdk')
2700
+ {
2701
+ return array(
2702
+ 'success' => 2,
2703
+ 'requires_action' => true,
2704
+ 'payment_intent_client_secret' => $intent->client_secret
2705
+ );
2706
+ }
2707
+ elseif($intent->status == 'succeeded') return array('success' => 1, 'id' => $intent->id);
2708
+ else return array('success' => 0, 'message' => __('Unknown Error!', 'modern-events-calendar-lite'));
2709
+ }
2710
+
2711
+ public function get_fee_amount($transaction)
2712
+ {
2713
+ $fee = isset($this->options['fee']) ? $this->options['fee'] : 0;
2714
+ $fee_type = isset($this->options['fee_type']) ? $this->options['fee_type'] : 'amount';
2715
+ $fee_per = isset($this->options['fee_per']) ? $this->options['fee_per'] : 'ticket';
2716
+
2717
+ if($fee_type == 'amount')
2718
+ {
2719
+ if($fee_per == 'ticket')
2720
+ {
2721
+ $amount = $fee * count($transaction['tickets']);
2722
+ }
2723
+ // Booking
2724
+ else
2725
+ {
2726
+ $amount = $fee;
2727
+ }
2728
+ }
2729
+ // Percent
2730
+ else
2731
+ {
2732
+ if($fee_per == 'ticket')
2733
+ {
2734
+ $tickets_price = 0;
2735
+ foreach($transaction['price_details']['details'] as $p)
2736
+ {
2737
+ if(isset($p['type']) and $p['type'] == 'tickets')
2738
+ {
2739
+ $tickets_price = $p['amount'];
2740
+ break;
2741
+ }
2742
+ }
2743
+
2744
+ $amount = ($fee * $tickets_price) / 100;
2745
+ }
2746
+ // Booking
2747
+ else
2748
+ {
2749
+ $amount = ($fee * $transaction['price']) / 100;
2750
+ }
2751
+ }
2752
+
2753
+ return $amount;
2754
+ }
2755
+
2756
+ public function do_ideal_transaction()
2757
+ {
2758
+ $transaction_id = isset($_GET['mec_ideal_transaction_id']) ? sanitize_text_field($_GET['mec_ideal_transaction_id']) : NULL;
2759
+ if(!trim($transaction_id)) return false;
2760
+
2761
+ $source = isset($_GET['source']) ? sanitize_text_field($_GET['source']) : NULL;
2762
+ if(!trim($source)) return false;
2763
+
2764
+ $transaction = $this->book->get_transaction($transaction_id);
2765
+
2766
+ // Invalid Transaction
2767
+ if(!is_array($transaction) or (is_array($transaction) and !isset($transaction['price']))) return false;
2768
+
2769
+ // Transaction is done
2770
+ if(isset($transaction['done']) and $transaction['done'] == '1') return false;
2771
+
2772
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : NULL;
2773
+ $event = get_post($event_id);
2774
+
2775
+ $author_id = $event->post_author;
2776
+ $stripe_user_id = get_user_meta($author_id, 'mec_stripe_id', true);
2777
+
2778
+ if($stripe_user_id) $charge_options = array('stripe_account' => $stripe_user_id);
2779
+ else $charge_options = NULL;
2780
+
2781
+ try
2782
+ {
2783
+ // Set Stripe Secret Key
2784
+ \Stripe\Stripe::setApiKey($this->options['secret_key']);
2785
+
2786
+ // Currency
2787
+ $currency_code = $this->main->get_currency_code($event_id);
2788
+
2789
+ if($stripe_user_id)
2790
+ {
2791
+ $application_fee_amount = $this->get_fee_amount($transaction);
2792
+
2793
+ $ch = array(
2794
+ 'amount' => (isset($transaction['price']) ? ((int) $this->stripe_multiply($transaction['price'], $currency_code)) : 0),
2795
+ 'currency' => $currency_code,
2796
+ 'source' => $source,
2797
+ 'description' => $this->get_stripe_charge_description($transaction_id),
2798
+ 'application_fee_amount' => (int) $this->stripe_multiply($application_fee_amount, $currency_code),
2799
+ );
2800
+ }
2801
+ else
2802
+ {
2803
+ $ch = array(
2804
+ 'amount' => (isset($transaction['price']) ? ((int) $this->stripe_multiply($transaction['price'], $currency_code)) : 0),
2805
+ 'currency' => $currency_code,
2806
+ 'source' => $source,
2807
+ 'description' => $this->get_stripe_charge_description($transaction_id),
2808
+ );
2809
+ }
2810
+
2811
+ $charge = \Stripe\Charge::create($ch, $charge_options);
2812
+ }
2813
+ catch(Exception $e)
2814
+ {
2815
+ return false;
2816
+ }
2817
+
2818
+ // Payment Invalid
2819
+ if(!$charge->captured or !$charge->paid) return false;
2820
+
2821
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
2822
+
2823
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
2824
+ $attention_times = explode(':', $attention_date);
2825
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
2826
+
2827
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
2828
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
2829
+
2830
+ $ticket_ids = '';
2831
+ $attendees_info = array();
2832
+
2833
+ foreach($attendees as $i => $attendee)
2834
+ {
2835
+ if(!is_numeric($i)) continue;
2836
+
2837
+ $ticket_ids .= $attendee['id'] . ',';
2838
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
2839
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
2840
+ }
2841
+
2842
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
2843
+ $user_id = $this->register_user($main_attendee, $transaction);
2844
+
2845
+ // Remove Sensitive Data
2846
+ if(isset($transaction['username']) or isset($transaction['password']))
2847
+ {
2848
+ unset($transaction['username']);
2849
+ unset($transaction['password']);
2850
+ }
2851
+
2852
+ $transaction['done'] = 1;
2853
+ $this->book->update_transaction($transaction_id, $transaction);
2854
+
2855
+ // MEC User
2856
+ $u = $this->getUser();
2857
+
2858
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
2859
+ $book_id = $this->book->add(
2860
+ array(
2861
+ 'post_author' => $user_id,
2862
+ 'post_type' => $this->PT,
2863
+ 'post_title' => $book_subject,
2864
+ 'post_date' => $date,
2865
+ 'attendees_info' => $attendees_info,
2866
+ 'mec_attendees' => $attendees,
2867
+ 'mec_gateway' => 'MEC_gateway_stripe',
2868
+ 'mec_gateway_label' => $this->title()
2869
+ ),
2870
+ $transaction_id,
2871
+ $ticket_ids
2872
+ );
2873
+
2874
+ // Assign User
2875
+ $u->assign($book_id, $user_id);
2876
+
2877
+ // Gateway Referrer
2878
+ update_post_meta($book_id, 'mec_gateway_ref_type', 'charge');
2879
+ update_post_meta($book_id, 'mec_gateway_ref_id', (isset($charge->id) ? $charge->id : ''));
2880
+
2881
+ // Fires after completely creating a new booking
2882
+ do_action('mec_booking_completed', $book_id);
2883
+
2884
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
2885
+ $redirect_to = '';
2886
+
2887
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
2888
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
2889
+
2890
+ // Create Stripe Customer
2891
+ if($charge and $charge->id)
2892
+ {
2893
+ $user_email = $u->get($user_id)->user_email;
2894
+
2895
+ $stripe = new \Stripe\StripeClient($this->options['secret_key']);
2896
+
2897
+ // Search Customers
2898
+ $customers = $stripe->customers->all([
2899
+ 'email' => $user_email,
2900
+ 'limit' => 1,
2901
+ ]);
2902
+
2903
+ if($customers->count()) $customer = $customers->first();
2904
+ else
2905
+ {
2906
+ $customer = $stripe->customers->create([
2907
+ 'name' => $name,
2908
+ 'email' => $user_email,
2909
+ ]);
2910
+ }
2911
+
2912
+ if($customer and isset($customer->id)) $stripe->charges->update($charge->id, ['customer' => $customer->id]);
2913
+ }
2914
+
2915
+ // Redirect
2916
+ if(trim($redirect_to))
2917
+ {
2918
+ wp_redirect($redirect_to);
2919
+ exit;
2920
+ }
2921
+ }
2922
+
2923
+ public function checkout_form($transaction_id, $params = array())
2924
+ {
2925
+ // Payment Method
2926
+ $payment_method = (isset($this->options['payment_method']) and trim($this->options['payment_method'])) ? $this->options['payment_method'] : 'cc';
2927
+
2928
+ if($payment_method == 'cc') $this->checkout_form_cc($transaction_id, $params);
2929
+ elseif($payment_method == 'ideal') $this->checkout_form_ideal($transaction_id, $params);
2930
+ }
2931
+
2932
+ public function checkout_form_cc($transaction_id, $params = array())
2933
+ {
2934
+ $transaction = $this->book->get_transaction($transaction_id);
2935
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : NULL;
2936
+
2937
+ $main_attendee_name = ((isset($transaction['tickets']) and isset($transaction['tickets'][0]) and isset($transaction['tickets'][0]['name'])) ? $transaction['tickets'][0]['name'] : '');
2938
+ $main_attendee_email = ((isset($transaction['tickets']) and isset($transaction['tickets'][0]) and isset($transaction['tickets'][0]['email'])) ? $transaction['tickets'][0]['email'] : '');
2939
+
2940
+ $event = get_post($event_id);
2941
+
2942
+ $author_id = $event->post_author;
2943
+ $stripe_user_id = get_user_meta($author_id, 'mec_stripe_id', true);
2944
+ ?>
2945
+ <script type="text/javascript">
2946
+ var stripe;
2947
+
2948
+ <?php if($stripe_user_id): ?>
2949
+ stripe = Stripe("<?php echo(isset($this->options['publishable_key']) ? $this->options['publishable_key'] : ''); ?>", {
2950
+ stripeAccount: "<?php echo $stripe_user_id; ?>"
2951
+ });
2952
+ <?php else: ?>
2953
+ stripe = Stripe("<?php echo(isset($this->options['publishable_key']) ? $this->options['publishable_key'] : ''); ?>");
2954
+ <?php endif; ?>
2955
+
2956
+ var elements = stripe.elements();
2957
+ var style = {
2958
+ base: {
2959
+ color: '#32325d',
2960
+ fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
2961
+ fontSmoothing: 'antialiased',
2962
+ fontSize: '16px',
2963
+ minHeight: '40px',
2964
+ '::placeholder': {
2965
+ color: '#aab7c4'
2966
+ },
2967
+ },
2968
+ invalid: {
2969
+ color: '#fa755a',
2970
+ iconColor: '#fa755a'
2971
+ }
2972
+ };
2973
+
2974
+ var card = elements.create('card');
2975
+ card.mount('#mec_card_element_stripe_connect_<?php echo $transaction_id; ?>');
2976
+
2977
+ // Validation
2978
+ card.addEventListener('change', function(event)
2979
+ {
2980
+ // Show the Error
2981
+ if(event.error) jQuery('#mec_do_transaction_stripe_connect_message<?php echo $transaction_id; ?>').text(event.error.message).addClass('mec-error').show();
2982
+ // Hide the Message
2983
+ else jQuery("#mec_do_transaction_stripe_connect_message<?php echo $transaction_id; ?>").removeClass("mec-success mec-error").hide();
2984
+ });
2985
+
2986
+ jQuery('#mec_do_transaction_stripe_connect_form<?php echo $transaction_id; ?>').on('submit', function(e)
2987
+ {
2988
+ // Prevent the form from submitting
2989
+ e.preventDefault();
2990
+
2991
+ var form = jQuery(this);
2992
+ var transaction_id = '<?php echo $transaction_id; ?>';
2993
+
2994
+ // No pressing the buy now button more than once
2995
+ form.find('button').prop('disabled', true);
2996
+
2997
+ // Add loading Class to the button
2998
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").addClass("loading");
2999
+
3000
+ // Hide the Message
3001
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).removeClass("mec-success mec-error").hide();
3002
+
3003
+ var payer_name = jQuery("#mec_name_stripe_connect_" + transaction_id).val();
3004
+ var payer_email = jQuery("#mec_email_stripe_connect_" + transaction_id).val();
3005
+ var payer_details = {
3006
+ billing_details: {}
3007
+ };
3008
+
3009
+ if(payer_name !== '') payer_details.billing_details.name = payer_name;
3010
+ if(payer_email !== '') payer_details.billing_details.email = payer_email;
3011
+
3012
+ stripe.createPaymentMethod('card', card, payer_details).then(function(result)
3013
+ {
3014
+ if(result.error)
3015
+ {
3016
+ // Remove the loading Class from the button
3017
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").removeClass("loading");
3018
+
3019
+ // Show the user what they did wrong
3020
+ jQuery('#mec_do_transaction_stripe_connect_message' + transaction_id).text(result.error.message).addClass('mec-error').show();
3021
+
3022
+ // Make the submit clickable again
3023
+ form.find('button').prop('disabled', false);
3024
+ }
3025
+ else
3026
+ {
3027
+ // Make the submit clickable again
3028
+ form.find('button').prop('disabled', false);
3029
+
3030
+ // Hide the Message
3031
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).removeClass("mec-success mec-error").hide();
3032
+
3033
+ // Set Payment Method ID
3034
+ jQuery("#mec_do_transaction_stripe_connect_payment_method_id" + transaction_id).val(result.paymentMethod.id);
3035
+
3036
+ var data = form.serialize();
3037
+ jQuery.ajax(
3038
+ {
3039
+ type: "GET",
3040
+ url: "<?php echo admin_url('admin-ajax.php', NULL); ?>",
3041
+ data: data,
3042
+ dataType: "JSON",
3043
+ success: function(data)
3044
+ {
3045
+ if(data.success === 1)
3046
+ {
3047
+ // Remove the loading Class from the button
3048
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").removeClass("loading");
3049
+
3050
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id).hide();
3051
+ jQuery(".mec-book-form-gateway-label").remove();
3052
+ jQuery(".mec-book-form-coupon").hide();
3053
+ jQuery(".mec-gateway-comment").hide();
3054
+
3055
+ jQuery("#mec-book-form-back-btn-step-3").remove();
3056
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).addClass("mec-success").html(data.message).show();
3057
+
3058
+ // Show Invoice Link
3059
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
3060
+ {
3061
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
3062
+ }
3063
+
3064
+ // Show Downloadable Link
3065
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
3066
+ {
3067
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
3068
+ }
3069
+
3070
+ // Show Extra info
3071
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
3072
+ {
3073
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).append('<div>' + data.data.extra_info+'</div>');
3074
+ }
3075
+
3076
+ // Redirect to thank you page
3077
+ if(typeof data.data.redirect_to !== "undefined" && data.data.redirect_to !== "")
3078
+ {
3079
+ setTimeout(function()
3080
+ {
3081
+ window.location.href = data.data.redirect_to;
3082
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
3083
+ }
3084
+ }
3085
+ else if(data.requires_action)
3086
+ {
3087
+ stripe.handleCardAction(data.payment_intent_client_secret).then(function(result)
3088
+ {
3089
+ if(result.error)
3090
+ {
3091
+ // Show the user what they did wrong
3092
+ jQuery('#mec_do_transaction_stripe_connect_message' + transaction_id).text(result.error.message).addClass('mec-error').show();
3093
+
3094
+ // Remove the loading Class from the button
3095
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").removeClass("loading");
3096
+
3097
+ // Make the submit clickable again
3098
+ form.find('button').prop('disabled', false);
3099
+ }
3100
+ else
3101
+ {
3102
+ // Set Payment Intent ID
3103
+ jQuery("#mec_do_transaction_stripe_connect_payment_intent_id" + transaction_id).val(result.paymentIntent.id);
3104
+
3105
+ var data = form.serialize();
3106
+ jQuery.ajax(
3107
+ {
3108
+ type: "GET",
3109
+ url: "<?php echo admin_url('admin-ajax.php', NULL); ?>",
3110
+ data: data,
3111
+ dataType: "JSON",
3112
+ success: function(data)
3113
+ {
3114
+ if(data.success === 1)
3115
+ {
3116
+ // Remove the loading Class from the button
3117
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").removeClass("loading");
3118
+
3119
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id).hide();
3120
+ jQuery(".mec-book-form-gateway-label").remove();
3121
+ jQuery(".mec-book-form-coupon").hide();
3122
+ jQuery(".mec-gateway-comment").hide();
3123
+
3124
+ jQuery("#mec-book-form-back-btn-step-3").remove();
3125
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).addClass("mec-success").html(data.message).show();
3126
+
3127
+ // Show Invoice Link
3128
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
3129
+ {
3130
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
3131
+ }
3132
+
3133
+ // Show Downloadable Link
3134
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
3135
+ {
3136
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
3137
+ }
3138
+
3139
+ // Show Extra info
3140
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
3141
+ {
3142
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).append('<div>' + data.data.extra_info+'</div>');
3143
+ }
3144
+
3145
+ // Redirect to thank you page
3146
+ if(typeof data.data.redirect_to !== "undefined" && data.data.redirect_to !== "")
3147
+ {
3148
+ setTimeout(function()
3149
+ {
3150
+ window.location.href = data.data.redirect_to;
3151
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
3152
+ }
3153
+ }
3154
+ else
3155
+ {
3156
+ // Remove the loading Class from the button
3157
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").removeClass("loading");
3158
+
3159
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).addClass("mec-error").html(data.message).show();
3160
+ }
3161
+ },
3162
+ error: function(jqXHR, textStatus, errorThrown)
3163
+ {
3164
+ // Remove the loading Class from the button
3165
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").removeClass("loading");
3166
+ }
3167
+ });
3168
+ }
3169
+ });
3170
+ }
3171
+ else
3172
+ {
3173
+ // Remove the loading Class from the button
3174
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").removeClass("loading");
3175
+
3176
+ jQuery("#mec_do_transaction_stripe_connect_message" + transaction_id).addClass("mec-error").html(data.message).show();
3177
+ }
3178
+ },
3179
+ error: function(jqXHR, textStatus, errorThrown)
3180
+ {
3181
+ // Remove the loading Class from the button
3182
+ jQuery("#mec_do_transaction_stripe_connect_form" + transaction_id + " button[type=submit]").removeClass("loading");
3183
+ }
3184
+ });
3185
+ }
3186
+ });
3187
+ });
3188
+ </script>
3189
+ <div class="mec-gateway-message mec-util-hidden" id="mec_do_transaction_stripe_connect_message<?php echo $transaction_id; ?>" role="alert"></div>
3190
+ <form id="mec_do_transaction_stripe_connect_form<?php echo $transaction_id; ?>">
3191
+ <div class="mec-form-row">
3192
+ <label for="mec_name_stripe_connect_<?php echo $transaction_id; ?>">
3193
+ <?php _e('Name', 'modern-events-calendar-lite'); ?>
3194
+ </label>
3195
+ <input id="mec_name_stripe_connect_<?php echo $transaction_id; ?>" type="text" value="<?php echo esc_attr($main_attendee_name); ?>">
3196
+ </div>
3197
+ <div class="mec-form-row">
3198
+ <label for="mec_email_stripe_connect_<?php echo $transaction_id; ?>">
3199
+ <?php _e('Email', 'modern-events-calendar-lite'); ?>
3200
+ </label>
3201
+ <input id="mec_email_stripe_connect_<?php echo $transaction_id; ?>" type="email" value="<?php echo esc_attr($main_attendee_email); ?>">
3202
+ </div>
3203
+ <div class="mec-form-row">
3204
+ <label for="mec_card_element_stripe_connect_<?php echo $transaction_id; ?>">
3205
+ <?php _e('Credit or debit card', 'modern-events-calendar-lite'); ?>
3206
+ </label>
3207
+ <div id="mec_card_element_stripe_connect_<?php echo $transaction_id; ?>">
3208
+ </div>
3209
+ </div>
3210
+ <div class="mec-form-row mec-click-pay">
3211
+ <input type="hidden" name="action" value="mec_do_transaction_stripe_connect"/>
3212
+ <input type="hidden" name="transaction_id" value="<?php echo $transaction_id; ?>"/>
3213
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
3214
+ <input type="hidden" name="payment_method_id" value="" id="mec_do_transaction_stripe_connect_payment_method_id<?php echo $transaction_id; ?>"/>
3215
+ <input type="hidden" name="payment_intent_id" value="" id="mec_do_transaction_stripe_connect_payment_intent_id<?php echo $transaction_id; ?>"/>
3216
+ <?php wp_nonce_field('mec_transaction_form_' . $transaction_id); ?>
3217
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
3218
+ </div>
3219
+ </form>
3220
+ <?php
3221
+ }
3222
+
3223
+ public function checkout_form_ideal($transaction_id, $params = array())
3224
+ {
3225
+ $transaction = $this->book->get_transaction($transaction_id);
3226
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
3227
+
3228
+ $main_attendee_name = ((isset($transaction['tickets']) and isset($transaction['tickets'][0]) and isset($transaction['tickets'][0]['name'])) ? $transaction['tickets'][0]['name'] : '');
3229
+ $event = get_post($event_id);
3230
+
3231
+ $author_id = $event->post_author;
3232
+ $stripe_user_id = get_user_meta($author_id, 'mec_stripe_id', true);
3233
+ ?>
3234
+ <script type="text/javascript">
3235
+ var stripe;
3236
+
3237
+ <?php if($stripe_user_id): ?>
3238
+ stripe = Stripe("<?php echo(isset($this->options['publishable_key']) ? $this->options['publishable_key'] : ''); ?>", {
3239
+ stripeAccount: "<?php echo $stripe_user_id; ?>"
3240
+ });
3241
+ <?php else: ?>
3242
+ stripe = Stripe("<?php echo(isset($this->options['publishable_key']) ? $this->options['publishable_key'] : ''); ?>");
3243
+ <?php endif; ?>
3244
+
3245
+ var elements = stripe.elements();
3246
+
3247
+ var idealBank = elements.create('idealBank');
3248
+ idealBank.mount('#mec_card_element_stripe_<?php echo $transaction_id; ?>');
3249
+
3250
+ jQuery('#mec_do_transaction_stripe_form<?php echo $transaction_id; ?>').on('submit', function(e)
3251
+ {
3252
+ // Prevent the form from submitting
3253
+ e.preventDefault();
3254
+
3255
+ var form = jQuery(this);
3256
+ var transaction_id = '<?php echo $transaction_id; ?>';
3257
+
3258
+ // No pressing the buy now button more than once
3259
+ form.find('button').prop('disabled', true);
3260
+
3261
+ // Hide the Message
3262
+ jQuery("#mec_do_transaction_stripe_message" + transaction_id).removeClass("mec-success mec-error").hide();
3263
+
3264
+ // Add loading Class to the button
3265
+ jQuery("#mec_do_transaction_stripe_form" + transaction_id + " button[type=submit]").addClass("loading");
3266
+
3267
+ var payer_name = jQuery("#mec_name_stripe_" + transaction_id).val();
3268
+ var source = {
3269
+ type: 'ideal',
3270
+ amount: <?php echo (isset($transaction['price']) ? ((int) $this->stripe_multiply($transaction['price'], $this->main->get_currency_code($event_id))) : 0); ?>,
3271
+ currency: '<?php echo $this->main->get_currency_code($event_id); ?>',
3272
+ owner:
3273
+ {
3274
+ name: payer_name,
3275
+ },
3276
+ redirect:
3277
+ {
3278
+ return_url: '<?php echo $this->main->add_qs_var('mec_ideal_transaction_id', $transaction_id, $this->get_return_url($event_id, false)); ?>',
3279
+ }
3280
+ };
3281
+
3282
+ stripe.createSource(idealBank, source).then(function(result)
3283
+ {
3284
+ if(result.error) jQuery("#mec_do_transaction_stripe_message" + transaction_id).addClass("mec-error").html(result.error.message).show();
3285
+ else document.location.href = result.source.redirect.url;
3286
+ });
3287
+ });
3288
+ </script>
3289
+ <div class="mec-gateway-message mec-util-hidden"
3290
+ id="mec_do_transaction_stripe_message<?php echo $transaction_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
3291
+ <form id="mec_do_transaction_stripe_form<?php echo $transaction_id; ?>">
3292
+ <div class="info-msg"><?php esc_html_e("You should complete the payment by returning back to the website.", 'modern-events-calendar-lite'); ?></div>
3293
+ <div class="mec-form-row mec-name-stripe">
3294
+ <label for="mec_name_stripe_<?php echo $transaction_id; ?>">
3295
+ <?php _e('Name', 'modern-events-calendar-lite'); ?>
3296
+ </label>
3297
+ <input id="mec_name_stripe_<?php echo $transaction_id; ?>" type="text" value="<?php echo esc_attr($main_attendee_name); ?>">
3298
+ </div>
3299
+ <div class="mec-form-row mec-ideal-element-stripe">
3300
+ <label for="mec_card_element_stripe_<?php echo $transaction_id; ?>">
3301
+ <?php _e('iDEAL Bank', 'modern-events-calendar-lite'); ?>
3302
+ </label>
3303
+ <div id="mec_card_element_stripe_<?php echo $transaction_id; ?>">
3304
+ </div>
3305
+ </div>
3306
+ <div class="mec-form-row mec-click-pay">
3307
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
3308
+ </div>
3309
+ </form>
3310
+ <?php
3311
+ }
3312
+
3313
+ public function options_form()
3314
+ {
3315
+ $pages = get_pages();
3316
+ $connection_method = (isset($this->options['connection_method']) and trim($this->options['connection_method'])) ? $this->options['connection_method'] : 'standard';
3317
+ ?>
3318
+ <div class="mec-form-row">
3319
+ <label>
3320
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][status]" value="0"/>
3321
+ <input onchange="jQuery('#mec_gateways<?php echo $this->id(); ?>_container_toggle').toggle(); if(jQuery(this).is(':checked')) jQuery('#mec_gateways_op_status').prop('checked', 'checked');" value="1"
3322
+ type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][status]"
3323
+ <?php
3324
+ if (isset($this->options['status']) and $this->options['status']) {
3325
+ echo 'checked="checked"';
3326
+ }
3327
+ ?>
3328
+ /> <?php _e('Stripe Connect', 'modern-events-calendar-lite'); ?>
3329
+ </label>
3330
+ </div>
3331
+ <div id="mec_gateways<?php echo $this->id(); ?>_container_toggle" class="mec-gateway-options-form
3332
+ <?php
3333
+ if ((isset($this->options['status']) and !$this->options['status']) or !isset($this->options['status'])) {
3334
+ echo 'mec-util-hidden';
3335
+ }
3336
+ ?>">
3337
+ <p><?php _e("Using this gateway, booking fee goes to the organizer account directly but you can get your fee in your Stripe account.", 'modern-events-calendar-lite'); ?></p>
3338
+ <p><?php _e("If organizer connects their account, then it will be the only enabled gateway for organizer events even if other gateways are enabled. Organizer Payment Module must be enabled to use this!", 'modern-events-calendar-lite'); ?></p>
3339
+ <p class="mec-only-strip-connect-standard <?php echo ($connection_method == 'express' ? 'w-hide' : ''); ?>"><?php echo sprintf(__("You should set %s as Redirect URL in your Stripe dashboard.", 'modern-events-calendar-lite'), '<code>'.rtrim(get_home_url(), '/').'/?mec-stripe-connect=1</code>'); ?></p>
3340
+ <br>
3341
+ <div class="mec-form-row">
3342
+ <label class="mec-col-3"
3343
+ for="mec_gateways<?php echo $this->id(); ?>_title"><?php _e('Title', 'modern-events-calendar-lite'); ?></label>
3344
+ <div class="mec-col-9">
3345
+ <input type="text" id="mec_gateways<?php echo $this->id(); ?>_title" name="mec[gateways][<?php echo $this->id(); ?>][title]" value="<?php echo (isset($this->options['title']) and trim($this->options['title'])) ? $this->options['title'] : ''; ?>" placeholder="<?php echo $this->label(); ?>"/>
3346
+ </div>
3347
+ </div>
3348
+ <div class="mec-form-row">
3349
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_comment"><?php _e('Comment', 'modern-events-calendar-lite'); ?></label>
3350
+ <div class="mec-col-9">
3351
+ <textarea id="mec_gateways<?php echo $this->id(); ?>_comment" name="mec[gateways][<?php echo $this->id(); ?>][comment]"><?php echo (isset($this->options['comment']) and trim($this->options['comment'])) ? stripslashes($this->options['comment']) : esc_html__('Stripe Gateway Description', 'modern-events-calendar-lite'); ?></textarea>
3352
+ <span class="mec-tooltip">
3353
+ <div class="box left">
3354
+ <h5 class="title"><?php _e('Comment', 'modern-events-calendar-lite'); ?></h5>
3355
+ <div class="content"><p><?php esc_attr_e('HTML allowed.', 'modern-events-calendar-lite'); ?><a href="https://webnus.net/dox/modern-events-calendar/booking/" target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
3356
+ </div>
3357
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
3358
+ </span>
3359
+ </div>
3360
+ </div>
3361
+ <div class="mec-form-row">
3362
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_organizer_comment"><?php _e('Comment for Organizer', 'modern-events-calendar-lite'); ?></label>
3363
+ <div class="mec-col-9">
3364
+ <textarea id="mec_gateways<?php echo $this->id(); ?>organizer_comment" name="mec[gateways][<?php echo $this->id(); ?>][organizer_comment]"><?php echo (isset($this->options['organizer_comment']) and trim($this->options['organizer_comment'])) ? stripslashes($this->options['organizer_comment']) : ''; ?></textarea>
3365
+ <span class="mec-tooltip">
3366
+ <div class="box left">
3367
+ <h5 class="title"><?php _e('Comment', 'modern-events-calendar-lite'); ?></h5>
3368
+ <div class="content"><p><?php esc_attr_e('HTML allowed.', 'modern-events-calendar-lite'); ?><a href="https://webnus.net/dox/modern-events-calendar/booking/" target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
3369
+ </div>
3370
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
3371
+ </span>
3372
+ </div>
3373
+ </div>
3374
+ <div class="mec-form-row">
3375
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_connection_method"><?php _e('Connection Method', 'modern-events-calendar-lite'); ?></label>
3376
+ <div class="mec-col-9">
3377
+ <select name="mec[gateways][<?php echo $this->id(); ?>][connection_method]" id="mec_gateways<?php echo $this->id(); ?>_connection_method" onchange="if(this.value === 'express') jQuery('.mec-only-strip-connect-standard').addClass('w-hide'); else jQuery('.mec-only-strip-connect-standard').removeClass('w-hide');">
3378
+ <option value="standard" <?php echo (isset($this->options['connection_method']) and $this->options['connection_method'] == 'standard') ? 'selected="selected"' : ''; ?>><?php esc_html_e('Standard', 'modern-events-calendar-lite'); ?></option>
3379
+ <option value="express" <?php echo (isset($this->options['connection_method']) and $this->options['connection_method'] == 'express') ? 'selected="selected"' : ''; ?>><?php esc_html_e('Express', 'modern-events-calendar-lite'); ?></option>
3380
+ </select>
3381
+ </div>
3382
+ </div>
3383
+ <div class="mec-form-row">
3384
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_payment_method"><?php _e('Payment Method', 'modern-events-calendar-lite'); ?></label>
3385
+ <div class="mec-col-9">
3386
+ <select name="mec[gateways][<?php echo $this->id(); ?>][payment_method]" id="mec_gateways<?php echo $this->id(); ?>_payment_method">
3387
+ <option value="cc" <?php echo (isset($this->options['payment_method']) and $this->options['payment_method'] == 'cc') ? 'selected="selected"' : ''; ?>><?php esc_html_e('Credit Card', 'modern-events-calendar-lite'); ?></option>
3388
+ <option value="ideal" <?php echo (isset($this->options['payment_method']) and $this->options['payment_method'] == 'ideal') ? 'selected="selected"' : ''; ?>><?php esc_html_e('iDEAL', 'modern-events-calendar-lite'); ?></option>
3389
+ </select>
3390
+ </div>
3391
+ </div>
3392
+ <div class="mec-form-row mec-only-strip-connect-standard <?php echo ($connection_method == 'express' ? 'w-hide' : ''); ?>">
3393
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_client_id"><?php _e('Client ID', 'modern-events-calendar-lite'); ?></label>
3394
+ <div class="mec-col-9">
3395
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_client_id" name="mec[gateways][<?php echo $this->id(); ?>][client_id]" value="<?php echo isset($this->options['client_id']) ? $this->options['client_id'] : ''; ?>">
3396
+ </div>
3397
+ </div>
3398
+ <div class="mec-form-row">
3399
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_secret_key"><?php _e('Secret Key', 'modern-events-calendar-lite'); ?></label>
3400
+ <div class="mec-col-9">
3401
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_secret_key" name="mec[gateways][<?php echo $this->id(); ?>][secret_key]" value="<?php echo isset($this->options['secret_key']) ? $this->options['secret_key'] : ''; ?>"/>
3402
+ </div>
3403
+ </div>
3404
+ <div class="mec-form-row">
3405
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_publishable_key"><?php _e('Publishable Key', 'modern-events-calendar-lite'); ?></label>
3406
+ <div class="mec-col-9">
3407
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_publishable_key" name="mec[gateways][<?php echo $this->id(); ?>][publishable_key]" value="<?php echo isset($this->options['publishable_key']) ? $this->options['publishable_key'] : ''; ?>"/>
3408
+ </div>
3409
+ </div>
3410
+ <div class="mec-form-row">
3411
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_fee"><?php _e('Your Fee', 'modern-events-calendar-lite'); ?></label>
3412
+ <div class="mec-col-9">
3413
+ <div class="mec-form-row">
3414
+ <div class="mec-col-4">
3415
+ <input type="number" id="mec_gateways<?php echo $this->id(); ?>_fee" name="mec[gateways][<?php echo $this->id(); ?>][fee]" value="<?php echo isset($this->options['fee']) ? $this->options['fee'] : 10; ?>">
3416
+ </div>
3417
+ <div class="mec-col-4">
3418
+ <select id="mec_gateways<?php echo $this->id(); ?>_fee_type" name="mec[gateways][<?php echo $this->id(); ?>][fee_type]" title="<?php esc_attr_e('Fee Type', 'modern-events-calendar-lite'); ?>">
3419
+ <option value="amount" <?php echo ((isset($this->options['fee_type']) and $this->options['fee_type'] == 'amount') ? 'selected="selected"' : ''); ?>><?php _e('Amount', 'modern-events-calendar-lite'); ?></option>
3420
+ <option value="percent" <?php echo ((isset($this->options['fee_type']) and $this->options['fee_type'] == 'percent') ? 'selected="selected"' : ''); ?>><?php _e('Percent', 'modern-events-calendar-lite'); ?></option>
3421
+ </select>
3422
+ </div>
3423
+ <div class="mec-col-4">
3424
+ <select id="mec_gateways<?php echo $this->id(); ?>_fee_per" name="mec[gateways][<?php echo $this->id(); ?>][fee_per]" title="<?php esc_attr_e('Per', 'modern-events-calendar-lite'); ?>">
3425
+ <option value="booking" <?php echo ((isset($this->options['fee_per']) and $this->options['fee_per'] == 'booking') ? 'selected="selected"' : ''); ?>><?php _e('Booking', 'modern-events-calendar-lite'); ?></option>
3426
+ <option value="ticket" <?php echo ((isset($this->options['fee_per']) and $this->options['fee_per'] == 'ticket') ? 'selected="selected"' : ''); ?>><?php _e('Ticket', 'modern-events-calendar-lite'); ?></option>
3427
+ </select>
3428
+ </div>
3429
+ </div>
3430
+ </div>
3431
+
3432
+ </div>
3433
+ <div class="mec-form-row">
3434
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_redirection_page"><?php _e('Redirection Page', 'modern-events-calendar-lite'); ?></label>
3435
+ <div class="mec-col-9">
3436
+ <select id="mec_gateways<?php echo $this->id(); ?>_redirection_page" name="mec[gateways][<?php echo $this->id(); ?>][redirection_page]">
3437
+ <option value="">-----</option>
3438
+ <?php foreach($pages as $page): if(!trim($page->post_title)) continue; ?>
3439
+ <option value="<?php echo $page->ID; ?>" <?php echo ((isset($this->options['redirection_page']) and $this->options['redirection_page'] == $page->ID) ? 'selected="selected"' : ''); ?>><?php echo $page->post_title; ?></option>
3440
+ <?php endforeach; ?>
3441
+ </select>
3442
+ <span class="mec-tooltip">
3443
+ <div class="box left">
3444
+ <h5 class="title"><?php _e('Redirection Page', 'modern-events-calendar-lite'); ?></h5>
3445
+ <div class="content"><p><?php esc_attr_e('Users will redirect to this page after connecting to your Stripe account. You can create a page to thank them. If you leave it empty then users will redirect to home page!', 'modern-events-calendar-lite'); ?></p></div>
3446
+ </div>
3447
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
3448
+ </span>
3449
+ </div>
3450
+ </div>
3451
+ <div class="mec-form-row">
3452
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_index"><?php _e('Position', 'modern-events-calendar-lite'); ?></label>
3453
+ <div class="mec-col-9">
3454
+ <input type="number" min="0" step="1" id="mec_gateways<?php echo $this->id(); ?>_index"
3455
+ name="mec[gateways][<?php echo $this->id(); ?>][index]"
3456
+ value="<?php echo (isset($this->options['index']) and trim($this->options['index'])) ? $this->options['index'] : 6; ?>"
3457
+ placeholder="<?php echo esc_attr__('Position', 'modern-events-calendar-lite'); ?>"/>
3458
+ </div>
3459
+ </div>
3460
+ </div>
3461
+ <?php
3462
+ }
3463
+
3464
+ public function op_enabled()
3465
+ {
3466
+ return true;
3467
+ }
3468
+
3469
+ public function op_form($options = array())
3470
+ {
3471
+ $client_id = isset($this->options['client_id']) ? trim($this->options['client_id']) : NULL;
3472
+ $secret_key = isset($this->options['secret_key']) ? trim($this->options['secret_key']) : NULL;
3473
+
3474
+ if(!$client_id or !$secret_key) return '';
3475
+
3476
+ global $post;
3477
+ $strip_account_id = get_user_meta($post->post_author, 'mec_stripe_id', true);
3478
+
3479
+ $connection_method = $this->get_connection_method();
3480
+ if($connection_method === 'express')
3481
+ {
3482
+ try
3483
+ {
3484
+ // Set Stripe Secret Key
3485
+ \Stripe\Stripe::setApiKey($this->options['secret_key']);
3486
+ \Stripe\Account::createLoginLink($strip_account_id);
3487
+ }
3488
+ catch(Exception $e)
3489
+ {
3490
+ delete_user_meta($post->post_author, 'mec_stripe_id');
3491
+ $strip_account_id = NULL;
3492
+ }
3493
+ }
3494
+ ?>
3495
+ <h4><?php echo $this->label(); ?></h4>
3496
+ <div class="mec-gateway-options-form">
3497
+
3498
+ <?php if(isset($this->options['organizer_comment']) and trim($this->options['organizer_comment'])): ?>
3499
+ <p><?php echo $this->options['organizer_comment']; ?></p>
3500
+ <?php endif; ?>
3501
+
3502
+ <div class="mec-form-row">
3503
+ <div class="mec-col-12">
3504
+
3505
+ <?php if($connection_method === 'express'): ?>
3506
+ <a id="mec_gateway_options_form_stripe_connection_button" class="button button-primary" onclick="mec_stripe_connection_checker();" href="<?php echo $this->main->URL('site'); ?>?mec-stripe-connect-express-redirect=1&_wpnonce=<?php echo wp_create_nonce('mec_stripe_connect_express_redirect'); ?>" target="_blank"><?php echo ($strip_account_id ? __('Connect New Account', 'modern-events-calendar-lite') : __('Connect', 'modern-events-calendar-lite')); ?></a>
3507
+
3508
+ <div id="mec_gateway_options_form_stripe_connection_success" class="<?php echo $strip_account_id ? '' : 'mec-util-hidden'; ?>">
3509
+ <p class="mec-success"><?php _e("You're connected to our account successfully and you will receive payments in your stripe account directly after deducting the fees.", 'modern-events-calendar-lite'); ?></p>
3510
+ <a href="<?php echo $this->main->URL('site'); ?>?mec-stripe-connect-express-dashboard=1&_wpnonce=<?php echo wp_create_nonce('mec_stripe_connect_express_dashboard'); ?>" target="_blank"><?php echo esc_html__('Visit your dashboard', 'modern-events-calendar-lite'); ?></a>
3511
+ </div>
3512
+ <?php else: ?>
3513
+ <a id="mec_gateway_options_form_stripe_connection_button" class="button button-primary" onclick="mec_stripe_connection_checker();" href="https://connect.stripe.com/oauth/authorize?response_type=code&client_id=<?php echo $client_id; ?>&scope=read_write" target="_blank"><?php echo ($strip_account_id ? __('Connect New Account', 'modern-events-calendar-lite') : __('Connect Your Account', 'modern-events-calendar-lite')); ?></a>
3514
+
3515
+ <div id="mec_gateway_options_form_stripe_connection_success" class="<?php echo $strip_account_id ? '' : 'mec-util-hidden'; ?>">
3516
+ <p class="mec-success"><?php _e("You're connected to our account successfully and you will receive payments in your stripe account directly after deducting the fees.", 'modern-events-calendar-lite'); ?></p>
3517
+ </div>
3518
+ <?php endif; ?>
3519
+
3520
+ </div>
3521
+ </div>
3522
+ </div>
3523
+ <script>
3524
+ function mec_stripe_connection_checker()
3525
+ {
3526
+ jQuery.ajax(
3527
+ {
3528
+ type: "GET",
3529
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
3530
+ data: "action=mec_check_stripe_connection",
3531
+ dataType: "JSON",
3532
+ success: function(data)
3533
+ {
3534
+ if(data.success === 1)
3535
+ {
3536
+ jQuery("#mec_gateway_options_form_stripe_connection_button").hide();
3537
+
3538
+ jQuery("#mec_gateway_options_form_stripe_connection_success").removeClass("mec-util-hidden");
3539
+ }
3540
+ else
3541
+ {
3542
+ setTimeout(function()
3543
+ {
3544
+ mec_stripe_connection_checker();
3545
+ }, 10000);
3546
+ }
3547
+ },
3548
+ error: function (jqXHR, textStatus, errorThrown)
3549
+ {
3550
+ }
3551
+ });
3552
+ }
3553
+ </script>
3554
+ <?php
3555
+ }
3556
+
3557
+ public function check_connection()
3558
+ {
3559
+ $success = 2;
3560
+ $message = __('Waiting for a response from gateway.', 'modern-events-calendar-lite');
3561
+
3562
+ $current_user_id = get_current_user_id();
3563
+ $stripe_user_id = get_user_meta($current_user_id, 'mec_stripe_id', true);
3564
+
3565
+ if($stripe_user_id)
3566
+ {
3567
+ $success = 1;
3568
+ $message = __('User connected successfully!', 'modern-events-calendar-lite');
3569
+ }
3570
+
3571
+ $this->response(
3572
+ array(
3573
+ 'success' => $success,
3574
+ 'message' => $message,
3575
+ )
3576
+ );
3577
+ }
3578
+ }
3579
+
3580
+ do_action('after_MEC_gateway');
3581
+
3582
+ class MEC_gateway_pay_locally extends MEC_gateway
3583
+ {
3584
+ public $id = 1;
3585
+ public $options;
3586
+
3587
+ public function __construct()
3588
+ {
3589
+ parent::__construct();
3590
+
3591
+ // Gateway options
3592
+ $this->options = $this->options();
3593
+
3594
+ // Register actions
3595
+ $this->factory->action('wp_ajax_mec_do_transaction_pay_locally', array($this, 'do_transaction'));
3596
+ $this->factory->action('wp_ajax_nopriv_mec_do_transaction_pay_locally', array($this, 'do_transaction'));
3597
+
3598
+ $this->factory->action('wp_ajax_mec_cart_do_transaction_pay_locally', array($this, 'cart_do_transaction'));
3599
+ $this->factory->action('wp_ajax_nopriv_mec_cart_do_transaction_pay_locally', array($this, 'cart_do_transaction'));
3600
+ }
3601
+
3602
+ public function label()
3603
+ {
3604
+ return __('Pay Locally', 'modern-events-calendar-lite');
3605
+ }
3606
+
3607
+ public function color()
3608
+ {
3609
+ return '#2DCA73';
3610
+ }
3611
+
3612
+ public function options_form()
3613
+ {
3614
+ ?>
3615
+ <div class="mec-form-row mec-click-pay">
3616
+ <label>
3617
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][status]" value="0"/>
3618
+ <input onchange="jQuery('#mec_gateways<?php echo $this->id(); ?>_container_toggle').toggle();" value="1"
3619
+ type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][status]"
3620
+ <?php
3621
+ if (isset($this->options['status']) and $this->options['status']) {
3622
+ echo 'checked="checked"';
3623
+ }
3624
+ ?>
3625
+ /> <?php _e('Pay Locally', 'modern-events-calendar-lite'); ?>
3626
+ </label>
3627
+ </div>
3628
+ <div id="mec_gateways<?php echo $this->id(); ?>_container_toggle" class="mec-gateway-options-form
3629
+ <?php
3630
+ if ((isset($this->options['status']) and !$this->options['status']) or !isset($this->options['status'])) {
3631
+ echo 'mec-util-hidden';
3632
+ }
3633
+ ?>">
3634
+ <div class="mec-form-row">
3635
+ <label class="mec-col-3"
3636
+ for="mec_gateways<?php echo $this->id(); ?>_title"><?php _e('Title', 'modern-events-calendar-lite'); ?></label>
3637
+ <div class="mec-col-9">
3638
+ <input type="text" id="mec_gateways<?php echo $this->id(); ?>_title"
3639
+ name="mec[gateways][<?php echo $this->id(); ?>][title]"
3640
+ value="<?php echo (isset($this->options['title']) and trim($this->options['title'])) ? $this->options['title'] : ''; ?>"
3641
+ placeholder="<?php echo $this->label(); ?>"/>
3642
+ </div>
3643
+ </div>
3644
+ <div class="mec-form-row">
3645
+ <label class="mec-col-3"
3646
+ for="mec_gateways<?php echo $this->id(); ?>_comment"><?php _e('Comment', 'modern-events-calendar-lite'); ?></label>
3647
+ <div class="mec-col-9">
3648
+ <textarea id="mec_gateways<?php echo $this->id(); ?>_comment"
3649
+ name="mec[gateways][<?php echo $this->id(); ?>][comment]"><?php echo (isset($this->options['comment']) and trim($this->options['comment'])) ? stripslashes($this->options['comment']) : esc_html__('Pay Locally Description', 'modern-events-calendar-lite'); ?></textarea>
3650
+ <span class="mec-tooltip">
3651
+ <div class="box left">
3652
+ <h5 class="title"><?php _e('Comment', 'modern-events-calendar-lite'); ?></h5>
3653
+ <div class="content"><p><?php esc_attr_e('HTML allowed.', 'modern-events-calendar-lite'); ?><a
3654
+ href="https://webnus.net/dox/modern-events-calendar/booking/"
3655
+ target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
3656
+ </div>
3657
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
3658
+ </span>
3659
+ </div>
3660
+ </div>
3661
+ <div class="mec-form-row">
3662
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_index"><?php _e('Position', 'modern-events-calendar-lite'); ?></label>
3663
+ <div class="mec-col-9">
3664
+ <input type="number" min="0" step="1" id="mec_gateways<?php echo $this->id(); ?>_index"
3665
+ name="mec[gateways][<?php echo $this->id(); ?>][index]"
3666
+ value="<?php echo (isset($this->options['index']) and trim($this->options['index'])) ? $this->options['index'] : 1; ?>"
3667
+ placeholder="<?php echo esc_attr__('Position', 'modern-events-calendar-lite'); ?>"/>
3668
+ </div>
3669
+ </div>
3670
+ <div class="mec-form-row">
3671
+ <label class="mec-col-12">
3672
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][disable_auto_confirmation]" value="0">
3673
+ <input value="1" type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][disable_auto_confirmation]" <?php echo (isset($this->options['disable_auto_confirmation']) and trim($this->options['disable_auto_confirmation'])) ? 'checked="checked"' : ''; ?>>
3674
+ <?php _e('Disable Auto Confirmation', 'modern-events-calendar-lite'); ?>
3675
+ </label>
3676
+ </div>
3677
+ </div>
3678
+ <?php
3679
+ }
3680
+
3681
+ public function checkout_form($transaction_id, $params = array())
3682
+ {
3683
+ ?>
3684
+ <script type="text/javascript">
3685
+ jQuery("#mec_do_transaction_pay_locally_form<?php echo $transaction_id; ?>").on("submit", function(event)
3686
+ {
3687
+ event.preventDefault();
3688
+ jQuery(this).find('button').attr('disabled', true);
3689
+
3690
+ // Add loading Class to the button
3691
+ jQuery("#mec_do_transaction_pay_locally_form<?php echo $transaction_id; ?> button[type=submit]").addClass("loading");
3692
+ jQuery("#mec_do_transaction_pay_locally_message<?php echo $transaction_id; ?>").removeClass("mec-success mec-error").hide();
3693
+
3694
+ var data = jQuery("#mec_do_transaction_pay_locally_form<?php echo $transaction_id; ?>").serialize();
3695
+ jQuery.ajax(
3696
+ {
3697
+ type: "GET",
3698
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
3699
+ data: data,
3700
+ dataType: "JSON",
3701
+ success: function (data)
3702
+ {
3703
+ // Remove the loading Class from the button
3704
+ jQuery("#mec_do_transaction_pay_locally_form<?php echo $transaction_id; ?> button[type=submit]").removeClass("loading");
3705
+
3706
+ jQuery("#mec_do_transaction_pay_locally_form<?php echo $transaction_id; ?>").hide();
3707
+ jQuery(".mec-book-form-gateway-label").remove();
3708
+
3709
+ if(data.success)
3710
+ {
3711
+ jQuery(".mec-book-form-coupon").hide();
3712
+ jQuery(".mec-gateway-comment").hide();
3713
+
3714
+ jQuery("#mec-book-form-back-btn-step-3").remove();
3715
+ jQuery("#mec_do_transaction_pay_locally_message<?php echo $transaction_id; ?>").addClass("mec-success").html(data.message).show();
3716
+
3717
+ // Show Invoice Link
3718
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
3719
+ {
3720
+ jQuery("#mec_do_transaction_pay_locally_message<?php echo $transaction_id; ?>").append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
3721
+ }
3722
+
3723
+ // Show Downloadable Link
3724
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
3725
+ {
3726
+ jQuery("#mec_do_transaction_pay_locally_message<?php echo $transaction_id; ?>").append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
3727
+ }
3728
+
3729
+ // Show Extra info
3730
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
3731
+ {
3732
+ jQuery("#mec_do_transaction_pay_locally_message<?php echo $transaction_id; ?>").append('<div>' + data.data.extra_info+'</div>');
3733
+ }
3734
+
3735
+ // Redirect to thank you page
3736
+ if (typeof data.data.redirect_to != "undefined" && data.data.redirect_to != "") {
3737
+ setTimeout(function () {
3738
+ window.location.href = data.data.redirect_to;
3739
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
3740
+ }
3741
+ jQuery(this).find('button').removeAttr('disabled');
3742
+ }
3743
+ else {
3744
+ jQuery("#mec_do_transaction_pay_locally_message<?php echo $transaction_id; ?>").addClass("mec-error").html(data.message).show();
3745
+ }
3746
+
3747
+ },
3748
+ error: function (jqXHR, textStatus, errorThrown) {
3749
+ // Remove the loading Class from the button
3750
+ jQuery("#mec_do_transaction_pay_locally_form<?php echo $transaction_id; ?> button[type=submit]").removeClass("loading");
3751
+ }
3752
+ });
3753
+ });
3754
+ </script>
3755
+ <div class="mec-gateway-message mec-util-hidden"
3756
+ id="mec_do_transaction_pay_locally_message<?php echo $transaction_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
3757
+ <form id="mec_do_transaction_pay_locally_form<?php echo $transaction_id; ?>" class="mec-click-pay">
3758
+ <input type="hidden" name="action" value="mec_do_transaction_pay_locally"/>
3759
+ <input type="hidden" name="transaction_id" value="<?php echo $transaction_id; ?>"/>
3760
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
3761
+ <?php wp_nonce_field('mec_transaction_form_' . $transaction_id); ?>
3762
+ <button class="mec-book-form-next-button" type="submit"><?php _e('Submit', 'modern-events-calendar-lite'); ?></button>
3763
+ <?php do_action('mec_booking_checkout_form_before_end', $transaction_id); ?>
3764
+ </form>
3765
+ <?php
3766
+ }
3767
+
3768
+ public function do_transaction($transaction_id = null)
3769
+ {
3770
+ if(!trim($transaction_id)) $transaction_id = isset($_GET['transaction_id']) ? sanitize_text_field($_GET['transaction_id']) : 0;
3771
+
3772
+ // Verify that the nonce is valid.
3773
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_transaction_form_' . $transaction_id))
3774
+ {
3775
+ $this->response(array(
3776
+ 'success' => 0,
3777
+ 'code' => 'NONCE_IS_INVALID',
3778
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
3779
+ ));
3780
+ }
3781
+
3782
+ // Validate Ticket Availability
3783
+ $this->validate($transaction_id);
3784
+
3785
+ $transaction = $this->book->get_transaction($transaction_id);
3786
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
3787
+
3788
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
3789
+ $attention_times = explode(':', $attention_date);
3790
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
3791
+
3792
+ // Is there any attendee?
3793
+ if (!count($attendees)) {
3794
+ $this->response(
3795
+ array(
3796
+ 'success' => 0,
3797
+ 'code' => 'NO_TICKET',
3798
+ 'message' => __(
3799
+ 'There is no attendee for booking!',
3800
+ 'mec'
3801
+ ),
3802
+ )
3803
+ );
3804
+ }
3805
+
3806
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
3807
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
3808
+
3809
+ $ticket_ids = '';
3810
+ $attendees_info = array();
3811
+
3812
+ foreach($attendees as $i => $attendee)
3813
+ {
3814
+ if(!is_numeric($i)) continue;
3815
+
3816
+ $ticket_ids .= $attendee['id'] . ',';
3817
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
3818
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
3819
+ }
3820
+
3821
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
3822
+ $user_id = $this->register_user($main_attendee, $transaction);
3823
+
3824
+ // Remove Sensitive Data
3825
+ if(isset($transaction['username']) or isset($transaction['password']))
3826
+ {
3827
+ unset($transaction['username']);
3828
+ unset($transaction['password']);
3829
+
3830
+ $this->book->update_transaction($transaction_id, $transaction);
3831
+ }
3832
+
3833
+ // MEC User
3834
+ $u = $this->getUser();
3835
+
3836
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
3837
+ $book_id = $this->book->add(
3838
+ array(
3839
+ 'post_author' => $user_id,
3840
+ 'post_type' => $this->PT,
3841
+ 'post_title' => $book_subject,
3842
+ 'post_date' => $date,
3843
+ 'attendees_info' => $attendees_info,
3844
+ 'mec_attendees' => $attendees,
3845
+ 'mec_gateway' => 'MEC_gateway_pay_locally',
3846
+ 'mec_gateway_label' => $this->title()
3847
+ ),
3848
+ $transaction_id,
3849
+ $ticket_ids
3850
+ );
3851
+
3852
+ // Assign User
3853
+ $u->assign($book_id, $user_id);
3854
+
3855
+ // Fires after completely creating a new booking
3856
+ do_action('mec_booking_completed', $book_id);
3857
+
3858
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
3859
+ $redirect_to = '';
3860
+
3861
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
3862
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
3863
+
3864
+ // Invoice Link
3865
+ $mec_confirmed = get_post_meta($book_id, 'mec_confirmed', true);
3866
+ $invoice_link = (!$mec_confirmed) ? '' : $this->book->get_invoice_link($transaction_id);
3867
+ $dl_file_link = (!$mec_confirmed) ? '' : $this->book->get_dl_file_link($book_id);
3868
+
3869
+ $extra_info = apply_filters('MEC_extra_info_gateways', '', $this->book->get_event_id_by_transaction_id($transaction_id), $book_id);
3870
+
3871
+ $this->response(
3872
+ array(
3873
+ 'success' => 1,
3874
+ 'message' => stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite'))),
3875
+ 'data' => array(
3876
+ 'book_id' => $book_id,
3877
+ 'redirect_to' => $redirect_to,
3878
+ 'invoice_link' => $invoice_link,
3879
+ 'dl_file_link' => $dl_file_link,
3880
+ 'extra_info' => $extra_info,
3881
+ ),
3882
+ )
3883
+ );
3884
+ }
3885
+
3886
+ public function cart_checkout_form($cart_id, $params = array())
3887
+ {
3888
+ ?>
3889
+ <div class="mec-gateway-message mec-util-hidden" id="mec_do_cart_pay_locally_message<?php echo $cart_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
3890
+ <form id="mec_do_cart_pay_locally_form<?php echo $cart_id; ?>" class="mec-click-pay">
3891
+ <input type="hidden" name="action" value="mec_cart_do_transaction_pay_locally"/>
3892
+ <input type="hidden" name="cart_id" value="<?php echo $cart_id; ?>"/>
3893
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
3894
+ <?php wp_nonce_field('mec_cart_form_' . $cart_id); ?>
3895
+ <button class="mec-book-form-next-button" type="submit"><?php _e('Submit', 'modern-events-calendar-lite'); ?></button>
3896
+ <?php do_action('mec_cart_checkout_form_before_end', $cart_id); ?>
3897
+ </form>
3898
+ <script type="text/javascript">
3899
+ jQuery("#mec_do_cart_pay_locally_form<?php echo $cart_id; ?>").on("submit", function(e)
3900
+ {
3901
+ e.preventDefault();
3902
+ jQuery(this).find('button').attr('disabled', true);
3903
+
3904
+ // Add loading Class to the button
3905
+ jQuery("#mec_do_cart_pay_locally_form<?php echo $cart_id; ?> button[type=submit]").addClass("loading");
3906
+ jQuery("#mec_do_cart_pay_locally_message<?php echo $cart_id; ?>").removeClass("mec-success mec-error").hide();
3907
+
3908
+ var data = jQuery("#mec_do_cart_pay_locally_form<?php echo $cart_id; ?>").serialize();
3909
+ jQuery.ajax(
3910
+ {
3911
+ type: "GET",
3912
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
3913
+ data: data,
3914
+ dataType: "JSON",
3915
+ success: function (data)
3916
+ {
3917
+ // Remove the loading Class from the button
3918
+ jQuery("#mec_do_cart_pay_locally_form<?php echo $cart_id; ?> button[type=submit]").removeClass("loading");
3919
+
3920
+ if(data.success)
3921
+ {
3922
+ jQuery("#mec_do_cart_pay_locally_form<?php echo $cart_id; ?>").hide();
3923
+ jQuery(".mec-checkout-form-gateway-label").remove();
3924
+
3925
+ jQuery(".mec-gateway-comment").hide();
3926
+ jQuery("#mec_do_cart_pay_locally_message<?php echo $cart_id; ?>").addClass("mec-success").html(data.message).show();
3927
+
3928
+ jQuery(this).find('button').removeAttr('disabled');
3929
+ }
3930
+ else
3931
+ {
3932
+ jQuery("#mec_do_cart_pay_locally_message<?php echo $cart_id; ?>").addClass("mec-error").html(data.message).show();
3933
+ }
3934
+ },
3935
+ error: function(jqXHR, textStatus, errorThrown)
3936
+ {
3937
+ // Remove the loading Class from the button
3938
+ jQuery("#mec_do_cart_pay_locally_form<?php echo $cart_id; ?> button[type=submit]").removeClass("loading");
3939
+ }
3940
+ });
3941
+ });
3942
+ </script>
3943
+ <?php
3944
+ }
3945
+
3946
+ public function cart_do_transaction()
3947
+ {
3948
+ $cart_id = isset($_GET['cart_id']) ? sanitize_text_field($_GET['cart_id']) : NULL;
3949
+
3950
+ // Verify that the nonce is valid.
3951
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_cart_form_' . $cart_id))
3952
+ {
3953
+ $this->response(array(
3954
+ 'success' => 0,
3955
+ 'code' => 'NONCE_IS_INVALID',
3956
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
3957
+ ));
3958
+ }
3959
+
3960
+ // Validate Ticket Availability
3961
+ $this->cart_validate($cart_id);
3962
+
3963
+ // Parent Function
3964
+ $this->response($this->do_cart_transaction($cart_id, array(
3965
+ 'gateway' => 'MEC_gateway_pay_locally',
3966
+ )));
3967
+ }
3968
+ }
3969
+
3970
+ class MEC_gateway_paypal_express extends MEC_gateway
3971
+ {
3972
+ public $id = 2;
3973
+ public $options;
3974
+
3975
+ public function __construct()
3976
+ {
3977
+ parent::__construct();
3978
+
3979
+ // Gateway options
3980
+ $this->options = $this->options();
3981
+
3982
+ // Register actions
3983
+ $this->factory->action('wp_ajax_mec_check_transaction_paypal_express', array($this, 'check_transaction'));
3984
+ $this->factory->action('wp_ajax_nopriv_mec_check_transaction_paypal_express', array($this, 'check_transaction'));
3985
+ $this->factory->action('wp_ajax_mec_pre_transaction_paypal_express', array($this, 'pre_validation'));
3986
+ $this->factory->action('wp_ajax_nopriv_mec_pre_transaction_paypal_express', array($this, 'pre_validation'));
3987
+
3988
+ $this->factory->action('wp_ajax_mec_cart_check_transaction_paypal_express', array($this, 'cart_check_transaction'));
3989
+ $this->factory->action('wp_ajax_nopriv_mec_cart_check_transaction_paypal_express', array($this, 'cart_check_transaction'));
3990
+ $this->factory->action('wp_ajax_mec_cart_pre_transaction_paypal_express', array($this, 'cart_pre_validation'));
3991
+ $this->factory->action('wp_ajax_nopriv_mec_cart_pre_transaction_paypal_express', array($this, 'cart_pre_validation'));
3992
+ }
3993
+
3994
+ public function label()
3995
+ {
3996
+ return __('PayPal Express', 'modern-events-calendar-lite');
3997
+ }
3998
+
3999
+ public function color()
4000
+ {
4001
+ return '#8338ec';
4002
+ }
4003
+
4004
+ public function op_enabled()
4005
+ {
4006
+ return true;
4007
+ }
4008
+
4009
+ public function op_form($options = array())
4010
+ {
4011
+ ?>
4012
+ <h4><?php echo $this->label(); ?></h4>
4013
+ <div class="mec-gateway-options-form">
4014
+ <div class="mec-form-row">
4015
+ <label class="mec-col-3" for="mec_op<?php echo $this->id(); ?>_account"><?php _e('Business Account', 'modern-events-calendar-lite'); ?></label>
4016
+ <div class="mec-col-9">
4017
+ <input type="text" id="mec_op<?php echo $this->id(); ?>_account" name="mec[op][<?php echo $this->id(); ?>][account]" value="<?php echo isset($options['account']) ? $options['account'] : ''; ?>" />
4018
+ <span class="mec-tooltip">
4019
+ <div class="box left">
4020
+ <h5 class="title"><?php _e('Business Account', 'modern-events-calendar-lite'); ?></h5>
4021
+ <div class="content"><p><?php esc_attr_e('Normally PayPal Email.', 'modern-events-calendar-lite'); ?><a href="https://webnus.net/dox/modern-events-calendar/booking/" target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
4022
+ </div>
4023
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
4024
+ </span>
4025
+ </div>
4026
+ </div>
4027
+ </div>
4028
+ <?php
4029
+ }
4030
+
4031
+ public function options_form()
4032
+ {
4033
+ ?>
4034
+ <div class="mec-form-row mec-click-pay">
4035
+ <label>
4036
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][status]" value="0"/>
4037
+ <input onchange="jQuery('#mec_gateways<?php echo $this->id(); ?>_container_toggle').toggle();" value="1"
4038
+ type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][status]"
4039
+ <?php
4040
+ if (isset($this->options['status']) and $this->options['status']) {
4041
+ echo 'checked="checked"';
4042
+ }
4043
+ ?>
4044
+ /> <?php _e('PayPal Express', 'modern-events-calendar-lite'); ?>
4045
+ </label>
4046
+ </div>
4047
+ <div id="mec_gateways<?php echo $this->id(); ?>_container_toggle" class="mec-gateway-options-form
4048
+ <?php
4049
+ if ((isset($this->options['status']) and !$this->options['status']) or !isset($this->options['status'])) {
4050
+ echo 'mec-util-hidden';
4051
+ }
4052
+ ?>">
4053
+ <div class="mec-form-row">
4054
+ <label class="mec-col-3"
4055
+ for="mec_gateways<?php echo $this->id(); ?>_title"><?php _e('Title', 'modern-events-calendar-lite'); ?></label>
4056
+ <div class="mec-col-9">
4057
+ <input type="text" id="mec_gateways<?php echo $this->id(); ?>_title"
4058
+ name="mec[gateways][<?php echo $this->id(); ?>][title]"
4059
+ value="<?php echo (isset($this->options['title']) and trim($this->options['title'])) ? $this->options['title'] : ''; ?>"
4060
+ placeholder="<?php echo $this->label(); ?>"/>
4061
+ </div>
4062
+ </div>
4063
+ <div class="mec-form-row">
4064
+ <label class="mec-col-3"
4065
+ for="mec_gateways<?php echo $this->id(); ?>_comment"><?php _e('Comment', 'modern-events-calendar-lite'); ?></label>
4066
+ <div class="mec-col-9">
4067
+ <textarea id="mec_gateways<?php echo $this->id(); ?>_comment"
4068
+ name="mec[gateways][<?php echo $this->id(); ?>][comment]"><?php echo (isset($this->options['comment']) and trim($this->options['comment'])) ? stripslashes($this->options['comment']) : esc_html__('Paypal Express Description', 'modern-events-calendar-lite'); ?></textarea>
4069
+ <span class="mec-tooltip">
4070
+ <div class="box left">
4071
+ <h5 class="title"><?php _e('Comment', 'modern-events-calendar-lite'); ?></h5>
4072
+ <div class="content"><p><?php esc_attr_e('HTML allowed.', 'modern-events-calendar-lite'); ?><a
4073
+ href="https://webnus.net/dox/modern-events-calendar/booking/"
4074
+ target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
4075
+ </div>
4076
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
4077
+ </span>
4078
+ </div>
4079
+ </div>
4080
+ <div class="mec-form-row">
4081
+ <label class="mec-col-3"
4082
+ for="mec_gateways<?php echo $this->id(); ?>_account"><?php _e('Business Account', 'modern-events-calendar-lite'); ?></label>
4083
+ <div class="mec-col-9">
4084
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_account"
4085
+ name="mec[gateways][<?php echo $this->id(); ?>][account]"
4086
+ value="<?php echo isset($this->options['account']) ? $this->options['account'] : ''; ?>" />
4087
+ <span class="mec-tooltip">
4088
+ <div class="box left">
4089
+ <h5 class="title"><?php _e('Business Account', 'modern-events-calendar-lite'); ?></h5>
4090
+ <div class="content"><p><?php esc_attr_e('Normally PayPal Email.', 'modern-events-calendar-lite'); ?><a
4091
+ href="https://webnus.net/dox/modern-events-calendar/booking/"
4092
+ target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
4093
+ </div>
4094
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
4095
+ </span>
4096
+ </div>
4097
+ </div>
4098
+ <div class="mec-form-row">
4099
+ <label class="mec-col-3"
4100
+ for="mec_gateways<?php echo $this->id(); ?>_mode"><?php _e('Mode', 'modern-events-calendar-lite'); ?></label>
4101
+ <div class="mec-col-9">
4102
+ <select id="mec_gateways<?php echo $this->id(); ?>_mode"
4103
+ name="mec[gateways][<?php echo $this->id(); ?>][mode]">
4104
+ <option value="live" <?php echo (isset($this->options['mode']) and $this->options['mode'] == 'live') ? 'selected="selected"' : ''; ?>><?php _e('Live', 'modern-events-calendar-lite'); ?></option>
4105
+ <option value="sandbox" <?php echo (isset($this->options['mode']) and $this->options['mode'] == 'sandbox') ? 'selected="selected"' : ''; ?>><?php _e('Sandbox', 'modern-events-calendar-lite'); ?></option>
4106
+ </select>
4107
+ </div>
4108
+ </div>
4109
+ <div class="mec-form-row">
4110
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_index"><?php _e('Position', 'modern-events-calendar-lite'); ?></label>
4111
+ <div class="mec-col-9">
4112
+ <input type="number" min="0" step="1" id="mec_gateways<?php echo $this->id(); ?>_index"
4113
+ name="mec[gateways][<?php echo $this->id(); ?>][index]"
4114
+ value="<?php echo (isset($this->options['index']) and trim($this->options['index'])) ? $this->options['index'] : 2; ?>"
4115
+ placeholder="<?php echo esc_attr__('Position', 'modern-events-calendar-lite'); ?>"/>
4116
+ </div>
4117
+ </div>
4118
+ </div>
4119
+ <?php
4120
+ }
4121
+
4122
+ public function get_api_url()
4123
+ {
4124
+ $live = 'https://www.paypal.com/cgi-bin/webscr';
4125
+ $sandbox = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
4126
+
4127
+ if($this->options['mode'] == 'live') $url = $live;
4128
+ else $url = $sandbox;
4129
+
4130
+ return $url;
4131
+ }
4132
+
4133
+ public function get_notify_url()
4134
+ {
4135
+ return $this->main->URL('mec') . 'app/features/gateways/paypal_ipn.php';
4136
+ }
4137
+
4138
+ public function checkout_form($transaction_id, $params = array())
4139
+ {
4140
+ // Get Options Compatible with Organizer Payment
4141
+ $options = $this->options($transaction_id);
4142
+
4143
+ $transaction = $this->book->get_transaction($transaction_id);
4144
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
4145
+ $tickets_count = isset($transaction['tickets']) ? count($transaction['tickets']) : 1;
4146
+ ?>
4147
+ <script type="text/javascript">
4148
+ function mec_paypal_express_pre_validation(transaction_id)
4149
+ {
4150
+ // Add loading Class to the button
4151
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id + " button[type=submit]").addClass("loading");
4152
+ jQuery("#mec_do_transaction_paypal_express_message" + transaction_id).removeClass("mec-success mec-error").hide();
4153
+
4154
+ jQuery.ajax(
4155
+ {
4156
+ type: "GET",
4157
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
4158
+ data: "action=mec_pre_transaction_paypal_express&transaction_id=" + transaction_id,
4159
+ dataType: "JSON",
4160
+ success: function(data)
4161
+ {
4162
+ if(data.success == 1)
4163
+ {
4164
+ // Remove the loading Class from the button
4165
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id + " button[type=submit]").removeClass("loading");
4166
+
4167
+ // Submit the Form
4168
+ jQuery('#mec_do_transaction_paypal_express_form' + transaction_id).trigger('submit');
4169
+ }
4170
+ else
4171
+ {
4172
+ // Remove the loading Class from the button
4173
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id + " button[type=submit]").removeClass("loading");
4174
+
4175
+ jQuery("#mec_do_transaction_paypal_express_message" + transaction_id).addClass("mec-error").html(data.message).show();
4176
+ }
4177
+ },
4178
+ error: function(jqXHR, textStatus, errorThrown)
4179
+ {
4180
+ // Remove the loading Class from the button
4181
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id + " button[type=submit]").removeClass("loading");
4182
+ }
4183
+ });
4184
+ }
4185
+
4186
+ function mec_paypal_express_pay_checker(transaction_id)
4187
+ {
4188
+ // Add loading Class to the button
4189
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id + " button[type=submit]").addClass("loading");
4190
+ jQuery("#mec_do_transaction_paypal_express_message" + transaction_id).removeClass("mec-success mec-error").hide();
4191
+
4192
+ jQuery.ajax(
4193
+ {
4194
+ type: "GET",
4195
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
4196
+ data: "action=mec_check_transaction_paypal_express&transaction_id=" + transaction_id,
4197
+ dataType: "JSON",
4198
+ success: function(data)
4199
+ {
4200
+ if(data.success == 1)
4201
+ {
4202
+ // Remove the loading Class from the button
4203
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id + " button[type=submit]").removeClass("loading");
4204
+
4205
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id).hide();
4206
+ jQuery(".mec-book-form-gateway-label").remove();
4207
+ jQuery(".mec-book-form-coupon").hide();
4208
+ jQuery(".mec-gateway-comment").hide();
4209
+
4210
+ jQuery("#mec-book-form-back-btn-step-3").remove();
4211
+ jQuery("#mec_do_transaction_paypal_express_message" + transaction_id).addClass("mec-success").html(data.message).show();
4212
+
4213
+ // Show Invoice Link
4214
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
4215
+ {
4216
+ jQuery("#mec_do_transaction_paypal_express_message" + transaction_id).append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
4217
+ }
4218
+
4219
+ // Show Downloadable Link
4220
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
4221
+ {
4222
+ jQuery("#mec_do_transaction_paypal_express_message" + transaction_id).append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
4223
+ }
4224
+
4225
+ // Show Extra info
4226
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
4227
+ {
4228
+ jQuery("#mec_do_transaction_paypal_express_message" + transaction_id).append('<div>' + data.data.extra_info+'</div>');
4229
+ }
4230
+
4231
+ // Redirect to thank you page
4232
+ if(typeof data.data.redirect_to != "undefined" && data.data.redirect_to != "")
4233
+ {
4234
+ setTimeout(function()
4235
+ {
4236
+ window.location.href = data.data.redirect_to;
4237
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
4238
+ }
4239
+ }
4240
+ else if(data.success == 0)
4241
+ {
4242
+ // Remove the loading Class from the button
4243
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id + " button[type=submit]").removeClass("loading");
4244
+
4245
+ jQuery("#mec_do_transaction_paypal_express_message" + transaction_id).addClass("mec-error").html(data.message).show();
4246
+ }
4247
+ else
4248
+ {
4249
+ setTimeout(function () {
4250
+ mec_paypal_express_pay_checker(transaction_id)
4251
+ }, 10000);
4252
+ }
4253
+ },
4254
+ error: function(jqXHR, textStatus, errorThrown)
4255
+ {
4256
+ // Remove the loading Class from the button
4257
+ jQuery("#mec_do_transaction_paypal_express_form" + transaction_id + " button[type=submit]").removeClass("loading");
4258
+ }
4259
+ });
4260
+ }
4261
+ </script>
4262
+ <div class="mec-gateway-message mec-util-hidden" id="mec_do_transaction_paypal_express_message<?php echo $transaction_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
4263
+ <form id="mec_do_transaction_paypal_express_form<?php echo $transaction_id; ?>" class="mec-click-pay" action="<?php echo $this->get_api_url(); ?>" method="post" target="_blank" onsubmit="mec_paypal_express_pay_checker('<?php echo $transaction_id; ?>');">
4264
+ <input type="hidden" name="cmd" value="_xclick"/>
4265
+ <input type="hidden" name="rm" value="2"/>
4266
+ <input type="hidden" name="business" value="<?php echo(isset($options['account']) ? $options['account'] : null); ?>"/>
4267
+ <input type="hidden" name="item_name" value="<?php echo esc_attr(get_the_title($event_id)); ?>"/>
4268
+ <input type="hidden" name="item_number" value="<?php echo $tickets_count; ?>"/>
4269
+ <input type="hidden" name="amount" value="<?php echo(isset($transaction['price']) ? $transaction['price'] : 0); ?>"/>
4270
+ <input type="hidden" name="currency_code" value="<?php echo $this->main->get_currency_code($event_id); ?>"/>
4271
+ <input type="hidden" name="cancel_return" value="<?php echo $this->get_cancel_url($event_id); ?>"/>
4272
+ <input type="hidden" name="notify_url" value="<?php echo $this->get_notify_url(); ?>"/>
4273
+ <input type="hidden" name="return" value="<?php echo $this->get_return_url($event_id); ?>"/>
4274
+ <input type="hidden" name="custom" value="<?php echo base64_encode(json_encode(array('transaction_id' => $transaction_id))); ?>"/>
4275
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
4276
+ </form>
4277
+ <?php
4278
+ }
4279
+
4280
+ public function pre_validation()
4281
+ {
4282
+ $transaction_id = (isset($_GET['transaction_id']) ? sanitize_text_field($_GET['transaction_id']) : 0);
4283
+
4284
+ // Validate Ticket Availability
4285
+ $this->validate($transaction_id);
4286
+
4287
+ $this->response(array('success' => 1, 'message' => __('Ready to checkout.', 'modern-events-calendar-lite')));
4288
+ }
4289
+
4290
+ public function do_transaction($transaction_id = null)
4291
+ {
4292
+ $transaction = $this->book->get_transaction($transaction_id);
4293
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
4294
+
4295
+ // Is there any attendee?
4296
+ if(!count($attendees))
4297
+ {
4298
+ $this->response(
4299
+ array(
4300
+ 'success' => 0,
4301
+ 'code' => 'NO_TICKET',
4302
+ 'message' => __(
4303
+ 'There is no attendee for booking!',
4304
+ 'mec'
4305
+ ),
4306
+ )
4307
+ );
4308
+ }
4309
+
4310
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
4311
+ $attention_times = explode(':', $attention_date);
4312
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
4313
+
4314
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
4315
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
4316
+
4317
+ $ticket_ids = '';
4318
+ $attendees_info = array();
4319
+
4320
+ foreach($attendees as $i => $attendee)
4321
+ {
4322
+ if(!is_numeric($i)) continue;
4323
+
4324
+ $ticket_ids .= $attendee['id'] . ',';
4325
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
4326
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
4327
+ }
4328
+
4329
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
4330
+ $user_id = $this->register_user($main_attendee, $transaction);
4331
+
4332
+ // Remove Sensitive Data
4333
+ if(isset($transaction['username']) or isset($transaction['password']))
4334
+ {
4335
+ unset($transaction['username']);
4336
+ unset($transaction['password']);
4337
+
4338
+ $this->book->update_transaction($transaction_id, $transaction);
4339
+ }
4340
+
4341
+ // MEC User
4342
+ $u = $this->getUser();
4343
+
4344
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
4345
+ $book_id = $this->book->add(
4346
+ array(
4347
+ 'post_author' => $user_id,
4348
+ 'post_type' => $this->PT,
4349
+ 'post_title' => $book_subject,
4350
+ 'post_date' => $date,
4351
+ 'attendees_info' => $attendees_info,
4352
+ 'mec_attendees' => $attendees,
4353
+ 'mec_gateway' => 'MEC_gateway_paypal_express',
4354
+ 'mec_gateway_label' => $this->title()
4355
+ ),
4356
+ $transaction_id,
4357
+ $ticket_ids
4358
+ );
4359
+
4360
+ // Assign User
4361
+ $u->assign($book_id, $user_id);
4362
+
4363
+ // Fires after completely creating a new booking
4364
+ do_action('mec_booking_completed', $book_id);
4365
+ }
4366
+
4367
+ public function validate_express_payment($vars)
4368
+ {
4369
+ // Check if Paypal is disabled
4370
+ if(!$this->enabled())
4371
+ {
4372
+ return false;
4373
+ }
4374
+
4375
+ $custom = $this->decode_custom($vars['custom']);
4376
+ $transaction_id = $custom['transaction_id'];
4377
+
4378
+ $transaction = $this->book->get_transaction($transaction_id);
4379
+
4380
+ $request_str = $this->get_request_string($vars) . '&cmd=_notify-validate';
4381
+ $response_str = $this->get_paypal_response($request_str, $this->get_api_url());
4382
+
4383
+ // $this->main->debug_log(current_time('Y-m-d H:i:s').' => ('.$response_str.') => '.print_r($vars, true));
4384
+
4385
+ if(strpos($response_str, 'VERIFIED') !== false) $status = 1;
4386
+ else $status = 0;
4387
+
4388
+ $amount = $vars['mc_gross'];
4389
+
4390
+ // Compare paid amount with transaction amount
4391
+ $valid = ($amount >= $transaction['price'] and $status) ? true : false;
4392
+ if($valid)
4393
+ {
4394
+ // Mark it as done
4395
+ $transaction['done'] = 1;
4396
+
4397
+ // Save Gateway Transaction ID
4398
+ $transaction['gateway_transaction_id'] = (isset($vars['txn_id']) and trim($vars['txn_id'])) ? $vars['txn_id'] : '';
4399
+
4400
+ $this->book->update_transaction($transaction_id, $transaction);
4401
+ $this->do_transaction($transaction_id);
4402
+
4403
+ return true;
4404
+ }
4405
+ else
4406
+ {
4407
+ // Mark it as done
4408
+ $transaction['done'] = 0;
4409
+ $this->book->update_transaction($transaction_id, $transaction);
4410
+
4411
+ return false;
4412
+ }
4413
+ }
4414
+
4415
+ public function check_transaction($transaction_id = null)
4416
+ {
4417
+ if(!trim($transaction_id)) $transaction_id = isset($_GET['transaction_id']) ? sanitize_text_field($_GET['transaction_id']) : 0;
4418
+
4419
+ $transaction = $this->book->get_transaction($transaction_id);
4420
+
4421
+ $success = 2;
4422
+ $message = __('Waiting for a response from gateway.', 'modern-events-calendar-lite');
4423
+ $data = array();
4424
+
4425
+ if(isset($transaction['done']) and $transaction['done'] == 1)
4426
+ {
4427
+ $success = 1;
4428
+ $message = stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite')));
4429
+
4430
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
4431
+
4432
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
4433
+ if($thankyou_page_id) $data['redirect_to'] = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
4434
+
4435
+ $extra_info = apply_filters('MEC_extra_info_gateways', '', $this->book->get_event_id_by_transaction_id($transaction_id), NULL);
4436
+
4437
+ // Invoice Link
4438
+ $data['invoice_link'] = $this->book->get_invoice_link($transaction_id);
4439
+ $data['dl_file_link'] = $this->book->get_dl_file_link($this->book->get_event_id_by_transaction_id($transaction_id));
4440
+ $data['extra_info'] = $extra_info;
4441
+ }
4442
+ elseif(isset($transaction['done']) and $transaction['done'] == 0)
4443
+ {
4444
+ $success = 0;
4445
+ $message = __('Payment invalid! Booking failed.', 'modern-events-calendar-lite');
4446
+ }
4447
+
4448
+ $this->response(
4449
+ array(
4450
+ 'success' => $success,
4451
+ 'message' => $message,
4452
+ 'data' => $data,
4453
+ )
4454
+ );
4455
+ }
4456
+
4457
+ public function cart_checkout_form($cart_id, $params = array())
4458
+ {
4459
+ // Get Options
4460
+ $options = $this->options();
4461
+
4462
+ // Cart Library
4463
+ $c = $this->getCart();
4464
+ $cart = $c->get_cart($cart_id);
4465
+
4466
+ $event_id = $c->get_first_event_id($cart);
4467
+ $transactions_count = count($cart);
4468
+ ?>
4469
+ <script type="text/javascript">
4470
+ function mec_paypal_express_pre_validation(cart_id)
4471
+ {
4472
+ // Add loading Class to the button
4473
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id + " button[type=submit]").addClass("loading");
4474
+ jQuery("#mec_do_transaction_paypal_express_message" + cart_id).removeClass("mec-success mec-error").hide();
4475
+
4476
+ jQuery.ajax(
4477
+ {
4478
+ type: "GET",
4479
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
4480
+ data: "action=mec_cart_pre_transaction_paypal_express&cart_id=" + cart_id,
4481
+ dataType: "JSON",
4482
+ success: function(data)
4483
+ {
4484
+ if(data.success == 1)
4485
+ {
4486
+ // Remove the loading Class from the button
4487
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id + " button[type=submit]").removeClass("loading");
4488
+
4489
+ // Submit the Form
4490
+ jQuery('#mec_do_transaction_paypal_express_form' + cart_id).trigger('submit');
4491
+ }
4492
+ else
4493
+ {
4494
+ // Remove the loading Class from the button
4495
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id + " button[type=submit]").removeClass("loading");
4496
+
4497
+ jQuery("#mec_do_transaction_paypal_express_message" + cart_id).addClass("mec-error").html(data.message).show();
4498
+ }
4499
+ },
4500
+ error: function(jqXHR, textStatus, errorThrown)
4501
+ {
4502
+ // Remove the loading Class from the button
4503
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id + " button[type=submit]").removeClass("loading");
4504
+ }
4505
+ });
4506
+ }
4507
+
4508
+ function mec_paypal_express_pay_checker(cart_id)
4509
+ {
4510
+ // Add loading Class to the button
4511
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id + " button[type=submit]").addClass("loading");
4512
+ jQuery("#mec_do_transaction_paypal_express_message" + cart_id).removeClass("mec-success mec-error").hide();
4513
+
4514
+ jQuery.ajax(
4515
+ {
4516
+ type: "GET",
4517
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
4518
+ data: "action=mec_cart_check_transaction_paypal_express&cart_id=" + cart_id,
4519
+ dataType: "JSON",
4520
+ success: function(data)
4521
+ {
4522
+ if(data.success == 1)
4523
+ {
4524
+ // Remove the loading Class from the button
4525
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id + " button[type=submit]").removeClass("loading");
4526
+
4527
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id).hide();
4528
+ jQuery(".mec-checkout-form-gateway-label").remove();
4529
+ jQuery(".mec-gateway-comment").hide();
4530
+
4531
+ jQuery("#mec_do_transaction_paypal_express_message" + cart_id).addClass("mec-success").html(data.message).show();
4532
+ }
4533
+ else if(data.success == 0)
4534
+ {
4535
+ // Remove the loading Class from the button
4536
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id + " button[type=submit]").removeClass("loading");
4537
+
4538
+ jQuery("#mec_do_transaction_paypal_express_message" + cart_id).addClass("mec-error").html(data.message).show();
4539
+ }
4540
+ else
4541
+ {
4542
+ setTimeout(function()
4543
+ {
4544
+ mec_paypal_express_pay_checker(cart_id)
4545
+ }, 10000);
4546
+ }
4547
+ },
4548
+ error: function(jqXHR, textStatus, errorThrown)
4549
+ {
4550
+ // Remove the loading Class from the button
4551
+ jQuery("#mec_do_transaction_paypal_express_form" + cart_id + " button[type=submit]").removeClass("loading");
4552
+ }
4553
+ });
4554
+ }
4555
+ </script>
4556
+ <div class="mec-gateway-message mec-util-hidden" id="mec_do_transaction_paypal_express_message<?php echo $cart_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
4557
+ <form id="mec_do_transaction_paypal_express_form<?php echo $cart_id; ?>" class="mec-click-pay" action="<?php echo $this->get_api_url(); ?>" method="post" target="_blank" onsubmit="mec_paypal_express_pay_checker('<?php echo $cart_id; ?>');">
4558
+ <input type="hidden" name="cmd" value="_xclick"/>
4559
+ <input type="hidden" name="rm" value="2"/>
4560
+ <input type="hidden" name="business" value="<?php echo(isset($options['account']) ? $options['account'] : null); ?>"/>
4561
+ <input type="hidden" name="item_name" value="<?php echo esc_attr(get_the_title($event_id)); ?>"/>
4562
+ <input type="hidden" name="item_number" value="<?php echo $transactions_count; ?>"/>
4563
+ <input type="hidden" name="amount" value="<?php echo $c->get_payable($cart); ?>"/>
4564
+ <input type="hidden" name="currency_code" value="<?php echo $this->main->get_currency_code(); ?>"/>
4565
+ <input type="hidden" name="cancel_return" value="<?php echo $this->get_cancel_url($event_id); ?>"/>
4566
+ <input type="hidden" name="notify_url" value="<?php echo $this->cart_get_notify_url(); ?>"/>
4567
+ <input type="hidden" name="return" value="<?php echo $this->get_return_url($event_id); ?>"/>
4568
+ <input type="hidden" name="custom" value="<?php echo base64_encode(json_encode(array('cart_id' => $cart_id))); ?>"/>
4569
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
4570
+ </form>
4571
+ <?php
4572
+ }
4573
+
4574
+ public function cart_get_notify_url()
4575
+ {
4576
+ return $this->main->URL('mec') . 'app/features/gateways/paypal_ipn_cart.php';
4577
+ }
4578
+
4579
+ public function cart_validate_express_payment($vars)
4580
+ {
4581
+ // Check if Paypal is disabled
4582
+ if(!$this->enabled()) return false;
4583
+
4584
+ $custom = $this->decode_custom($vars['custom']);
4585
+ $cart_id = $custom['cart_id'];
4586
+
4587
+ // Cart Library
4588
+ $c = $this->getCart();
4589
+ $cart = $c->get_cart($cart_id);
4590
+
4591
+ $payable = $c->get_payable($cart);
4592
+
4593
+ $request_str = $this->get_request_string($vars) . '&cmd=_notify-validate';
4594
+ $response_str = $this->get_paypal_response($request_str, $this->get_api_url());
4595
+
4596
+ // $this->main->debug_log(current_time('Y-m-d H:i:s').' => ('.$response_str.') => '.print_r($vars, true));
4597
+
4598
+ if(strpos($response_str, 'VERIFIED') !== false) $status = 1;
4599
+ else $status = 0;
4600
+
4601
+ $amount = $vars['mc_gross'];
4602
+
4603
+ // Compare paid amount with transaction amount
4604
+ $valid = ($amount >= $payable and $status) ? true : false;
4605
+ if($valid)
4606
+ {
4607
+ foreach($cart as $transaction_id)
4608
+ {
4609
+ // Mark as done
4610
+ $transaction['done'] = 1;
4611
+
4612
+ // Save Gateway Transaction ID
4613
+ $transaction['gateway_transaction_id'] = (isset($vars['txn_id']) and trim($vars['txn_id'])) ? $vars['txn_id'] : '';
4614
+
4615
+ $this->book->update_transaction($transaction_id, $transaction);
4616
+ }
4617
+
4618
+ $this->cart_do_transaction($cart_id);
4619
+
4620
+ return true;
4621
+ }
4622
+ else
4623
+ {
4624
+ // Mark as not done
4625
+ foreach($cart as $transaction_id)
4626
+ {
4627
+ $transaction['done'] = 0;
4628
+ $this->book->update_transaction($transaction_id, $transaction);
4629
+ }
4630
+
4631
+ return false;
4632
+ }
4633
+ }
4634
+
4635
+ public function cart_pre_validation()
4636
+ {
4637
+ $cart_id = (isset($_GET['cart_id']) ? sanitize_text_field($_GET['cart_id']) : 0);
4638
+
4639
+ // Validate Ticket Availability
4640
+ $this->cart_validate($cart_id);
4641
+
4642
+ $this->response(array('success' => 1, 'message' => __('Ready to checkout.', 'modern-events-calendar-lite')));
4643
+ }
4644
+
4645
+ public function cart_do_transaction($cart_id)
4646
+ {
4647
+ // Cart Library
4648
+ $c = $this->getCart();
4649
+
4650
+ $cart = $c->get_cart($cart_id);
4651
+ foreach($cart as $transaction_id) $this->do_transaction($transaction_id);
4652
+
4653
+ // Empty Cart
4654
+ $c->clear($cart_id);
4655
+ }
4656
+
4657
+ public function cart_check_transaction()
4658
+ {
4659
+ $cart_id = isset($_GET['cart_id']) ? sanitize_text_field($_GET['cart_id']) : 0;
4660
+ $transaction = array();
4661
+
4662
+ // Cart Library
4663
+ $c = $this->getCart();
4664
+
4665
+ $cart = $c->get_cart($cart_id);
4666
+ foreach($cart as $transaction_id)
4667
+ {
4668
+ $transaction = $this->book->get_transaction($transaction_id);
4669
+ break;
4670
+ }
4671
+
4672
+ $success = 2;
4673
+ $message = __('Waiting for a response from gateway.', 'modern-events-calendar-lite');
4674
+ $data = array();
4675
+
4676
+ if(isset($transaction['done']) and $transaction['done'] == 1)
4677
+ {
4678
+ $success = 1;
4679
+ $message = stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite')));
4680
+ }
4681
+ elseif(isset($transaction['done']) and $transaction['done'] == 0)
4682
+ {
4683
+ $success = 0;
4684
+ $message = __('Payment invalid! Booking failed.', 'modern-events-calendar-lite');
4685
+ }
4686
+
4687
+ $this->response(array(
4688
+ 'success' => $success,
4689
+ 'message' => $message,
4690
+ 'data' => $data,
4691
+ ));
4692
+ }
4693
+ }
4694
+
4695
+ class MEC_gateway_paypal_credit_card extends MEC_gateway
4696
+ {
4697
+ public $id = 3;
4698
+ public $options;
4699
+
4700
+ public function __construct()
4701
+ {
4702
+ parent::__construct();
4703
+
4704
+ // Gateway options
4705
+ $this->options = $this->options();
4706
+
4707
+ // Register actions
4708
+ $this->factory->action('wp_ajax_mec_do_transaction_paypal_credit_card', array($this, 'do_transaction'));
4709
+ $this->factory->action('wp_ajax_nopriv_mec_do_transaction_paypal_credit_card', array($this, 'do_transaction'));
4710
+
4711
+ $this->factory->action('wp_ajax_mec_cart_do_transaction_paypal_credit_card', array($this, 'cart_do_transaction'));
4712
+ $this->factory->action('wp_ajax_nopriv_mec_cart_do_transaction_paypal_credit_card', array($this, 'cart_do_transaction'));
4713
+ }
4714
+
4715
+ public function label()
4716
+ {
4717
+ return __('PayPal Credit Card', 'modern-events-calendar-lite');
4718
+ }
4719
+
4720
+ public function color()
4721
+ {
4722
+ return '#0aafff';
4723
+ }
4724
+
4725
+ public function get_api_url()
4726
+ {
4727
+ $live = 'https://api-3t.paypal.com/nvp';
4728
+ $sandbox = 'https://api-3t.sandbox.paypal.com/nvp';
4729
+
4730
+ if ($this->options['mode'] == 'live') {
4731
+ $url = $live;
4732
+ } else {
4733
+ $url = $sandbox;
4734
+ }
4735
+
4736
+ return $url;
4737
+ }
4738
+
4739
+ public function op_enabled()
4740
+ {
4741
+ return true;
4742
+ }
4743
+
4744
+ public function op_form($options = array())
4745
+ {
4746
+ $last_error = get_option('mec_paypal_cc_error', NULL);
4747
+ ?>
4748
+ <h4><?php echo $this->label(); ?></h4>
4749
+ <div class="mec-gateway-options-form">
4750
+ <div class="mec-form-row">
4751
+ <label class="mec-col-3" for="mec_op<?php echo $this->id(); ?>_api_username"><?php _e('API Username', 'modern-events-calendar-lite'); ?></label>
4752
+ <div class="mec-col-9">
4753
+ <input type="text" id="mec_op<?php echo $this->id(); ?>_api_username" name="mec[op][<?php echo $this->id(); ?>][api_username]" value="<?php echo isset($options['api_username']) ? $options['api_username'] : ''; ?>" />
4754
+ </div>
4755
+ </div>
4756
+ <div class="mec-form-row">
4757
+ <label class="mec-col-3" for="mec_op<?php echo $this->id(); ?>_api_password"><?php _e('API Password', 'modern-events-calendar-lite'); ?></label>
4758
+ <div class="mec-col-9">
4759
+ <input type="text" id="mec_op<?php echo $this->id(); ?>_api_password" name="mec[op][<?php echo $this->id(); ?>][api_password]" value="<?php echo isset($options['api_password']) ? $options['api_password'] : ''; ?>" />
4760
+ </div>
4761
+ </div>
4762
+ <div class="mec-form-row">
4763
+ <label class="mec-col-3" for="mec_op<?php echo $this->id(); ?>_api_signature"><?php _e('API Signature', 'modern-events-calendar-lite'); ?></label>
4764
+ <div class="mec-col-9">
4765
+ <input type="text" id="mec_op<?php echo $this->id(); ?>_api_signature" name="mec[op][<?php echo $this->id(); ?>][api_signature]" value="<?php echo isset($options['api_signature']) ? $options['api_signature'] : ''; ?>" />
4766
+ </div>
4767
+ </div>
4768
+ </div>
4769
+ <?php
4770
+ }
4771
+
4772
+ public function options_form()
4773
+ {
4774
+ $last_error = get_option('mec_paypal_cc_error', NULL);
4775
+ ?>
4776
+ <div class="mec-form-row mec-click-pay">
4777
+ <label>
4778
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][status]" value="0"/>
4779
+ <input onchange="jQuery('#mec_gateways<?php echo $this->id(); ?>_container_toggle').toggle();" value="1"
4780
+ type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][status]"
4781
+ <?php
4782
+ if (isset($this->options['status']) and $this->options['status']) {
4783
+ echo 'checked="checked"';
4784
+ }
4785
+ ?>
4786
+ /> <?php _e('PayPal Credit Card', 'modern-events-calendar-lite'); ?>
4787
+ </label>
4788
+ </div>
4789
+ <div id="mec_gateways<?php echo $this->id(); ?>_container_toggle" class="mec-gateway-options-form <?php
4790
+ if ((isset($this->options['status']) and !$this->options['status']) or !isset($this->options['status'])) {
4791
+ echo 'mec-util-hidden';
4792
+ }
4793
+ ?>">
4794
+ <?php if($last_error): ?>
4795
+ <div class="warning-msg">
4796
+ <p><?php esc_html_e("Below error is the latest error received from Paypal during the payment in frontend so it's not related to the configuration form. It might help you to find some misconfiguration on your Paypal account or inserted credentials.", 'modern-events-calendar-lite'); ?></p>
4797
+ <?php echo $last_error; ?>
4798
+ </div>
4799
+ <?php endif; ?>
4800
+ <div class="mec-form-row">
4801
+ <label class="mec-col-3"
4802
+ for="mec_gateways<?php echo $this->id(); ?>_title"><?php _e('Title', 'modern-events-calendar-lite'); ?></label>
4803
+ <div class="mec-col-9">
4804
+ <input type="text" id="mec_gateways<?php echo $this->id(); ?>_title"
4805
+ name="mec[gateways][<?php echo $this->id(); ?>][title]"
4806
+ value="<?php echo (isset($this->options['title']) and trim($this->options['title'])) ? $this->options['title'] : ''; ?>"
4807
+ placeholder="<?php echo $this->label(); ?>"/>
4808
+ </div>
4809
+ </div>
4810
+ <div class="mec-form-row">
4811
+ <label class="mec-col-3"
4812
+ for="mec_gateways<?php echo $this->id(); ?>_comment"><?php _e('Comment', 'modern-events-calendar-lite'); ?></label>
4813
+ <div class="mec-col-9">
4814
+ <textarea id="mec_gateways<?php echo $this->id(); ?>_comment"
4815
+ name="mec[gateways][<?php echo $this->id(); ?>][comment]"><?php echo (isset($this->options['comment']) and trim($this->options['comment'])) ? stripslashes($this->options['comment']) : esc_html__('Paypal Credit Card Description', 'modern-events-calendar-lite'); ?></textarea>
4816
+ <span class="mec-tooltip">
4817
+ <div class="box left">
4818
+ <h5 class="title"><?php _e('Comment', 'modern-events-calendar-lite'); ?></h5>
4819
+ <div class="content"><p><?php esc_attr_e('HTML allowed.', 'modern-events-calendar-lite'); ?><a
4820
+ href="https://webnus.net/dox/modern-events-calendar/booking/"
4821
+ target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
4822
+ </div>
4823
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
4824
+ </span>
4825
+ </div>
4826
+ </div>
4827
+ <div class="mec-form-row">
4828
+ <label class="mec-col-3"
4829
+ for="mec_gateways<?php echo $this->id(); ?>_api_username"><?php _e('API Username', 'modern-events-calendar-lite'); ?></label>
4830
+ <div class="mec-col-9">
4831
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_api_username"
4832
+ name="mec[gateways][<?php echo $this->id(); ?>][api_username]"
4833
+ value="<?php echo isset($this->options['api_username']) ? $this->options['api_username'] : ''; ?>"/>
4834
+ </div>
4835
+ </div>
4836
+ <div class="mec-form-row">
4837
+ <label class="mec-col-3"
4838
+ for="mec_gateways<?php echo $this->id(); ?>_api_password"><?php _e('API Password', 'modern-events-calendar-lite'); ?></label>
4839
+ <div class="mec-col-9">
4840
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_api_password"
4841
+ name="mec[gateways][<?php echo $this->id(); ?>][api_password]"
4842
+ value="<?php echo isset($this->options['api_password']) ? $this->options['api_password'] : ''; ?>"/>
4843
+ </div>
4844
+ </div>
4845
+ <div class="mec-form-row">
4846
+ <label class="mec-col-3"
4847
+ for="mec_gateways<?php echo $this->id(); ?>_api_signature"><?php _e('API Signature', 'modern-events-calendar-lite'); ?></label>
4848
+ <div class="mec-col-9">
4849
+ <input class="mec-required" type="text" id="mec_gateways<?php echo $this->id(); ?>_api_signature"
4850
+ name="mec[gateways][<?php echo $this->id(); ?>][api_signature]"
4851
+ value="<?php echo isset($this->options['api_signature']) ? $this->options['api_signature'] : ''; ?>"/>
4852
+ </div>
4853
+ </div>
4854
+ <div class="mec-form-row">
4855
+ <label class="mec-col-3"
4856
+ for="mec_gateways<?php echo $this->id(); ?>_mode"><?php _e('Mode', 'modern-events-calendar-lite'); ?></label>
4857
+ <div class="mec-col-9">
4858
+ <select id="mec_gateways<?php echo $this->id(); ?>_mode"
4859
+ name="mec[gateways][<?php echo $this->id(); ?>][mode]">
4860
+ <option value="live" <?php echo (isset($this->options['mode']) and $this->options['mode'] == 'live') ? 'selected="selected"' : ''; ?>><?php _e('Live', 'modern-events-calendar-lite'); ?></option>
4861
+ <option value="sandbox" <?php echo (isset($this->options['mode']) and $this->options['mode'] == 'sandbox') ? 'selected="selected"' : ''; ?>><?php _e('Sandbox', 'modern-events-calendar-lite'); ?></option>
4862
+ </select>
4863
+ </div>
4864
+ </div>
4865
+ <div class="mec-form-row">
4866
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_index"><?php _e('Position', 'modern-events-calendar-lite'); ?></label>
4867
+ <div class="mec-col-9">
4868
+ <input type="number" min="0" step="1" id="mec_gateways<?php echo $this->id(); ?>_index"
4869
+ name="mec[gateways][<?php echo $this->id(); ?>][index]"
4870
+ value="<?php echo (isset($this->options['index']) and trim($this->options['index'])) ? $this->options['index'] : 3; ?>"
4871
+ placeholder="<?php echo esc_attr__('Position', 'modern-events-calendar-lite'); ?>"/>
4872
+ </div>
4873
+ </div>
4874
+ </div>
4875
+ <?php
4876
+ }
4877
+
4878
+ public function checkout_form($transaction_id, $params = array())
4879
+ {
4880
+ $transaction = $this->book->get_transaction($transaction_id);
4881
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
4882
+ ?>
4883
+ <script type="text/javascript">
4884
+ function mec_paypal_credit_card_send_request(transaction_id) {
4885
+ // Add loading Class to the button
4886
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + transaction_id + " button[type=submit]").addClass("loading");
4887
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + transaction_id).removeClass("mec-success mec-error").hide();
4888
+
4889
+ var data = jQuery("#mec_do_transaction_paypal_credit_card_form" + transaction_id).serialize();
4890
+ jQuery.ajax(
4891
+ {
4892
+ type: "GET",
4893
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
4894
+ data: data,
4895
+ dataType: "JSON",
4896
+ success: function (data) {
4897
+ if (data.success == 1) {
4898
+ // Remove the loading Class from the button
4899
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + transaction_id + " button[type=submit]").removeClass("loading");
4900
+
4901
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + transaction_id).hide();
4902
+ jQuery(".mec-book-form-gateway-label").remove();
4903
+ jQuery(".mec-book-form-coupon").hide();
4904
+ jQuery(".mec-gateway-comment").hide();
4905
+
4906
+ jQuery("#mec-book-form-back-btn-step-3").remove();
4907
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + transaction_id).addClass("mec-success").html(data.message).show();
4908
+
4909
+ // Show Invoice Link
4910
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
4911
+ {
4912
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + transaction_id).append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
4913
+ }
4914
+
4915
+ // Show Downloadable Link
4916
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
4917
+ {
4918
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + transaction_id).append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
4919
+ }
4920
+
4921
+ // Show Extra info
4922
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
4923
+ {
4924
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + transaction_id).append('<div>' + data.data.extra_info+'</div>');
4925
+ }
4926
+
4927
+ // Redirect to thank you page
4928
+ if (typeof data.data.redirect_to != "undefined" && data.data.redirect_to != "") {
4929
+ setTimeout(function () {
4930
+ window.location.href = data.data.redirect_to;
4931
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
4932
+ }
4933
+ }
4934
+ else {
4935
+ // Remove the loading Class from the button
4936
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + transaction_id + " button[type=submit]").removeClass("loading");
4937
+
4938
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + transaction_id).addClass("mec-error").html(data.message).show();
4939
+ }
4940
+ },
4941
+ error: function (jqXHR, textStatus, errorThrown) {
4942
+ // Remove the loading Class from the button
4943
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + transaction_id + " button[type=submit]").removeClass("loading");
4944
+ }
4945
+ });
4946
+ }
4947
+ </script>
4948
+ <style>.nice-select{-webkit-tap-highlight-color:transparent;background-color:#fff;border-radius:5px;border:solid 1px #e8e8e8;box-sizing:border-box;clear:both;cursor:pointer;display:block;float:left;font-family:inherit;font-size:14px;font-weight:400;height:42px;line-height:40px;outline:0;padding-left:18px;padding-right:30px;position:relative;text-align:left!important;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;width:auto}.nice-select:hover{border-color:#dbdbdb}.nice-select.open,.nice-select:active,.nice-select:focus{border-color:#999}.nice-select:after{border-bottom:2px solid #999;border-right:2px solid #999;content:'';display:block;height:5px;margin-top:-4px;pointer-events:none;position:absolute;right:12px;top:50%;-webkit-transform-origin:66% 66%;-ms-transform-origin:66% 66%;transform-origin:66% 66%;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg);-webkit-transition:all .15s ease-in-out;transition:all .15s ease-in-out;width:5px}.nice-select.open:after{-webkit-transform:rotate(-135deg);-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.nice-select.open .list{opacity:1;pointer-events:auto;-webkit-transform:scale(1) translateY(0);-ms-transform:scale(1) translateY(0);transform:scale(1) translateY(0)}.nice-select.disabled{border-color:#ededed;color:#999;pointer-events:none}.nice-select.disabled:after{border-color:#ccc}.nice-select.wide{width:100%}.nice-select.wide .list{left:0!important;right:0!important}.nice-select.right{float:right}.nice-select.right .list{left:auto;right:0}.nice-select.small{font-size:12px;height:36px;line-height:34px}.nice-select.small:after{height:4px;width:4px}.nice-select.small .option{line-height:34px;min-height:34px}.nice-select .list{background-color:#fff;border-radius:5px;box-shadow:0 0 0 1px rgba(68,68,68,.11);box-sizing:border-box;margin-top:4px;opacity:0;overflow:hidden;padding:0;pointer-events:none;position:absolute;top:100%;left:0;-webkit-transform-origin:50% 0;-ms-transform-origin:50% 0;transform-origin:50% 0;-webkit-transform:scale(.75) translateY(-21px);-ms-transform:scale(.75) translateY(-21px);transform:scale(.75) translateY(-21px);-webkit-transition:all .2s cubic-bezier(.5,0,0,1.25),opacity .15s ease-out;transition:all .2s cubic-bezier(.5,0,0,1.25),opacity .15s ease-out;z-index:9}.nice-select .list:hover .option:not(:hover){background-color:transparent!important}.nice-select .option{cursor:pointer;font-weight:400;line-height:40px;list-style:none;min-height:40px;outline:0;padding-left:18px;padding-right:29px;text-align:left;-webkit-transition:all .2s;transition:all .2s}.nice-select .option.focus,.nice-select .option.selected.focus,.nice-select .option:hover{background-color:#f6f6f6}.nice-select .option.selected{font-weight:700}.nice-select .option.disabled{background-color:transparent;color:#999;cursor:default}.no-csspointerevents .nice-select .list{display:none}.no-csspointerevents .nice-select.open .list{display:block}</style>
4949
+ <script type="text/javascript" src="<?php echo $this->main->asset('js/jquery.nice-select.min.js'); ?>"></script>
4950
+ <script>
4951
+ jQuery(document).ready(function () {
4952
+ if (jQuery('.mec-booking-shortcode').length < 0) {
4953
+ return;
4954
+ }
4955
+ // Events
4956
+ jQuery('.mec-booking-shortcode').find('select').niceSelect();
4957
+
4958
+ });
4959
+ </script>
4960
+ <div class="mec-gateway-message mec-util-hidden"
4961
+ id="mec_do_transaction_paypal_credit_card_message<?php echo $transaction_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
4962
+ <form id="mec_do_transaction_paypal_credit_card_form<?php echo $transaction_id; ?>"
4963
+ onsubmit="mec_paypal_credit_card_send_request('<?php echo $transaction_id; ?>'); return false;">
4964
+ <div class="mec-form-row mec-paypal-credit-card-first-name">
4965
+ <label for="mec_paypal_credit_card_first_name"><?php echo __('First name', 'modern-events-calendar-lite'); ?></label>
4966
+ <input type="text" name="first_name" id="mec_paypal_credit_card_first_name"/>
4967
+ </div>
4968
+ <div class="mec-form-row mec-paypal-credit-card-last-name">
4969
+ <label for="mec_paypal_credit_card_last_name"><?php echo __('Last name', 'modern-events-calendar-lite'); ?></label>
4970
+ <input type="text" name="last_name" id="mec_paypal_credit_card_last_name"/>
4971
+ </div>
4972
+ <div class="mec-form-row mec-paypal-credit-card-card-type">
4973
+ <label for="mec_paypal_credit_card_card_type"><?php echo __('Card Type', 'modern-events-calendar-lite'); ?></label>
4974
+ <select name="card_type" id="mec_paypal_credit_card_card_type">
4975
+ <option value="Visa"><?php echo __('Visa', 'modern-events-calendar-lite'); ?></option>
4976
+ <option value="MasterCard"><?php echo __('MasterCard', 'modern-events-calendar-lite'); ?></option>
4977
+ <option value="Discover"><?php echo __('Discover', 'modern-events-calendar-lite'); ?></option>
4978
+ <option value="Amex"><?php echo __('American Express', 'modern-events-calendar-lite'); ?></option>
4979
+ </select>
4980
+ </div>
4981
+ <div class="mec-form-row mec-paypal-credit-card-cc-number">
4982
+ <label for="mec_paypal_credit_card_cc_number"><?php echo __('CC Number', 'modern-events-calendar-lite'); ?></label>
4983
+ <input type="text" name="cc_number" id="mec_paypal_credit_card_cc_number"/>
4984
+ </div>
4985
+ <div class="mec-form-row mec-paypal-credit-card-expiration-date-month">
4986
+ <label for="mec_paypal_credit_card_expiration_date_month"><?php echo __('Expiration Date', 'modern-events-calendar-lite'); ?></label>
4987
+ <select name="expiration_date_month" id="mec_paypal_credit_card_expiration_date_month">
4988
+ <?php foreach (array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12') as $month) : ?>
4989
+ <option value="<?php echo $month; ?>"><?php echo $month; ?></option>
4990
+ <?php endforeach; ?>
4991
+ </select>
4992
+ <select name="expiration_date_year" id="mec_paypal_credit_card_expiration_date_year">
4993
+ <?php
4994
+ for ($i = 0; $i <= 10;
4995
+ $i++) :
4996
+ $y = date('Y', strtotime('+' . $i . ' years'));
4997
+ ?>
4998
+ <option value="<?php echo $y; ?>"><?php echo $y; ?></option>
4999
+ <?php endfor; ?>
5000
+ </select>
5001
+ </div>
5002
+ <div class="mec-form-row mec-paypal-credit-card-cvv2">
5003
+ <label for="mec_paypal_credit_card_cvv2"><?php echo __('CVV2', 'modern-events-calendar-lite'); ?></label>
5004
+ <input type="text" name="cvv2" id="mec_paypal_credit_card_cvv2"/>
5005
+ </div>
5006
+ <div class="mec-form-row mec-click-pay">
5007
+ <input type="hidden" name="action" value="mec_do_transaction_paypal_credit_card"/>
5008
+ <input type="hidden" name="transaction_id" value="<?php echo $transaction_id; ?>"/>
5009
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
5010
+ <?php wp_nonce_field('mec_transaction_form_' . $transaction_id); ?>
5011
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
5012
+ </div>
5013
+ </form>
5014
+ <?php
5015
+ }
5016
+
5017
+ public function do_transaction($transaction_id = null)
5018
+ {
5019
+ if(!trim($transaction_id)) $transaction_id = isset($_GET['transaction_id']) ? sanitize_text_field($_GET['transaction_id']) : 0;
5020
+
5021
+ // Verify that the nonce is valid.
5022
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_transaction_form_' . $transaction_id))
5023
+ {
5024
+ $this->response(array(
5025
+ 'success' => 0,
5026
+ 'code' => 'NONCE_IS_INVALID',
5027
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
5028
+ ));
5029
+ }
5030
+
5031
+ // Validate Ticket Availability
5032
+ $this->validate($transaction_id);
5033
+
5034
+ $transaction = $this->book->get_transaction($transaction_id);
5035
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
5036
+
5037
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
5038
+ $attention_times = explode(':', $attention_date);
5039
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
5040
+
5041
+ // Is there any attendee?
5042
+ if (!count($attendees)) {
5043
+ $this->response(
5044
+ array(
5045
+ 'success' => 0,
5046
+ 'code' => 'NO_TICKET',
5047
+ 'message' => __(
5048
+ 'There is no attendee for booking!',
5049
+ 'mec'
5050
+ ),
5051
+ )
5052
+ );
5053
+ }
5054
+
5055
+ $validate = $this->validate_paypal($_GET);
5056
+ if(!$validate)
5057
+ {
5058
+ $this->response(
5059
+ array(
5060
+ 'success' => 0,
5061
+ 'code' => 'PAYMENT_IS_INVALID',
5062
+ 'message' => __(
5063
+ 'Payment is invalid.',
5064
+ 'mec'
5065
+ ),
5066
+ )
5067
+ );
5068
+ }
5069
+
5070
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
5071
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
5072
+
5073
+ $ticket_ids = '';
5074
+ $attendees_info = array();
5075
+
5076
+ foreach($attendees as $i => $attendee)
5077
+ {
5078
+ if(!is_numeric($i)) continue;
5079
+
5080
+ $ticket_ids .= $attendee['id'] . ',';
5081
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
5082
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
5083
+ }
5084
+
5085
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
5086
+ $user_id = $this->register_user($main_attendee, $transaction);
5087
+
5088
+ // Remove Sensitive Data
5089
+ if(isset($transaction['username']) or isset($transaction['password']))
5090
+ {
5091
+ unset($transaction['username']);
5092
+ unset($transaction['password']);
5093
+
5094
+ $this->book->update_transaction($transaction_id, $transaction);
5095
+ }
5096
+
5097
+ // MEC User
5098
+ $u = $this->getUser();
5099
+
5100
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
5101
+ $book_id = $this->book->add(
5102
+ array(
5103
+ 'post_author' => $user_id,
5104
+ 'post_type' => $this->PT,
5105
+ 'post_title' => $book_subject,
5106
+ 'post_date' => $date,
5107
+ 'attendees_info' => $attendees_info,
5108
+ 'mec_attendees' => $attendees,
5109
+ 'mec_gateway' => 'MEC_gateway_paypal_credit_card',
5110
+ 'mec_gateway_label' => $this->title()
5111
+ ),
5112
+ $transaction_id,
5113
+ $ticket_ids
5114
+ );
5115
+
5116
+ // Assign User
5117
+ $u->assign($book_id, $user_id);
5118
+
5119
+ // Fires after completely creating a new booking
5120
+ do_action('mec_booking_completed', $book_id);
5121
+
5122
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
5123
+ $redirect_to = '';
5124
+
5125
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
5126
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
5127
+
5128
+ // Invoice Link
5129
+ $mec_confirmed = get_post_meta($book_id, 'mec_confirmed', true);
5130
+ $invoice_link = (!$mec_confirmed) ? '' : $this->book->get_invoice_link($transaction_id);
5131
+ $dl_file_link = (!$mec_confirmed) ? '' : $this->book->get_dl_file_link($book_id);
5132
+
5133
+ $extra_info = apply_filters('MEC_extra_info_gateways', '', $this->book->get_event_id_by_transaction_id($transaction_id), $book_id);
5134
+
5135
+ $this->response(
5136
+ array(
5137
+ 'success' => 1,
5138
+ 'message' => stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite'))),
5139
+ 'data' => array(
5140
+ 'book_id' => $book_id,
5141
+ 'redirect_to' => $redirect_to,
5142
+ 'invoice_link' => $invoice_link,
5143
+ 'dl_file_link' => $dl_file_link,
5144
+ 'extra_info' => $extra_info,
5145
+ ),
5146
+ )
5147
+ );
5148
+ }
5149
+
5150
+ public function validate_paypal($vars = array())
5151
+ {
5152
+ $card_type = (isset($vars['card_type']) ? sanitize_text_field($vars['card_type']) : null);
5153
+ $cc_number = (isset($vars['cc_number']) ? sanitize_text_field($vars['cc_number']) : null);
5154
+ $cvv2 = (isset($vars['cvv2']) ? sanitize_text_field($vars['cvv2']) : null);
5155
+ $first_name = (isset($vars['first_name']) ? sanitize_text_field($vars['first_name']) : null);
5156
+ $last_name = (isset($vars['last_name']) ? sanitize_text_field($vars['last_name']) : null);
5157
+ $exp_date_month = (isset($vars['expiration_date_month']) ? sanitize_text_field($vars['expiration_date_month']) : null);
5158
+ $exp_date_year = (isset($vars['expiration_date_year']) ? sanitize_text_field($vars['expiration_date_year']) : null);
5159
+
5160
+ // Check Card details
5161
+ if(!$card_type or !$cc_number or !$cvv2) return false;
5162
+
5163
+ $transaction_id = isset($vars['transaction_id']) ? sanitize_text_field($vars['transaction_id']) : 0;
5164
+
5165
+ // Get Options Compatible with Organizer Payment
5166
+ $options = $this->options($transaction_id);
5167
+
5168
+ $transaction = $this->book->get_transaction($transaction_id);
5169
+ $event_id = isset($transaction['event_id']) ? $transaction['event_id'] : 0;
5170
+
5171
+ $expdate = $exp_date_month . $exp_date_year;
5172
+ $params = array(
5173
+ 'METHOD' => 'DoDirectPayment',
5174
+ 'USER' => (isset($options['api_username']) ? $options['api_username'] : null),
5175
+ 'PWD' => (isset($options['api_password']) ? $options['api_password'] : null),
5176
+ 'SIGNATURE' => (isset($options['api_signature']) ? $options['api_signature'] : null),
5177
+ 'VERSION' => 90.0,
5178
+ 'CREDITCARDTYPE' => $card_type,
5179
+ 'ACCT' => $cc_number,
5180
+ 'EXPDATE' => $expdate,
5181
+ 'CVV2' => $cvv2,
5182
+ 'FIRSTNAME' => $first_name,
5183
+ 'LASTNAME' => $last_name,
5184
+ 'AMT' => (isset($transaction['price']) ? $transaction['price'] : 0),
5185
+ 'CURRENCYCODE' => $this->main->get_currency_code($event_id),
5186
+ 'DESC' => get_the_title($event_id),
5187
+ );
5188
+
5189
+ $request_str = $this->get_request_string($params);
5190
+ $response_str = $this->get_paypal_response($request_str, $this->get_api_url());
5191
+
5192
+ $results = $this->normalize_NVP($response_str);
5193
+
5194
+ $status = strpos(strtolower($results['ACK']), 'success') !== false ? 1 : 0;
5195
+ $amount = isset($results['AMT']) ? $results['AMT'] : 0;
5196
+
5197
+ // Save Transaction ID
5198
+ if($status)
5199
+ {
5200
+ $gateway_transaction_id = isset($results['TRANSACTIONID']) ? $results['TRANSACTIONID'] : '';
5201
+ if($gateway_transaction_id)
5202
+ {
5203
+ $transaction['gateway_transaction_id'] = $gateway_transaction_id;
5204
+ $this->book->update_transaction($transaction_id, $transaction);
5205
+ }
5206
+ }
5207
+
5208
+ // Error
5209
+ if(!$status)
5210
+ {
5211
+ $error = (isset($results['L_ERRORCODE0']) ? '('.$results['L_ERRORCODE0'].') ' : '').(isset($results['L_LONGMESSAGE0']) ? $results['L_LONGMESSAGE0'] : '');
5212
+
5213
+ // Log it
5214
+ trigger_error($error, E_USER_NOTICE);
5215
+
5216
+ // Save it
5217
+ update_option('mec_paypal_cc_error', current_time('Y-m-d H:i:s').': '.$error, false);
5218
+ }
5219
+
5220
+ // Compare paid amount with transaction amount
5221
+ return ($amount >= $transaction['price'] and $status) ? true : false;
5222
+ }
5223
+
5224
+ public function normalize_NVP($nvp_string)
5225
+ {
5226
+ $Array = array();
5227
+ while (strlen($nvp_string)) {
5228
+ // name
5229
+ $keypos = strpos($nvp_string, '=');
5230
+ $keyval = substr($nvp_string, 0, $keypos);
5231
+
5232
+ // value
5233
+ $valuepos = strpos($nvp_string, '&') ? strpos($nvp_string, '&') : strlen($nvp_string);
5234
+ $valval = substr($nvp_string, $keypos + 1, $valuepos - $keypos - 1);
5235
+
5236
+ // decoding the respose
5237
+ $Array[$keyval] = urldecode($valval);
5238
+ $nvp_string = substr($nvp_string, $valuepos + 1, strlen($nvp_string));
5239
+ }
5240
+
5241
+ return $Array;
5242
+ }
5243
+
5244
+ public function cart_checkout_form($cart_id, $params = array())
5245
+ {
5246
+ ?>
5247
+ <div class="mec-gateway-message mec-util-hidden"
5248
+ id="mec_do_transaction_paypal_credit_card_message<?php echo $cart_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
5249
+ <form id="mec_do_transaction_paypal_credit_card_form<?php echo $cart_id; ?>"
5250
+ onsubmit="mec_paypal_credit_card_send_request('<?php echo $cart_id; ?>'); return false;">
5251
+ <div class="mec-form-row mec-paypal-credit-card-first-name">
5252
+ <label for="mec_paypal_credit_card_first_name"><?php echo __('First name', 'modern-events-calendar-lite'); ?></label>
5253
+ <input type="text" name="first_name" id="mec_paypal_credit_card_first_name"/>
5254
+ </div>
5255
+ <div class="mec-form-row mec-paypal-credit-card-last-name">
5256
+ <label for="mec_paypal_credit_card_last_name"><?php echo __('Last name', 'modern-events-calendar-lite'); ?></label>
5257
+ <input type="text" name="last_name" id="mec_paypal_credit_card_last_name"/>
5258
+ </div>
5259
+ <div class="mec-form-row mec-paypal-credit-card-card-type">
5260
+ <label for="mec_paypal_credit_card_card_type"><?php echo __('Card Type', 'modern-events-calendar-lite'); ?></label>
5261
+ <select name="card_type" id="mec_paypal_credit_card_card_type">
5262
+ <option value="Visa"><?php echo __('Visa', 'modern-events-calendar-lite'); ?></option>
5263
+ <option value="MasterCard"><?php echo __('MasterCard', 'modern-events-calendar-lite'); ?></option>
5264
+ <option value="Discover"><?php echo __('Discover', 'modern-events-calendar-lite'); ?></option>
5265
+ <option value="Amex"><?php echo __('American Express', 'modern-events-calendar-lite'); ?></option>
5266
+ </select>
5267
+ </div>
5268
+ <div class="mec-form-row mec-paypal-credit-card-cc-number">
5269
+ <label for="mec_paypal_credit_card_cc_number"><?php echo __('CC Number', 'modern-events-calendar-lite'); ?></label>
5270
+ <input type="text" name="cc_number" id="mec_paypal_credit_card_cc_number"/>
5271
+ </div>
5272
+ <div class="mec-form-row mec-paypal-credit-card-expiration-date-month">
5273
+ <label for="mec_paypal_credit_card_expiration_date_month"><?php echo __('Expiration Date', 'modern-events-calendar-lite'); ?></label>
5274
+ <select name="expiration_date_month" id="mec_paypal_credit_card_expiration_date_month">
5275
+ <?php foreach (array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12') as $month) : ?>
5276
+ <option value="<?php echo $month; ?>"><?php echo $month; ?></option>
5277
+ <?php endforeach; ?>
5278
+ </select>
5279
+ <select name="expiration_date_year" id="mec_paypal_credit_card_expiration_date_year">
5280
+ <?php
5281
+ for ($i = 0; $i <= 10;
5282
+ $i++) :
5283
+ $y = date('Y', strtotime('+' . $i . ' years'));
5284
+ ?>
5285
+ <option value="<?php echo $y; ?>"><?php echo $y; ?></option>
5286
+ <?php endfor; ?>
5287
+ </select>
5288
+ </div>
5289
+ <div class="mec-form-row mec-paypal-credit-card-cvv2">
5290
+ <label for="mec_paypal_credit_card_cvv2"><?php echo __('CVV2', 'modern-events-calendar-lite'); ?></label>
5291
+ <input type="text" name="cvv2" id="mec_paypal_credit_card_cvv2"/>
5292
+ </div>
5293
+ <div class="mec-form-row mec-click-pay">
5294
+ <input type="hidden" name="action" value="mec_cart_do_transaction_paypal_credit_card"/>
5295
+ <input type="hidden" name="cart_id" value="<?php echo $cart_id; ?>"/>
5296
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
5297
+ <?php wp_nonce_field('mec_transaction_form_' . $cart_id); ?>
5298
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Pay', 'modern-events-calendar-lite'); ?></button>
5299
+ </div>
5300
+ </form>
5301
+ <script type="text/javascript">
5302
+ function mec_paypal_credit_card_send_request(cart_id)
5303
+ {
5304
+ // Add loading Class to the button
5305
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + cart_id + " button[type=submit]").addClass("loading");
5306
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + cart_id).removeClass("mec-success mec-error").hide();
5307
+
5308
+ var data = jQuery("#mec_do_transaction_paypal_credit_card_form" + cart_id).serialize();
5309
+ jQuery.ajax(
5310
+ {
5311
+ type: "GET",
5312
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
5313
+ data: data,
5314
+ dataType: "JSON",
5315
+ success: function(data)
5316
+ {
5317
+ // Remove the loading Class from the button
5318
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + cart_id + " button[type=submit]").removeClass("loading");
5319
+
5320
+ if(data.success == 1)
5321
+ {
5322
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + cart_id).hide();
5323
+ jQuery(".mec-checkout-form-gateway-label").remove();
5324
+ jQuery(".mec-gateway-comment").hide();
5325
+
5326
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + cart_id).addClass("mec-success").html(data.message).show();
5327
+ }
5328
+ else
5329
+ {
5330
+ jQuery("#mec_do_transaction_paypal_credit_card_message" + cart_id).addClass("mec-error").html(data.message).show();
5331
+ }
5332
+ },
5333
+ error: function(jqXHR, textStatus, errorThrown)
5334
+ {
5335
+ // Remove the loading Class from the button
5336
+ jQuery("#mec_do_transaction_paypal_credit_card_form" + cart_id + " button[type=submit]").removeClass("loading");
5337
+ }
5338
+ });
5339
+ }
5340
+ </script>
5341
+ <?php
5342
+ }
5343
+
5344
+ public function cart_do_transaction()
5345
+ {
5346
+ $cart_id = isset($_GET['cart_id']) ? sanitize_text_field($_GET['cart_id']) : NULL;
5347
+
5348
+ // Verify that the nonce is valid.
5349
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_transaction_form_' . $cart_id))
5350
+ {
5351
+ $this->response(array(
5352
+ 'success' => 0,
5353
+ 'code' => 'NONCE_IS_INVALID',
5354
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
5355
+ ));
5356
+ }
5357
+
5358
+ // Validate Ticket Availability
5359
+ $this->cart_validate($cart_id);
5360
+
5361
+ /**
5362
+ * Payment
5363
+ */
5364
+
5365
+ $validate = $this->cart_validate_paypal($_GET);
5366
+ if(!$validate)
5367
+ {
5368
+ $this->response(array(
5369
+ 'success' => 0,
5370
+ 'code' => 'PAYMENT_IS_INVALID',
5371
+ 'message' => __('Payment is invalid.', 'modern-events-calendar-lite'),
5372
+ ));
5373
+ }
5374
+
5375
+ /**
5376
+ * Booking
5377
+ */
5378
+
5379
+ // Cart Library
5380
+ $c = $this->getCart();
5381
+ $cart = $c->get_cart($cart_id);
5382
+
5383
+ $book_ids = array();
5384
+ foreach($cart as $transaction_id)
5385
+ {
5386
+ $transaction = $this->book->get_transaction($transaction_id);
5387
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
5388
+
5389
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
5390
+ $attention_times = explode(':', $attention_date);
5391
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
5392
+
5393
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
5394
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
5395
+
5396
+ $ticket_ids = '';
5397
+ $attendees_info = array();
5398
+
5399
+ foreach($attendees as $i => $attendee)
5400
+ {
5401
+ if(!is_numeric($i)) continue;
5402
+
5403
+ $ticket_ids .= $attendee['id'] . ',';
5404
+
5405
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
5406
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
5407
+ }
5408
+
5409
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
5410
+ $user_id = $this->register_user($main_attendee, $transaction);
5411
+
5412
+ // Remove Sensitive Data
5413
+ if(isset($transaction['username']) or isset($transaction['password']))
5414
+ {
5415
+ unset($transaction['username']);
5416
+ unset($transaction['password']);
5417
+
5418
+ $this->book->update_transaction($transaction_id, $transaction);
5419
+ }
5420
+
5421
+ // MEC User
5422
+ $u = $this->getUser();
5423
+
5424
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
5425
+ $book_id = $this->book->add(
5426
+ array(
5427
+ 'post_author' => $user_id,
5428
+ 'post_type' => $this->PT,
5429
+ 'post_title' => $book_subject,
5430
+ 'post_date' => $date,
5431
+ 'attendees_info' => $attendees_info,
5432
+ 'mec_attendees' => $attendees,
5433
+ 'mec_gateway' => 'MEC_gateway_paypal_credit_card',
5434
+ 'mec_gateway_label' => $this->title()
5435
+ ),
5436
+ $transaction_id,
5437
+ $ticket_ids
5438
+ );
5439
+
5440
+ // Assign User
5441
+ $u->assign($book_id, $user_id);
5442
+
5443
+ // Fires after completely creating a new booking
5444
+ do_action('mec_booking_completed', $book_id);
5445
+
5446
+ $book_ids[] = $book_id;
5447
+ }
5448
+
5449
+ $invoice_status = (isset($this->settings['mec_cart_invoice']) and $this->settings['mec_cart_invoice']);
5450
+ $invoice_link = (!$invoice_status) ? '' : $c->get_invoice_link($cart_id);
5451
+
5452
+ $message = stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite')));
5453
+ if(trim($invoice_link)) $message .= ' <a class="mec-invoice-download" href="'.esc_url($invoice_link).'">'.__('Download Invoice', 'modern-events-calendar-lite').'</a>';
5454
+
5455
+ // Empty Cart
5456
+ $c->clear($cart_id);
5457
+
5458
+ $this->response(array(
5459
+ 'success' => 1,
5460
+ 'message' => $message,
5461
+ 'data' => array(
5462
+ 'book_ids' => $book_ids,
5463
+ 'invoice_link' => $invoice_link,
5464
+ ),
5465
+ ));
5466
+ }
5467
+
5468
+ public function cart_validate_paypal($vars = array())
5469
+ {
5470
+ $card_type = (isset($vars['card_type']) ? sanitize_text_field($vars['card_type']) : null);
5471
+ $cc_number = (isset($vars['cc_number']) ? sanitize_text_field($vars['cc_number']) : null);
5472
+ $cvv2 = (isset($vars['cvv2']) ? sanitize_text_field($vars['cvv2']) : null);
5473
+ $first_name = (isset($vars['first_name']) ? sanitize_text_field($vars['first_name']) : null);
5474
+ $last_name = (isset($vars['last_name']) ? sanitize_text_field($vars['last_name']) : null);
5475
+ $exp_date_month = (isset($vars['expiration_date_month']) ? sanitize_text_field($vars['expiration_date_month']) : null);
5476
+ $exp_date_year = (isset($vars['expiration_date_year']) ? sanitize_text_field($vars['expiration_date_year']) : null);
5477
+
5478
+ // Check Card details
5479
+ if(!$card_type or !$cc_number or !$cvv2) return false;
5480
+
5481
+ $cart_id = isset($vars['cart_id']) ? sanitize_text_field($vars['cart_id']) : 0;
5482
+
5483
+ // Cart Library
5484
+ $c = $this->getCart();
5485
+ $cart = $c->get_cart($cart_id);
5486
+
5487
+ // Payable
5488
+ $payable = $c->get_payable($cart);
5489
+
5490
+ // Get Options
5491
+ $options = $this->options();
5492
+
5493
+ $expdate = $exp_date_month . $exp_date_year;
5494
+ $params = array(
5495
+ 'METHOD' => 'DoDirectPayment',
5496
+ 'USER' => (isset($options['api_username']) ? $options['api_username'] : null),
5497
+ 'PWD' => (isset($options['api_password']) ? $options['api_password'] : null),
5498
+ 'SIGNATURE' => (isset($options['api_signature']) ? $options['api_signature'] : null),
5499
+ 'VERSION' => 90.0,
5500
+ 'CREDITCARDTYPE' => $card_type,
5501
+ 'ACCT' => $cc_number,
5502
+ 'EXPDATE' => $expdate,
5503
+ 'CVV2' => $cvv2,
5504
+ 'FIRSTNAME' => $first_name,
5505
+ 'LASTNAME' => $last_name,
5506
+ 'AMT' => $payable,
5507
+ 'CURRENCYCODE' => $this->main->get_currency_code(),
5508
+ 'DESC' => sprintf(__('Transactions: %s', 'modern-events-calendar-lite'), implode(', ', $cart)),
5509
+ );
5510
+
5511
+ $request_str = $this->get_request_string($params);
5512
+ $response_str = $this->get_paypal_response($request_str, $this->get_api_url());
5513
+
5514
+ $results = $this->normalize_NVP($response_str);
5515
+
5516
+ $status = strpos(strtolower($results['ACK']), 'success') !== false ? 1 : 0;
5517
+ $amount = isset($results['AMT']) ? $results['AMT'] : 0;
5518
+
5519
+ // Save Transaction ID
5520
+ if($status)
5521
+ {
5522
+ $gateway_transaction_id = isset($results['TRANSACTIONID']) ? $results['TRANSACTIONID'] : '';
5523
+ if($gateway_transaction_id)
5524
+ {
5525
+ foreach($cart as $transaction_id)
5526
+ {
5527
+ $transaction = $this->book->get_transaction($transaction_id);
5528
+
5529
+ $transaction['gateway_transaction_id'] = $gateway_transaction_id;
5530
+ $this->book->update_transaction($transaction_id, $transaction);
5531
+ }
5532
+ }
5533
+ }
5534
+
5535
+ // Error
5536
+ if(!$status)
5537
+ {
5538
+ $error = (isset($results['L_ERRORCODE0']) ? '('.$results['L_ERRORCODE0'].') ' : '').(isset($results['L_LONGMESSAGE0']) ? $results['L_LONGMESSAGE0'] : '');
5539
+
5540
+ // Log it
5541
+ trigger_error($error, E_USER_NOTICE);
5542
+
5543
+ // Save it
5544
+ update_option('mec_paypal_cc_error', current_time('Y-m-d H:i:s').': '.$error, false);
5545
+ }
5546
+
5547
+ // Compare paid amount with transaction amount
5548
+ return ($amount >= $payable and $status) ? true : false;
5549
+ }
5550
+ }
5551
+
5552
+ class MEC_gateway_woocommerce extends MEC_gateway
5553
+ {
5554
+ public $id = 6;
5555
+ public $options;
5556
+
5557
+ public function __construct()
5558
+ {
5559
+ parent::__construct();
5560
+
5561
+ // Gateway options
5562
+ $this->options = $this->options();
5563
+
5564
+ // Register actions
5565
+ $this->factory->action('wp_ajax_mec_create_order_woocommerce', array($this, 'create_order'));
5566
+ $this->factory->action('wp_ajax_nopriv_mec_create_order_woocommerce', array($this, 'create_order'));
5567
+
5568
+ $this->factory->action('wp_ajax_mec_check_transaction_woocommerce', array($this, 'check_transaction'));
5569
+ $this->factory->action('wp_ajax_nopriv_mec_check_transaction_woocommerce', array($this, 'check_transaction'));
5570
+
5571
+ $this->factory->action('woocommerce_order_status_completed', array($this, 'after_order_completed'), 10, 1);
5572
+ $this->factory->action('woocommerce_thankyou', array($this, 'after_payment'), 10, 1);
5573
+
5574
+ $this->factory->action('woocommerce_order_status_cancelled', array($this, 'after_order_cancellation'), 10, 1);
5575
+ $this->factory->action('woocommerce_order_status_refunded', array($this, 'after_order_cancellation'), 10, 1);
5576
+
5577
+ $this->factory->filter('woocommerce_order_subtotal_to_display', array($this, 'hide_subtotal'), 10, 3);
5578
+ }
5579
+
5580
+ public function label()
5581
+ {
5582
+ return __('Pay by WooCommerce', 'modern-events-calendar-lite');
5583
+ }
5584
+
5585
+ public function color()
5586
+ {
5587
+ return '#ff007f';
5588
+ }
5589
+
5590
+ public function enabled()
5591
+ {
5592
+ return ((isset($this->options['status']) and $this->options['status']) ? (function_exists('wc_create_order') ? true : false) : false);
5593
+ }
5594
+
5595
+ public function create_order()
5596
+ {
5597
+ $transaction_id = isset($_POST['transaction_id']) ? sanitize_text_field($_POST['transaction_id']) : 0;
5598
+
5599
+ // Verify that the nonce is valid.
5600
+ if(!wp_verify_nonce($_POST['_wpnonce'], 'mec_transaction_form_' . $transaction_id))
5601
+ {
5602
+ $this->response(array(
5603
+ 'success' => 0,
5604
+ 'code' => 'NONCE_IS_INVALID',
5605
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
5606
+ ));
5607
+ }
5608
+
5609
+ // Validate Ticket Availability
5610
+ $this->validate($transaction_id);
5611
+
5612
+ $transaction = $this->book->get_transaction($transaction_id);
5613
+ $event_id = $transaction['event_id'];
5614
+
5615
+ // Now we create the order
5616
+ $order = wc_create_order(
5617
+ array(
5618
+ 'customer_id' => get_current_user_id(),
5619
+ )
5620
+ );
5621
+
5622
+ // Set Transaction ID into the Order Meta Data, We will use it after WC checkout
5623
+ update_post_meta($order->get_id(), '_mec_transaction_id', $transaction_id);
5624
+
5625
+ $attendee_name = isset($transaction['tickets']) ? $transaction['tickets'][0]['name'] : '';
5626
+ $ex = explode(' ', $attendee_name);
5627
+
5628
+ $fname = $lname = '';
5629
+
5630
+ // Update Order Billing First Name and Last Name
5631
+ if(trim($ex[0]))
5632
+ {
5633
+ $fname = $ex[0];
5634
+ update_post_meta($order->get_id(), '_billing_first_name', $fname);
5635
+ }
5636
+
5637
+ if(trim($ex[1]))
5638
+ {
5639
+ $lname = implode(' ', array_slice($ex, 1));
5640
+ update_post_meta($order->get_id(), '_billing_last_name', $lname);
5641
+ }
5642
+
5643
+ $order->set_address(
5644
+ array(
5645
+ 'first_name' => $fname,
5646
+ 'last_name' => $lname,
5647
+ 'email' => $transaction['tickets'][0]['email'],
5648
+ ),
5649
+ 'shipping'
5650
+ );
5651
+
5652
+ $order->set_address(
5653
+ array(
5654
+ 'first_name' => $fname,
5655
+ 'last_name' => $lname,
5656
+ 'email' => $transaction['tickets'][0]['email'],
5657
+ ),
5658
+ 'billing'
5659
+ );
5660
+
5661
+ $order->set_currency($this->main->get_currency_code($event_id));
5662
+
5663
+ $fee = new WC_Order_Item_Fee();
5664
+ $fee->set_name(sprintf(__('Booking fee for %s', 'modern-events-calendar-lite'), get_the_title($event_id)));
5665
+ $fee->set_tax_class('');
5666
+ $fee->set_tax_status('taxable');
5667
+ $fee->set_amount((isset($transaction['price']) ? $transaction['price'] : 0));
5668
+ $fee->set_total((isset($transaction['price']) ? $transaction['price'] : 0));
5669
+
5670
+ $order->add_item($fee);
5671
+ $order->calculate_totals();
5672
+
5673
+ $url = $order->get_checkout_payment_url();
5674
+ $this->response(
5675
+ array(
5676
+ 'success' => 1,
5677
+ 'message' => __('Order created. Please proceed with checkout.', 'modern-events-calendar-lite'),
5678
+ 'data' => array(
5679
+ 'url' => $url,
5680
+ 'id' => $order->get_id(),
5681
+ ),
5682
+ )
5683
+ );
5684
+ }
5685
+
5686
+ public function do_transaction($transaction_id = null, $order_id = null)
5687
+ {
5688
+ $transaction = $this->book->get_transaction($transaction_id);
5689
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
5690
+
5691
+ // Is there any attendee?
5692
+ if(!count($attendees))
5693
+ {
5694
+ return array(
5695
+ 'success' => 0,
5696
+ 'code' => 'NO_TICKET',
5697
+ 'message' => __('There is no attendee for booking!', 'modern-events-calendar-lite'),
5698
+ );
5699
+ }
5700
+
5701
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
5702
+ $attention_times = explode(':', $attention_date);
5703
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
5704
+
5705
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
5706
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
5707
+
5708
+ $ticket_ids = '';
5709
+ $attendees_info = array();
5710
+
5711
+ foreach($attendees as $i => $attendee)
5712
+ {
5713
+ if(!is_numeric($i)) continue;
5714
+
5715
+ $ticket_ids .= $attendee['id'] . ',';
5716
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
5717
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
5718
+ }
5719
+
5720
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
5721
+ $user_id = $this->register_user($main_attendee, $transaction);
5722
+
5723
+ // Remove Sensitive Data
5724
+ if(isset($transaction['username']) or isset($transaction['password']))
5725
+ {
5726
+ unset($transaction['username']);
5727
+ unset($transaction['password']);
5728
+
5729
+ $this->book->update_transaction($transaction_id, $transaction);
5730
+ }
5731
+
5732
+ // MEC User
5733
+ $u = $this->getUser();
5734
+
5735
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
5736
+ $book_id = $this->book->add(
5737
+ array(
5738
+ 'post_author' => $user_id,
5739
+ 'post_type' => $this->PT,
5740
+ 'post_title' => $book_subject,
5741
+ 'post_date' => $date,
5742
+ 'attendees_info' => $attendees_info,
5743
+ 'mec_attendees' => $attendees,
5744
+ 'mec_gateway' => 'MEC_gateway_woocommerce',
5745
+ 'mec_gateway_label' => $this->title()
5746
+ ),
5747
+ $transaction_id,
5748
+ $ticket_ids
5749
+ );
5750
+
5751
+ // Assign User
5752
+ $u->assign($book_id, $user_id);
5753
+
5754
+ update_post_meta($book_id, 'mec_order_id', $order_id);
5755
+
5756
+ // Fires after completely creating a new booking
5757
+ do_action('mec_booking_completed', $book_id);
5758
+
5759
+ // Update WC Order client
5760
+ if($order_id)
5761
+ {
5762
+ $customer = get_post_meta($order_id, '_customer_user', true);
5763
+ if($customer != $user_id)
5764
+ {
5765
+ // MEC User
5766
+ $u = $this->getUser();
5767
+
5768
+ update_post_meta($order_id, '_customer_user', $user_id);
5769
+ update_post_meta($order_id, '_billing_email', $u->get($user_id)->user_email);
5770
+ }
5771
+ }
5772
+
5773
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
5774
+ $redirect_to = '';
5775
+
5776
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
5777
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
5778
+
5779
+ // Invoice Link
5780
+ $mec_confirmed = get_post_meta($book_id, 'mec_confirmed', true);
5781
+ $invoice_link = (!$mec_confirmed) ? '' : $this->book->get_invoice_link($transaction_id);
5782
+ $dl_file_link = (!$mec_confirmed) ? '' : $this->book->get_dl_file_link($book_id);
5783
+
5784
+ $extra_info = apply_filters('MEC_extra_info_gateways', '', $this->book->get_event_id_by_transaction_id($transaction_id), $book_id);
5785
+
5786
+ return array(
5787
+ 'success' => 1,
5788
+ 'message' => stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite'))),
5789
+ 'data' => array(
5790
+ 'book_id' => $book_id,
5791
+ 'redirect_to' => $redirect_to,
5792
+ 'invoice_link' => $invoice_link,
5793
+ 'dl_file_link' => $dl_file_link,
5794
+ 'extra_info' => $extra_info,
5795
+ ),
5796
+ );
5797
+ }
5798
+
5799
+ public function checkout_form($transaction_id, $params = array())
5800
+ {
5801
+ ?>
5802
+ <script type="text/javascript">
5803
+ jQuery('#mec_do_transaction_woocommerce_form<?php echo $transaction_id; ?>').on('submit', function(e)
5804
+ {
5805
+ // Prevent the form from submitting
5806
+ e.preventDefault();
5807
+
5808
+ var transaction_id = '<?php echo $transaction_id; ?>';
5809
+
5810
+ // Add loading Class to the button
5811
+ jQuery("#mec_do_transaction_woocommerce_form" + transaction_id + " button[type=submit]").addClass("loading");
5812
+ jQuery("#mec_do_transaction_woocommerce_message" + transaction_id).removeClass("mec-success mec-error").hide();
5813
+
5814
+ var data = jQuery("#mec_do_transaction_woocommerce_form" + transaction_id).serialize();
5815
+ jQuery.ajax(
5816
+ {
5817
+ type: "POST",
5818
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
5819
+ data: data,
5820
+ dataType: "JSON",
5821
+ success: function (data) {
5822
+ if (data.success == 1) {
5823
+ window.location.href = data.data.url;
5824
+ }
5825
+ else {
5826
+ // Remove the loading Class from the button
5827
+ jQuery("#mec_do_transaction_woocommerce_form" + transaction_id + " button[type=submit]").removeClass("loading");
5828
+
5829
+ jQuery("#mec_do_transaction_woocommerce_message" + transaction_id).addClass("mec-error").html(data.message).show();
5830
+ }
5831
+ },
5832
+ error: function (jqXHR, textStatus, errorThrown) {
5833
+ // Remove the loading Class from the button
5834
+ jQuery("#mec_do_transaction_woocommerce_form" + transaction_id + " button[type=submit]").removeClass("loading");
5835
+ }
5836
+ });
5837
+ });
5838
+
5839
+ function mec_woocommerce_pay_checker(transaction_id)
5840
+ {
5841
+ jQuery.ajax(
5842
+ {
5843
+ type: "GET",
5844
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
5845
+ data: "action=mec_check_transaction_woocommerce&transaction_id=" + transaction_id,
5846
+ dataType: "JSON",
5847
+ success: function (data) {
5848
+ if (data.success == 1) {
5849
+ jQuery("#mec-book-form-back-btn-step-3").remove();
5850
+ jQuery("#mec_do_transaction_woocommerce_message" + transaction_id).addClass("mec-success").html(data.message).show();
5851
+ jQuery("#mec_do_transaction_woocommerce_checkout" + transaction_id).hide();
5852
+
5853
+ // Show Invoice Link
5854
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
5855
+ {
5856
+ jQuery("#mec_do_transaction_woocommerce_message" + transaction_id).append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
5857
+ }
5858
+
5859
+ // Show Downloadable Link
5860
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
5861
+ {
5862
+ jQuery("#mec_do_transaction_woocommerce_message" + transaction_id).append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
5863
+ }
5864
+
5865
+ // Show Extra info
5866
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
5867
+ {
5868
+ jQuery("#mec_do_transaction_woocommerce_message" + transaction_id).append('<div>' + data.data.extra_info+'</div>');
5869
+ }
5870
+
5871
+ // Redirect to thank you page
5872
+ if (typeof data.data.redirect_to != "undefined" && data.data.redirect_to != "") {
5873
+ setTimeout(function () {
5874
+ window.location.href = data.data.redirect_to;
5875
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
5876
+ }
5877
+ }
5878
+ else if (data.success == 0) {
5879
+ jQuery("#mec_do_transaction_woocommerce_message" + transaction_id).addClass("mec-error").html(data.message).show();
5880
+ }
5881
+ else {
5882
+ setTimeout(function () {
5883
+ mec_woocommerce_pay_checker(transaction_id)
5884
+ }, 10000);
5885
+ }
5886
+ },
5887
+ error: function (jqXHR, textStatus, errorThrown) {
5888
+ setTimeout(function () {
5889
+ mec_woocommerce_pay_checker(transaction_id)
5890
+ }, 10000);
5891
+ }
5892
+ });
5893
+ }
5894
+ </script>
5895
+ <div class="mec-gateway-message mec-util-hidden"
5896
+ id="mec_do_transaction_woocommerce_message<?php echo $transaction_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
5897
+ <form id="mec_do_transaction_woocommerce_form<?php echo $transaction_id; ?>" class="mec-click-pay">
5898
+ <div class="mec-form-row">
5899
+ <input type="hidden" name="action" value="mec_create_order_woocommerce"/>
5900
+ <input type="hidden" name="transaction_id" value="<?php echo $transaction_id; ?>"/>
5901
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
5902
+ <?php wp_nonce_field('mec_transaction_form_' . $transaction_id); ?>
5903
+ <button type="submit" class="mec-book-form-next-button"><?php _e('Checkout', 'modern-events-calendar-lite'); ?></button>
5904
+ </div>
5905
+ </form>
5906
+ <div class="mec-util-hidden" id="mec_do_transaction_woocommerce_checkout<?php echo $transaction_id; ?>">
5907
+ <a class="mec-woo-booking-checkout" target="_blank"><?php _e('Checkout', 'modern-events-calendar-lite'); ?></a>
5908
+ </div>
5909
+ <?php
5910
+ }
5911
+
5912
+ public function options_form()
5913
+ {
5914
+ ?>
5915
+ <div class="mec-form-row mec-click-pay">
5916
+ <label>
5917
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][status]" value="0"/>
5918
+ <input onchange="jQuery('#mec_gateways<?php echo $this->id(); ?>_container_toggle').toggle();" value="1"
5919
+ type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][status]"
5920
+ <?php
5921
+ if (isset($this->options['status']) and $this->options['status']) {
5922
+ echo 'checked="checked"';
5923
+ }
5924
+ ?>
5925
+ /> <?php _e('Pay by WooCommerce', 'modern-events-calendar-lite'); ?>
5926
+ </label>
5927
+ </div>
5928
+ <div id="mec_gateways<?php echo $this->id(); ?>_container_toggle" class="mec-gateway-options-form
5929
+ <?php
5930
+ if ((isset($this->options['status']) and !$this->options['status']) or !isset($this->options['status'])) {
5931
+ echo 'mec-util-hidden';
5932
+ }
5933
+ ?>
5934
+ ">
5935
+ <?php if (!function_exists('wc_create_order')) : ?>
5936
+ <p class="mec-error"><?php _e('WooCommerce must be installed and activated first.', 'modern-events-calendar-lite'); ?></p>
5937
+ <?php else : ?>
5938
+ <div class="mec-form-row">
5939
+ <label class="mec-col-3"
5940
+ for="mec_gateways<?php echo $this->id(); ?>_title"><?php _e('Title', 'modern-events-calendar-lite'); ?></label>
5941
+ <div class="mec-col-9">
5942
+ <input type="text" id="mec_gateways<?php echo $this->id(); ?>_title"
5943
+ name="mec[gateways][<?php echo $this->id(); ?>][title]"
5944
+ value="<?php echo (isset($this->options['title']) and trim($this->options['title'])) ? $this->options['title'] : ''; ?>"
5945
+ placeholder="<?php echo $this->label(); ?>"/>
5946
+ </div>
5947
+ </div>
5948
+ <div class="mec-form-row">
5949
+ <label class="mec-col-3"
5950
+ for="mec_gateways<?php echo $this->id(); ?>_comment"><?php _e('Comment', 'modern-events-calendar-lite'); ?></label>
5951
+ <div class="mec-col-9">
5952
+ <textarea id="mec_gateways<?php echo $this->id(); ?>_comment"
5953
+ name="mec[gateways][<?php echo $this->id(); ?>][comment]"><?php echo (isset($this->options['comment']) and trim($this->options['comment'])) ? stripslashes($this->options['comment']) : esc_html__('WooCommerce Gateway Description', 'modern-events-calendar-lite'); ?></textarea>
5954
+ <span class="mec-tooltip">
5955
+ <div class="box left">
5956
+ <h5 class="title"><?php _e('Comment', 'modern-events-calendar-lite'); ?></h5>
5957
+ <div class="content"><p><?php esc_attr_e('HTML allowed.', 'modern-events-calendar-lite'); ?><a
5958
+ href="https://webnus.net/dox/modern-events-calendar/woocommerce/"
5959
+ target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
5960
+ </div>
5961
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
5962
+ </span>
5963
+ </div>
5964
+ </div>
5965
+ <div class="mec-form-row">
5966
+ <label class="mec-col-3"
5967
+ for="mec_gateways<?php echo $this->id(); ?>_auto_order_complete"><?php _e('Automatically complete WC orders', 'modern-events-calendar-lite'); ?></label>
5968
+ <div class="mec-col-9">
5969
+ <select id="mec_gateways<?php echo $this->id(); ?>_auto_order_complete"
5970
+ name="mec[gateways][<?php echo $this->id(); ?>][auto_order_complete]">
5971
+ <option value="1" <?php echo((isset($this->options['auto_order_complete']) and $this->options['auto_order_complete'] == '1') ? 'selected="selected"' : ''); ?>><?php _e('Enabled', 'modern-events-calendar-lite'); ?></option>
5972
+ <option value="0" <?php echo((isset($this->options['auto_order_complete']) and $this->options['auto_order_complete'] == '0') ? 'selected="selected"' : ''); ?>><?php _e('Disabled', 'modern-events-calendar-lite'); ?></option>
5973
+ </select>
5974
+ <span class="mec-tooltip">
5975
+ <div class="box left">
5976
+ <h5 class="title"><?php _e('Auto WC orders', 'modern-events-calendar-lite'); ?></h5>
5977
+ <div class="content"><p><?php esc_attr_e('It applies only to the orders that are related to MEC.', 'modern-events-calendar-lite'); ?>
5978
+ <a href="https://webnus.net/dox/modern-events-calendar/woocommerce/"
5979
+ target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
5980
+ </div>
5981
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
5982
+ </span>
5983
+ </div>
5984
+ </div>
5985
+ <div class="mec-form-row">
5986
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_index"><?php _e('Position', 'modern-events-calendar-lite'); ?></label>
5987
+ <div class="mec-col-9">
5988
+ <input type="number" min="0" step="1" id="mec_gateways<?php echo $this->id(); ?>_index"
5989
+ name="mec[gateways][<?php echo $this->id(); ?>][index]"
5990
+ value="<?php echo (isset($this->options['index']) and trim($this->options['index'])) ? $this->options['index'] : 5; ?>"
5991
+ placeholder="<?php echo esc_attr__('Position', 'modern-events-calendar-lite'); ?>"/>
5992
+ </div>
5993
+ </div>
5994
+ <?php endif; ?>
5995
+ </div>
5996
+ <?php
5997
+ }
5998
+
5999
+ public function check_transaction($transaction_id = null)
6000
+ {
6001
+ if (!trim($transaction_id)) {
6002
+ $transaction_id = isset($_GET['transaction_id']) ? sanitize_text_field($_GET['transaction_id']) : 0;
6003
+ }
6004
+
6005
+ $transaction = $this->book->get_transaction($transaction_id);
6006
+
6007
+ $success = 2;
6008
+ $message = __('Waiting for a response from gateway.', 'modern-events-calendar-lite');
6009
+ $data = array();
6010
+
6011
+ if (isset($transaction['done']) and $transaction['done'] == 1) {
6012
+ $success = 1;
6013
+ $message = stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite')));
6014
+
6015
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
6016
+
6017
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
6018
+ if($thankyou_page_id) $data['redirect_to'] = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
6019
+ } elseif (isset($transaction['done']) and $transaction['done'] == 0) {
6020
+ $success = 0;
6021
+ $message = __('Payment invalid! Booking failed.', 'modern-events-calendar-lite');
6022
+ }
6023
+
6024
+ $this->response(
6025
+ array(
6026
+ 'success' => $success,
6027
+ 'message' => $message,
6028
+ 'data' => $data,
6029
+ )
6030
+ );
6031
+ }
6032
+
6033
+ public function after_payment($order_id)
6034
+ {
6035
+ if (!$order_id) {
6036
+ return;
6037
+ }
6038
+
6039
+ // Auto Order Complete is not enabled
6040
+ if (!isset($this->options['auto_order_complete']) or (isset($this->options['auto_order_complete']) and !$this->options['auto_order_complete'])) {
6041
+ return;
6042
+ }
6043
+
6044
+ $transaction_id = get_post_meta($order_id, '_mec_transaction_id', true);
6045
+ if (!$transaction_id) {
6046
+ return;
6047
+ }
6048
+
6049
+ $order = wc_get_order($order_id);
6050
+ $order->update_status('completed');
6051
+ }
6052
+
6053
+ public function after_order_completed($order_id)
6054
+ {
6055
+ $transaction_id = get_post_meta($order_id, '_mec_transaction_id', true);
6056
+ if (!$transaction_id) {
6057
+ return;
6058
+ }
6059
+
6060
+ // Mark it as done
6061
+ $transaction = $this->book->get_transaction($transaction_id);
6062
+ $transaction['done'] = 1;
6063
+
6064
+ $this->book->update_transaction($transaction_id, $transaction);
6065
+
6066
+ // Do MEC Transaction
6067
+ $this->do_transaction($transaction_id, $order_id);
6068
+ }
6069
+
6070
+ public function after_order_cancellation($order_id)
6071
+ {
6072
+ $transaction_id = get_post_meta($order_id, '_mec_transaction_id', true);
6073
+ if (!$transaction_id) {
6074
+ return;
6075
+ }
6076
+
6077
+ // Mark bookings as Canceled
6078
+ $bookings = $this->book->get_bookings_by_transaction_id($transaction_id);
6079
+ foreach($bookings as $booking)
6080
+ {
6081
+ $this->book->cancel($booking->ID);
6082
+ $this->book->reject($booking->ID);
6083
+ }
6084
+ }
6085
+
6086
+ public function hide_subtotal($subtotal, $compound, $order)
6087
+ {
6088
+ if(is_object($order) and method_exists($order, 'meta_exists') and $order->meta_exists('_mec_transaction_id')) return false;
6089
+ else return $subtotal;
6090
+ }
6091
+ }
6092
+
6093
+ class MEC_gateway_free extends MEC_gateway
6094
+ {
6095
+ public $id = 4;
6096
+ public $options;
6097
+
6098
+ public function __construct()
6099
+ {
6100
+ parent::__construct();
6101
+
6102
+ // Gateway options
6103
+ $this->options = $this->options();
6104
+ }
6105
+
6106
+ public function label()
6107
+ {
6108
+ return __('Free', 'modern-events-calendar-lite');
6109
+ }
6110
+
6111
+ public function color()
6112
+ {
6113
+ return '#23c8d2';
6114
+ }
6115
+
6116
+ public function do_transaction($transaction_id = null)
6117
+ {
6118
+ $transaction = $this->book->get_transaction($transaction_id);
6119
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
6120
+
6121
+ $price = isset($transaction['price']) ? $transaction['price'] : 0;
6122
+
6123
+ // Booking is not free!
6124
+ if($price)
6125
+ {
6126
+ return array(
6127
+ 'success' => 0,
6128
+ 'code' => 'NOT_FREE',
6129
+ 'message' => __('This booking is not free!', 'modern-events-calendar-lite'),
6130
+ );
6131
+ }
6132
+
6133
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
6134
+ $attention_times = explode(':', $attention_date);
6135
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
6136
+
6137
+ // Is there any attendee?
6138
+ if(!count($attendees))
6139
+ {
6140
+ return array(
6141
+ 'success' => 0,
6142
+ 'code' => 'NO_TICKET',
6143
+ 'message' => __('There is no attendee for booking!', 'modern-events-calendar-lite'),
6144
+ );
6145
+ }
6146
+
6147
+ // Validate Ticket Availability
6148
+ $this->validate($transaction_id);
6149
+
6150
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
6151
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
6152
+
6153
+ $ticket_ids = '';
6154
+ $attendees_info = array();
6155
+
6156
+ foreach($attendees as $i => $attendee)
6157
+ {
6158
+ if(!is_numeric($i)) continue;
6159
+
6160
+ $ticket_ids .= $attendee['id'] . ',';
6161
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
6162
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
6163
+ }
6164
+
6165
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
6166
+ $user_id = $this->register_user($main_attendee, $transaction);
6167
+
6168
+ // Remove Sensitive Data
6169
+ if(isset($transaction['username']) or isset($transaction['password']))
6170
+ {
6171
+ unset($transaction['username']);
6172
+ unset($transaction['password']);
6173
+
6174
+ $this->book->update_transaction($transaction_id, $transaction);
6175
+ }
6176
+
6177
+ // MEC User
6178
+ $u = $this->getUser();
6179
+
6180
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
6181
+ $book_id = $this->book->add(
6182
+ array(
6183
+ 'post_author' => $user_id,
6184
+ 'post_type' => $this->PT,
6185
+ 'post_title' => $book_subject,
6186
+ 'post_date' => $date,
6187
+ 'attendees_info' => $attendees_info,
6188
+ 'mec_attendees' => $attendees,
6189
+ 'mec_gateway' => 'MEC_gateway_free',
6190
+ 'mec_gateway_label' => $this->title()
6191
+ ),
6192
+ $transaction_id,
6193
+ $ticket_ids
6194
+ );
6195
+
6196
+ if(!$book_id) $book_id = $this->book->get_book_id_transaction_id($transaction_id);
6197
+
6198
+ // Assign User
6199
+ $u->assign($book_id, $user_id);
6200
+
6201
+ // Fires after completely creating a new booking
6202
+ do_action('mec_booking_completed', $book_id);
6203
+
6204
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
6205
+ $redirect_to = '';
6206
+
6207
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
6208
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
6209
+
6210
+ // Invoice Link
6211
+ $mec_confirmed = get_post_meta($book_id, 'mec_confirmed', true);
6212
+ $invoice_link = (!$mec_confirmed) ? '' : $this->book->get_invoice_link($transaction_id);
6213
+ $dl_file_link = (!$mec_confirmed) ? '' : $this->book->get_dl_file_link($book_id);
6214
+
6215
+ $extra_info = apply_filters('MEC_extra_info_gateways', '', $this->book->get_event_id_by_transaction_id($transaction_id), $book_id);
6216
+
6217
+ $message = stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite')));
6218
+ if(trim($invoice_link)) $message .= ' <a class="mec-invoice-download" href="'.esc_url($invoice_link).'">'.__('Download Invoice', 'modern-events-calendar-lite').'</a>';
6219
+ if(trim($dl_file_link)) $message .= ' — <a class="mec-file-download" href="'.esc_url($dl_file_link).'">'.__('Download File', 'modern-events-calendar-lite').'</a>';
6220
+ if(trim($extra_info)) $message .= '<div>' . $extra_info . '</div>';
6221
+
6222
+ return array(
6223
+ 'success' => 1,
6224
+ 'message' => $message,
6225
+ 'data' => array(
6226
+ 'book_id' => $book_id,
6227
+ 'redirect_to' => $redirect_to,
6228
+ ),
6229
+ );
6230
+ }
6231
+
6232
+ public function cart_do_transaction($cart_id)
6233
+ {
6234
+ // Validate Ticket Availability
6235
+ $this->cart_validate($cart_id);
6236
+
6237
+ // Parent Function
6238
+ return $this->do_cart_transaction($cart_id, array(
6239
+ 'gateway' => 'MEC_gateway_free',
6240
+ ));
6241
+ }
6242
+ }
6243
+
6244
+ class MEC_gateway_bank_transfer extends MEC_gateway
6245
+ {
6246
+ public $id = 8;
6247
+ public $options;
6248
+
6249
+ public function __construct()
6250
+ {
6251
+ parent::__construct();
6252
+
6253
+ // Gateway options
6254
+ $this->options = $this->options();
6255
+
6256
+ // Register actions
6257
+ $this->factory->action('wp_ajax_mec_do_transaction_bank_transfer', array($this, 'do_transaction'));
6258
+ $this->factory->action('wp_ajax_nopriv_mec_do_transaction_bank_transfer', array($this, 'do_transaction'));
6259
+
6260
+ $this->factory->action('wp_ajax_mec_cart_do_transaction_bank_transfer', array($this, 'cart_do_transaction'));
6261
+ $this->factory->action('wp_ajax_nopriv_mec_cart_do_transaction_bank_transfer', array($this, 'cart_do_transaction'));
6262
+ }
6263
+
6264
+ public function label()
6265
+ {
6266
+ return __('Bank Transfer', 'modern-events-calendar-lite');
6267
+ }
6268
+
6269
+ public function color()
6270
+ {
6271
+ return '#2DCA73';
6272
+ }
6273
+
6274
+ public function options_form()
6275
+ {
6276
+ ?>
6277
+ <div class="mec-form-row mec-click-pay">
6278
+ <label>
6279
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][status]" value="0"/>
6280
+ <input onchange="jQuery('#mec_gateways<?php echo $this->id(); ?>_container_toggle').toggle();" value="1"
6281
+ type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][status]"
6282
+ <?php
6283
+ if (isset($this->options['status']) and $this->options['status']) {
6284
+ echo 'checked="checked"';
6285
+ }
6286
+ ?>
6287
+ /> <?php _e('Bank Transfer', 'modern-events-calendar-lite'); ?>
6288
+ </label>
6289
+ </div>
6290
+ <div id="mec_gateways<?php echo $this->id(); ?>_container_toggle" class="mec-gateway-options-form
6291
+ <?php
6292
+ if ((isset($this->options['status']) and !$this->options['status']) or !isset($this->options['status'])) {
6293
+ echo 'mec-util-hidden';
6294
+ }
6295
+ ?>">
6296
+ <div class="mec-form-row">
6297
+ <label class="mec-col-3"
6298
+ for="mec_gateways<?php echo $this->id(); ?>_title"><?php _e('Title', 'modern-events-calendar-lite'); ?></label>
6299
+ <div class="mec-col-9">
6300
+ <input type="text" id="mec_gateways<?php echo $this->id(); ?>_title"
6301
+ name="mec[gateways][<?php echo $this->id(); ?>][title]"
6302
+ value="<?php echo (isset($this->options['title']) and trim($this->options['title'])) ? $this->options['title'] : ''; ?>"
6303
+ placeholder="<?php echo $this->label(); ?>"/>
6304
+ </div>
6305
+ </div>
6306
+ <div class="mec-form-row">
6307
+ <label class="mec-col-3"
6308
+ for="mec_gateways<?php echo $this->id(); ?>_comment"><?php _e('Comment', 'modern-events-calendar-lite'); ?></label>
6309
+ <div class="mec-col-9">
6310
+ <textarea id="mec_gateways<?php echo $this->id(); ?>_comment"
6311
+ name="mec[gateways][<?php echo $this->id(); ?>][comment]"><?php echo (isset($this->options['comment']) and trim($this->options['comment'])) ? stripslashes($this->options['comment']) : esc_html__('Bank Transfer Description', 'modern-events-calendar-lite'); ?></textarea>
6312
+ <span class="mec-tooltip">
6313
+ <div class="box left">
6314
+ <h5 class="title"><?php _e('Comment', 'modern-events-calendar-lite'); ?></h5>
6315
+ <div class="content"><p><?php esc_attr_e('HTML allowed.', 'modern-events-calendar-lite'); ?><a
6316
+ href="https://webnus.net/dox/modern-events-calendar/booking/"
6317
+ target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
6318
+ </div>
6319
+ <i title="" class="dashicons-before dashicons-editor-help"></i>
6320
+ </span>
6321
+ </div>
6322
+ </div>
6323
+ <div class="mec-form-row">
6324
+ <label class="mec-col-3" for="mec_gateways<?php echo $this->id(); ?>_index"><?php _e('Position', 'modern-events-calendar-lite'); ?></label>
6325
+ <div class="mec-col-9">
6326
+ <input type="number" min="0" step="1" id="mec_gateways<?php echo $this->id(); ?>_index"
6327
+ name="mec[gateways][<?php echo $this->id(); ?>][index]"
6328
+ value="<?php echo (isset($this->options['index']) and trim($this->options['index'])) ? $this->options['index'] : 8; ?>"
6329
+ placeholder="<?php echo esc_attr__('Position', 'modern-events-calendar-lite'); ?>"/>
6330
+ </div>
6331
+ </div>
6332
+ <div class="mec-form-row">
6333
+ <label class="mec-col-12">
6334
+ <input type="hidden" name="mec[gateways][<?php echo $this->id(); ?>][disable_auto_confirmation]" value="0">
6335
+ <input value="1" type="checkbox" name="mec[gateways][<?php echo $this->id(); ?>][disable_auto_confirmation]" <?php echo (isset($this->options['disable_auto_confirmation']) and trim($this->options['disable_auto_confirmation'])) ? 'checked="checked"' : ''; ?>>
6336
+ <?php _e('Disable Auto Confirmation', 'modern-events-calendar-lite'); ?>
6337
+ </label>
6338
+ </div>
6339
+ </div>
6340
+ <?php
6341
+ }
6342
+
6343
+ public function checkout_form($transaction_id, $params = array())
6344
+ {
6345
+ ?>
6346
+ <script type="text/javascript">
6347
+ jQuery("#mec_do_transaction_bank_transfer_form<?php echo $transaction_id; ?>").on("submit", function(event)
6348
+ {
6349
+ event.preventDefault();
6350
+ jQuery(this).find('button').attr('disabled', true);
6351
+
6352
+ // Add loading Class to the button
6353
+ jQuery("#mec_do_transaction_bank_transfer_form<?php echo $transaction_id; ?> button[type=submit]").addClass("loading");
6354
+ jQuery("#mec_do_transaction_bank_transfer_message<?php echo $transaction_id; ?>").removeClass("mec-success mec-error").hide();
6355
+
6356
+ var data = jQuery("#mec_do_transaction_bank_transfer_form<?php echo $transaction_id; ?>").serialize();
6357
+ jQuery.ajax(
6358
+ {
6359
+ type: "GET",
6360
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
6361
+ data: data,
6362
+ dataType: "JSON",
6363
+ success: function (data)
6364
+ {
6365
+ // Remove the loading Class from the button
6366
+ jQuery("#mec_do_transaction_bank_transfer_form<?php echo $transaction_id; ?> button[type=submit]").removeClass("loading");
6367
+
6368
+ jQuery("#mec_do_transaction_bank_transfer_form<?php echo $transaction_id; ?>").hide();
6369
+ jQuery(".mec-book-form-gateway-label").remove();
6370
+
6371
+ if(data.success)
6372
+ {
6373
+ jQuery(".mec-book-form-coupon").hide();
6374
+ jQuery(".mec-gateway-comment").hide();
6375
+
6376
+ jQuery("#mec-book-form-back-btn-step-3").remove();
6377
+ jQuery("#mec_do_transaction_bank_transfer_message<?php echo $transaction_id; ?>").addClass("mec-success").html(data.message).show();
6378
+
6379
+ // Show Invoice Link
6380
+ if(typeof data.data.invoice_link !== "undefined" && data.data.invoice_link != "")
6381
+ {
6382
+ jQuery("#mec_do_transaction_bank_transfer_message<?php echo $transaction_id; ?>").append(' <a class="mec-invoice-download" href="' + data.data.invoice_link + '"><?php echo esc_js(__('Download Invoice', 'modern-events-calendar-lite')); ?></a>');
6383
+ }
6384
+
6385
+ // Show Downloadable Link
6386
+ if(typeof data.data.dl_file_link !== "undefined" && data.data.dl_file_link != "")
6387
+ {
6388
+ jQuery("#mec_do_transaction_bank_transfer_message<?php echo $transaction_id; ?>").append(' — <a class="mec-dl-file-download" href="' + data.data.dl_file_link + '"><?php echo esc_js(__('Download File', 'modern-events-calendar-lite')); ?></a>');
6389
+ }
6390
+
6391
+ // Show Extra info
6392
+ if(typeof data.data.extra_info !== "undefined" && data.data.extra_info != "" && data.data.extra_info != null)
6393
+ {
6394
+ jQuery("#mec_do_transaction_bank_transfer_message<?php echo $transaction_id; ?>").append('<div>' + data.data.extra_info+'</div>');
6395
+ }
6396
+
6397
+ // Redirect to thank you page
6398
+ if (typeof data.data.redirect_to != "undefined" && data.data.redirect_to != "") {
6399
+ setTimeout(function () {
6400
+ window.location.href = data.data.redirect_to;
6401
+ }, <?php echo $this->main->get_thankyou_page_time($transaction_id); ?>);
6402
+ }
6403
+ jQuery(this).find('button').removeAttr('disabled');
6404
+ }
6405
+ else
6406
+ {
6407
+ jQuery("#mec_do_transaction_bank_transfer_message<?php echo $transaction_id; ?>").addClass("mec-error").html(data.message).show();
6408
+ }
6409
+ },
6410
+ error: function(jqXHR, textStatus, errorThrown)
6411
+ {
6412
+ // Remove the loading Class from the button
6413
+ jQuery("#mec_do_transaction_bank_transfer_form<?php echo $transaction_id; ?> button[type=submit]").removeClass("loading");
6414
+ }
6415
+ });
6416
+ });
6417
+ </script>
6418
+ <div class="mec-gateway-message mec-util-hidden"
6419
+ id="mec_do_transaction_bank_transfer_message<?php echo $transaction_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
6420
+ <form id="mec_do_transaction_bank_transfer_form<?php echo $transaction_id; ?>" class="mec-click-pay">
6421
+ <input type="hidden" name="action" value="mec_do_transaction_bank_transfer"/>
6422
+ <input type="hidden" name="transaction_id" value="<?php echo $transaction_id; ?>"/>
6423
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
6424
+ <?php wp_nonce_field('mec_transaction_form_' . $transaction_id); ?>
6425
+ <button class="mec-book-form-next-button" type="submit"><?php _e('Submit', 'modern-events-calendar-lite'); ?></button>
6426
+ <?php do_action('mec_booking_checkout_form_before_end', $transaction_id); ?>
6427
+ </form>
6428
+ <?php
6429
+ }
6430
+
6431
+ public function do_transaction($transaction_id = null)
6432
+ {
6433
+ if(!trim($transaction_id)) $transaction_id = isset($_GET['transaction_id']) ? sanitize_text_field($_GET['transaction_id']) : 0;
6434
+
6435
+ // Verify that the nonce is valid.
6436
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_transaction_form_' . $transaction_id))
6437
+ {
6438
+ $this->response(array(
6439
+ 'success' => 0,
6440
+ 'code' => 'NONCE_IS_INVALID',
6441
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
6442
+ ));
6443
+ }
6444
+
6445
+ // Validate Ticket Availability
6446
+ $this->validate($transaction_id);
6447
+
6448
+ $transaction = $this->book->get_transaction($transaction_id);
6449
+ $attendees = isset($transaction['tickets']) ? $transaction['tickets'] : array();
6450
+
6451
+ $attention_date = isset($transaction['date']) ? $transaction['date'] : '';
6452
+ $attention_times = explode(':', $attention_date);
6453
+ $date = date('Y-m-d H:i:s', trim($attention_times[0]));
6454
+
6455
+ // Is there any attendee?
6456
+ if (!count($attendees)) {
6457
+ $this->response(
6458
+ array(
6459
+ 'success' => 0,
6460
+ 'code' => 'NO_TICKET',
6461
+ 'message' => __(
6462
+ 'There is no attendee for booking!',
6463
+ 'mec'
6464
+ ),
6465
+ )
6466
+ );
6467
+ }
6468
+
6469
+ $main_attendee = isset($attendees[0]) ? $attendees[0] : array();
6470
+ $name = isset($main_attendee['name']) ? $main_attendee['name'] : '';
6471
+
6472
+ $ticket_ids = '';
6473
+ $attendees_info = array();
6474
+
6475
+ foreach($attendees as $i => $attendee)
6476
+ {
6477
+ if(!is_numeric($i)) continue;
6478
+
6479
+ $ticket_ids .= $attendee['id'] . ',';
6480
+ if(!array_key_exists($attendee['email'], $attendees_info)) $attendees_info[$attendee['email']] = array('count' => $attendee['count']);
6481
+ else $attendees_info[$attendee['email']]['count'] = ($attendees_info[$attendee['email']]['count'] + $attendee['count']);
6482
+ }
6483
+
6484
+ $ticket_ids = ',' . trim($ticket_ids, ', ') . ',';
6485
+ $user_id = $this->register_user($main_attendee, $transaction);
6486
+
6487
+ // Remove Sensitive Data
6488
+ if(isset($transaction['username']) or isset($transaction['password']))
6489
+ {
6490
+ unset($transaction['username']);
6491
+ unset($transaction['password']);
6492
+
6493
+ $this->book->update_transaction($transaction_id, $transaction);
6494
+ }
6495
+
6496
+ // MEC User
6497
+ $u = $this->getUser();
6498
+
6499
+ $book_subject = $name.' - '.(isset($main_attendee['email']) ? $main_attendee['email'] : $u->get($user_id)->user_email);
6500
+ $book_id = $this->book->add(
6501
+ array(
6502
+ 'post_author' => $user_id,
6503
+ 'post_type' => $this->PT,
6504
+ 'post_title' => $book_subject,
6505
+ 'post_date' => $date,
6506
+ 'attendees_info' => $attendees_info,
6507
+ 'mec_attendees' => $attendees,
6508
+ 'mec_gateway' => 'MEC_gateway_bank_transfer',
6509
+ 'mec_gateway_label' => $this->title()
6510
+ ),
6511
+ $transaction_id,
6512
+ $ticket_ids
6513
+ );
6514
+
6515
+ // Assign User
6516
+ $u->assign($book_id, $user_id);
6517
+
6518
+ // Fires after completely creating a new booking
6519
+ do_action('mec_booking_completed', $book_id);
6520
+
6521
+ $event_id = (isset($transaction['event_id']) ? $transaction['event_id'] : 0);
6522
+ $redirect_to = '';
6523
+
6524
+ $thankyou_page_id = $this->main->get_thankyou_page_id($event_id);
6525
+ if($thankyou_page_id) $redirect_to = $this->book->get_thankyou_page($thankyou_page_id, $transaction_id);
6526
+
6527
+ // Invoice Link
6528
+ $mec_confirmed = get_post_meta($book_id, 'mec_confirmed', true);
6529
+ $invoice_link = (!$mec_confirmed) ? '' : $this->book->get_invoice_link($transaction_id);
6530
+ $dl_file_link = (!$mec_confirmed) ? '' : $this->book->get_dl_file_link($book_id);
6531
+
6532
+ $extra_info = apply_filters('MEC_extra_info_gateways', '', $this->book->get_event_id_by_transaction_id($transaction_id), $book_id);
6533
+
6534
+ $this->response(
6535
+ array(
6536
+ 'success' => 1,
6537
+ 'message' => stripslashes($this->main->m('book_success_message', __('Thank you for booking. Your tickets are booked, booking verification might be needed, please check your email.', 'modern-events-calendar-lite'))),
6538
+ 'data' => array(
6539
+ 'book_id' => $book_id,
6540
+ 'redirect_to' => $redirect_to,
6541
+ 'invoice_link' => $invoice_link,
6542
+ 'dl_file_link' => $dl_file_link,
6543
+ 'extra_info' => $extra_info,
6544
+ ),
6545
+ )
6546
+ );
6547
+ }
6548
+
6549
+ public function cart_checkout_form($cart_id, $params = array())
6550
+ {
6551
+ ?>
6552
+ <div class="mec-gateway-message mec-util-hidden" id="mec_do_cart_bank_transfer_message<?php echo $cart_id; ?>"><?php do_action('mec_extra_info_payment'); ?></div>
6553
+ <form id="mec_do_cart_bank_transfer_form<?php echo $cart_id; ?>" class="mec-click-pay">
6554
+ <input type="hidden" name="action" value="mec_cart_do_transaction_bank_transfer"/>
6555
+ <input type="hidden" name="cart_id" value="<?php echo $cart_id; ?>"/>
6556
+ <input type="hidden" name="gateway_id" value="<?php echo $this->id(); ?>"/>
6557
+ <?php wp_nonce_field('mec_cart_form_' . $cart_id); ?>
6558
+ <button class="mec-book-form-next-button" type="submit"><?php _e('Submit', 'modern-events-calendar-lite'); ?></button>
6559
+ <?php do_action('mec_cart_checkout_form_before_end', $cart_id); ?>
6560
+ </form>
6561
+ <script type="text/javascript">
6562
+ jQuery("#mec_do_cart_bank_transfer_form<?php echo $cart_id; ?>").on("submit", function(event)
6563
+ {
6564
+ event.preventDefault();
6565
+ jQuery(this).find('button').attr('disabled', true);
6566
+
6567
+ // Add loading Class to the button
6568
+ jQuery("#mec_do_cart_bank_transfer_form<?php echo $cart_id; ?> button[type=submit]").addClass("loading");
6569
+ jQuery("#mec_do_cart_bank_transfer_message<?php echo $cart_id; ?>").removeClass("mec-success mec-error").hide();
6570
+
6571
+ var data = jQuery("#mec_do_cart_bank_transfer_form<?php echo $cart_id; ?>").serialize();
6572
+ jQuery.ajax(
6573
+ {
6574
+ type: "GET",
6575
+ url: "<?php echo admin_url('admin-ajax.php', null); ?>",
6576
+ data: data,
6577
+ dataType: "JSON",
6578
+ success: function (data)
6579
+ {
6580
+ // Remove the loading Class from the button
6581
+ jQuery("#mec_do_cart_bank_transfer_form<?php echo $cart_id; ?> button[type=submit]").removeClass("loading");
6582
+
6583
+ if(data.success)
6584
+ {
6585
+ jQuery("#mec_do_cart_bank_transfer_form<?php echo $cart_id; ?>").hide();
6586
+ jQuery(".mec-checkout-form-gateway-label").remove();
6587
+
6588
+ jQuery(".mec-gateway-comment").hide();
6589
+ jQuery("#mec_do_cart_bank_transfer_message<?php echo $cart_id; ?>").addClass("mec-success").html(data.message).show();
6590
+
6591
+ jQuery(this).find('button').removeAttr('disabled');
6592
+ }
6593
+ else
6594
+ {
6595
+ jQuery("#mec_do_cart_bank_transfer_message<?php echo $cart_id; ?>").addClass("mec-error").html(data.message).show();
6596
+ }
6597
+ },
6598
+ error: function(jqXHR, textStatus, errorThrown)
6599
+ {
6600
+ // Remove the loading Class from the button
6601
+ jQuery("#mec_do_cart_bank_transfer_form<?php echo $cart_id; ?> button[type=submit]").removeClass("loading");
6602
+ }
6603
+ });
6604
+ });
6605
+ </script>
6606
+ <?php
6607
+ }
6608
+
6609
+ public function cart_do_transaction()
6610
+ {
6611
+ $cart_id = isset($_GET['cart_id']) ? sanitize_text_field($_GET['cart_id']) : NULL;
6612
+
6613
+ // Verify that the nonce is valid.
6614
+ if(!wp_verify_nonce(sanitize_text_field($_GET['_wpnonce']), 'mec_cart_form_' . $cart_id))
6615
+ {
6616
+ $this->response(array(
6617
+ 'success' => 0,
6618
+ 'code' => 'NONCE_IS_INVALID',
6619
+ 'message' => __('Request is invalid!', 'modern-events-calendar-lite'),
6620
+ ));
6621
+ }
6622
+
6623
+ // Validate Ticket Availability
6624
+ $this->cart_validate($cart_id);
6625
+
6626
+ // Parent Function
6627
+ $this->response($this->do_cart_transaction($cart_id, array(
6628
+ 'gateway' => 'MEC_gateway_bank_transfer',
6629
+ )));
6630
+ }
6631
+ }
app/features/gateways/paypal_ipn_cart.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
- /**
3
- * WordPress initializing
4
- */
5
- function mec_find_wordpress_base_path()
6
- {
7
- $dir = dirname(__FILE__);
8
-
9
- do
10
- {
11
- if(file_exists($dir.'/wp-load.php') and file_exists($dir.'/wp-config.php')) return $dir;
12
- }
13
- while($dir = realpath($dir.'/..'));
14
-
15
- return NULL;
16
- }
17
-
18
- define('BASE_PATH', mec_find_wordpress_base_path().'/');
19
- define('WP_USE_THEMES', false);
20
-
21
- global $wp, $wp_query, $wp_the_query, $wp_rewrite, $wp_did_header;
22
- require(BASE_PATH.'wp-load.php');
23
-
24
- // exit if request method is GET
25
- if(!isset($_SERVER['REQUEST_METHOD']) or (isset($_SERVER['REQUEST_METHOD']) and $_SERVER['REQUEST_METHOD'] == 'GET')) exit;
26
-
27
- $model = new MEC_gateway_paypal_express();
28
-
29
- $POST = array_map('stripslashes', $_POST);
30
- $verified = $model->cart_validate_express_payment($POST);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/features/mec.php CHANGED
@@ -192,41 +192,61 @@ class MEC_feature_mec extends MEC_base
192
  /* Activate License */
193
  public function activate_license()
194
  {
195
- // Current User is not Permitted
196
- if(!current_user_can('manage_options')) $this->main->response(array('success'=>0, 'code'=>'ADMIN_ONLY'));
197
-
198
- if(!wp_verify_nonce($_REQUEST['nonce'], 'mec_settings_nonce'))
199
  {
200
- exit();
201
- }
202
 
203
- $options = get_option('mec_options');
204
 
205
- $options['product_name'] = $_REQUEST['content']['LicenseTypeJson'];
206
- $options['purchase_code'] = $_REQUEST['content']['PurchaseCodeJson'];
 
207
 
208
- $verify = NULL;
209
- if($this->getPRO())
210
- {
211
- $envato = $this->getEnvato();
212
- $verify = $envato->get_MEC_info('activation');
213
- }
214
 
215
- if(!is_null($verify->item_link))
216
- {
217
- $LicenseStatus = 'success';
218
- update_option( 'mec_license_status', 'active');
219
- $options['product_id'] = $verify->item_id;
220
- }
221
- else
222
- {
223
- $LicenseStatus = __('Activation failed. Please check your purchase code or license type.<br><b>Note: Your purchase code should match your licesne type.</b>', 'modern-events-calendar-lite') . '<a style="text-decoration: underline; padding-left: 7px;" href="https://webnus.net/dox/modern-events-calendar/auto-update-issue/" target="_blank">' . __('Troubleshooting', 'modern-events-calendar-lite') . '</a>';
224
- update_option( 'mec_license_status', 'faild');
 
 
 
 
 
 
225
  }
 
226
 
227
- update_option( 'mec_options', $options);
228
- echo $LicenseStatus;
229
- wp_die();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  }
231
 
232
  /* Download MEC settings */
@@ -1618,7 +1638,8 @@ class MEC_feature_mec extends MEC_base
1618
 
1619
  public function register_assets_per_page_meta_boxes()
1620
  {
1621
- add_meta_box('mec_metabox_app', __('Include MEC Assets', 'modern-events-calendar-lite'), array($this, 'meta_box_assets_per_page'), 'page', 'side', 'low');
 
1622
  }
1623
 
1624
  public function meta_box_assets_per_page($post)
@@ -1640,8 +1661,10 @@ class MEC_feature_mec extends MEC_base
1640
  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
1641
  if(defined('DOING_AUTOSAVE') and DOING_AUTOSAVE) return;
1642
 
1643
- // Not a Page
1644
- if($post->post_type != 'page') return;
 
 
1645
 
1646
  if(isset($_POST['mec_include_assets']))
1647
  {
@@ -1660,10 +1683,15 @@ class MEC_feature_mec extends MEC_base
1660
  global $post;
1661
 
1662
  $status_per_page = 1;
1663
- if($post and isset($post->post_type) and $post->post_type === 'page')
1664
  {
1665
- $status_per_page = get_post_meta($post->ID, 'mec_include_assets', true);
1666
- if(trim($status_per_page) == '') $status_per_page = 0;
 
 
 
 
 
1667
  }
1668
 
1669
  $status = (boolean) $status_per_page;
@@ -1672,6 +1700,11 @@ class MEC_feature_mec extends MEC_base
1672
  return $status;
1673
  }
1674
 
 
 
 
 
 
1675
  public function page_title($title)
1676
  {
1677
  // Occurrences Status
192
  /* Activate License */
193
  public function activate_license()
194
  {
195
+ if($this->getPRO())
 
 
 
196
  {
197
+ // Current User is not Permitted
198
+ if(!current_user_can('manage_options')) $this->main->response(array('success'=>0, 'code'=>'ADMIN_ONLY'));
199
 
200
+ if(!wp_verify_nonce($_REQUEST['nonce'], 'mec_settings_nonce')) exit();
201
 
202
+ $options = get_option('mec_options');
203
+ $options['product_name'] = $_REQUEST['content']['LicenseTypeJson'];
204
+ $options['purchase_code'] = $_REQUEST['content']['PurchaseCodeJson'];
205
 
206
+ $verify = NULL;
207
+ $verify = $this->plugin_activation_request($options);
 
 
 
 
208
 
209
+ if($verify and !is_null($verify) and isset($verify->item_link) and !is_null($verify->item_link))
210
+ {
211
+ $LicenseStatus = 'success';
212
+ update_option('mec_license_status', 'active');
213
+ $options['product_id'] = $verify->item_id;
214
+ }
215
+ else
216
+ {
217
+ $LicenseStatus = __('Activation failed. Please check your purchase code or license type.<br><b>Note: Your purchase code should match your licesne type.</b>', 'modern-events-calendar-lite') . '<a style="text-decoration: underline; padding-left: 7px;" href="https://webnus.net/dox/modern-events-calendar/auto-update-issue/" target="_blank">' . __('Troubleshooting', 'modern-events-calendar-lite') . '</a>';
218
+ update_option('mec_license_status', 'faild');
219
+ }
220
+
221
+
222
+ update_option( 'mec_options', $options);
223
+ echo $LicenseStatus;
224
+ wp_die();
225
  }
226
+ }
227
 
228
+ // MEC activation request
229
+ public function plugin_activation_request($options)
230
+ {
231
+ $code = $options['purchase_code'];
232
+ $product_name = $options['product_name'];
233
+ $item_id = $options['product_id'];
234
+ $url = get_home_url();
235
+
236
+ $verify_url = MEC_API_URL . '/activation/verify?category=mec&license=' . $code . '&url=' . $url . '&item_id=' . $item_id;
237
+
238
+ $JSON = wp_remote_retrieve_body(wp_remote_get($verify_url, array(
239
+ 'body' => null,
240
+ 'timeout' => '120',
241
+ 'redirection' => '10',
242
+ 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
243
+ )));
244
+
245
+ if($JSON != ''){
246
+ $data = json_decode($JSON);
247
+ return $data;
248
+ }
249
+ else return false;
250
  }
251
 
252
  /* Download MEC settings */
1638
 
1639
  public function register_assets_per_page_meta_boxes()
1640
  {
1641
+ $post_types = $this->assets_per_page_post_types();
1642
+ add_meta_box('mec_metabox_app', __('Include MEC Assets', 'modern-events-calendar-lite'), array($this, 'meta_box_assets_per_page'), $post_types, 'side', 'low');
1643
  }
1644
 
1645
  public function meta_box_assets_per_page($post)
1661
  // If this is an autosave, our form has not been submitted, so we don't want to do anything.
1662
  if(defined('DOING_AUTOSAVE') and DOING_AUTOSAVE) return;
1663
 
1664
+ $post_types = $this->assets_per_page_post_types();
1665
+
1666
+ // Not a Supported Post Type
1667
+ if(!in_array($post->post_type, $post_types)) return;
1668
 
1669
  if(isset($_POST['mec_include_assets']))
1670
  {
1683
  global $post;
1684
 
1685
  $status_per_page = 1;
1686
+ if($post)
1687
  {
1688
+ $post_types = $this->assets_per_page_post_types();
1689
+
1690
+ if(isset($post->post_type) and in_array($post->post_type, $post_types))
1691
+ {
1692
+ $status_per_page = get_post_meta($post->ID, 'mec_include_assets', true);
1693
+ if(trim($status_per_page) == '') $status_per_page = 0;
1694
+ }
1695
  }
1696
 
1697
  $status = (boolean) $status_per_page;
1700
  return $status;
1701
  }
1702
 
1703
+ public function assets_per_page_post_types()
1704
+ {
1705
+ return apply_filters('mec_assets_per_page_post_types', array('page', 'post', 'forum', 'topic', 'reply'));
1706
+ }
1707
+
1708
  public function page_title($title)
1709
  {
1710
  // Occurrences Status
app/features/mec/booking.php CHANGED
@@ -977,6 +977,11 @@ $gateways_options = $this->main->get_gateways_options();
977
  </label>
978
  <p><?php esc_html_e("By enabling this feature, tickets will be added to WooCommerce cart and all payment process would be done by WooCommerce so all of MEC payment related modules will be disabled. To configure your desired gateways and booking fields etc, you need to configure WooCommerce on your website.", 'modern-events-calendar-lite'); ?></p>
979
  <div id="mec_gateways_wc_status_guide" class="<?php if(!isset($settings['wc_status']) or (isset($settings['wc_status']) and !$settings['wc_status'])) echo 'w-hidden'; ?>">
 
 
 
 
 
980
  <p><?php esc_html_e("You cannot use following MEC features so you should use WooCommerc and its addons if you need them.", 'modern-events-calendar-lite'); ?></p>
981
  <ul>
982
  <li><?php esc_html_e('Payment gateways', 'modern-events-calendar-lite'); ?></li>
@@ -1105,7 +1110,7 @@ $gateways_options = $this->main->get_gateways_options();
1105
  <div class="mec-col-12">
1106
  <label>
1107
  <input type="hidden" name="mec[settings][mec_cart_status]" value="0" />
1108
- <input id="mec_gateways_mec_cart_status" onchange="jQuery('#mec_gateways_mec_cart_status_guide').toggleClass('w-hidden');" value="1" type="checkbox" name="mec[settings][mec_cart_status]" <?php if(isset($settings['mec_cart_status']) and $settings['mec_cart_status']) echo 'checked="checked"'; ?> /> <?php _e('Use MEC Cart System', 'modern-events-calendar-lite'); ?>
1109
  </label>
1110
  <p><?php esc_html_e("If you don't want to use WooCommerce for any reason you can use MEC Cart for adding a simple cart and checkout system to your website.", 'modern-events-calendar-lite'); ?></p>
1111
  <div id="mec_gateways_mec_cart_status_guide" class="<?php if(!isset($settings['mec_cart_status']) or (isset($settings['mec_cart_status']) and !$settings['mec_cart_status'])) echo 'w-hidden'; ?>">
977
  </label>
978
  <p><?php esc_html_e("By enabling this feature, tickets will be added to WooCommerce cart and all payment process would be done by WooCommerce so all of MEC payment related modules will be disabled. To configure your desired gateways and booking fields etc, you need to configure WooCommerce on your website.", 'modern-events-calendar-lite'); ?></p>
979
  <div id="mec_gateways_wc_status_guide" class="<?php if(!isset($settings['wc_status']) or (isset($settings['wc_status']) and !$settings['wc_status'])) echo 'w-hidden'; ?>">
980
+
981
+ <?php if(isset($settings['mec_cart_status']) and $settings['mec_cart_status']): ?>
982
+ <p class="mec-error" id="mec_wc_status_mec_cart_error"><?php esc_html_e("Please disable MEC Cart first otherwise you're not able to use WooCommerce feature.", 'modern-events-calendar-lite'); ?></p>
983
+ <?php endif; ?>
984
+
985
  <p><?php esc_html_e("You cannot use following MEC features so you should use WooCommerc and its addons if you need them.", 'modern-events-calendar-lite'); ?></p>
986
  <ul>
987
  <li><?php esc_html_e('Payment gateways', 'modern-events-calendar-lite'); ?></li>
1110
  <div class="mec-col-12">
1111
  <label>
1112
  <input type="hidden" name="mec[settings][mec_cart_status]" value="0" />
1113
+ <input id="mec_gateways_mec_cart_status" onchange="jQuery('#mec_gateways_mec_cart_status_guide, #mec_wc_status_mec_cart_error').toggleClass('w-hidden');" value="1" type="checkbox" name="mec[settings][mec_cart_status]" <?php if(isset($settings['mec_cart_status']) and $settings['mec_cart_status']) echo 'checked="checked"'; ?> /> <?php _e('Use MEC Cart System', 'modern-events-calendar-lite'); ?>
1114
  </label>
1115
  <p><?php esc_html_e("If you don't want to use WooCommerce for any reason you can use MEC Cart for adding a simple cart and checkout system to your website.", 'modern-events-calendar-lite'); ?></p>
1116
  <div id="mec_gateways_mec_cart_status_guide" class="<?php if(!isset($settings['mec_cart_status']) or (isset($settings['mec_cart_status']) and !$settings['mec_cart_status'])) echo 'w-hidden'; ?>">
app/features/mec/dashboard.php CHANGED
@@ -27,15 +27,7 @@ $user_organizer_count_l = wp_count_terms('mec_organizer', array(
27
 
28
  $version = $verify = NULL;
29
 
30
- if($this->getPRO())
31
- {
32
- // Get MEC New Update
33
- $envato = $this->getEnvato();
34
-
35
- $v = $envato->get_MEC_info('version');
36
- $version = isset($v->version) ? $v->version : NULL;
37
- //$verify = $envato->get_MEC_info('activate');
38
-
39
  $mec_license_status = get_option( 'mec_license_status');
40
  }
41
 
@@ -66,15 +58,6 @@ $box_stats = apply_filters('mec_dashboard_box_stats', true);
66
  <?php if(!$this->getPRO()): ?>
67
  <span><a href="https://wordpress.org/support/plugin/modern-events-calendar-lite/reviews/#new-post" target="_blank"><?php echo _x('Rate the plugin ★★★★★', 'plugin rate', 'modern-events-calendar-lite'); ?></a></span>
68
  <?php endif; ?>
69
- <?php if(version_compare(MEC_VERSION, $version, '<')): ?>
70
- <span class="mec-tooltip">
71
- <div class="box">
72
- <h5 class="title"><?php _e('Update', 'modern-events-calendar-lite'); ?></h5>
73
- <div class="content"><p><?php esc_attr_e("Update $version is ready for download.", 'modern-events-calendar-lite'); ?><a href="https://webnus.net/dox/modern-events-calendar/category/installation/" target="_blank"><?php _e('Read More', 'modern-events-calendar-lite'); ?></a></p></div>
74
- </div>
75
- <i title="" class="dashicons-before dashicons-editor-help"></i>
76
- </span>
77
- <?php endif; ?>
78
  <!-- </p> -->
79
  </div>
80
  </div>
27
 
28
  $version = $verify = NULL;
29
 
30
+ if($this->getPRO()){
 
 
 
 
 
 
 
 
31
  $mec_license_status = get_option( 'mec_license_status');
32
  }
33
 
58
  <?php if(!$this->getPRO()): ?>
59
  <span><a href="https://wordpress.org/support/plugin/modern-events-calendar-lite/reviews/#new-post" target="_blank"><?php echo _x('Rate the plugin ★★★★★', 'plugin rate', 'modern-events-calendar-lite'); ?></a></span>
60
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
61
  <!-- </p> -->
62
  </div>
63
  </div>
app/features/profile/profile.php CHANGED
@@ -112,6 +112,9 @@ $id = 1;
112
  $check_event_exist = $db->select("SELECT `ID` FROM `#__posts` WHERE `ID`={$event_id}", 'loadResult');
113
 
114
  $event = trim($check_event_exist) ? $render->data($event_id) : array();
 
 
 
115
  ?>
116
  <tr id="mec_profile_booking_<?php echo $ID; ?>">
117
  <td>
@@ -129,7 +132,15 @@ $id = 1;
129
  <span class="mec-event-date">
130
  <div class="mec-tooltip">
131
  <div class="box">
 
 
 
 
 
 
 
132
  <?php echo trim(date($datetime_format, $start_time).' - '.date($datetime_format, $end_time), '- '); ?>
 
133
  </div>
134
  <i class="mec-sl-calendar"></i>
135
  </div>
112
  $check_event_exist = $db->select("SELECT `ID` FROM `#__posts` WHERE `ID`={$event_id}", 'loadResult');
113
 
114
  $event = trim($check_event_exist) ? $render->data($event_id) : array();
115
+
116
+ // Multiple Dates
117
+ $all_dates = (isset($transaction['all_dates']) and is_array($transaction['all_dates'])) ? $transaction['all_dates'] : array();
118
  ?>
119
  <tr id="mec_profile_booking_<?php echo $ID; ?>">
120
  <td>
132
  <span class="mec-event-date">
133
  <div class="mec-tooltip">
134
  <div class="box">
135
+ <?php if(count($all_dates)): ?>
136
+ <span>
137
+ <?php foreach($all_dates as $all_date): $all_date_ex = explode(':', $all_date); ?>
138
+ <?php echo trim(date($datetime_format, $all_date_ex[0]).' - '.date($datetime_format, $all_date_ex[1]), '- '); ?><br>
139
+ <?php endforeach; ?>
140
+ </span>
141
+ <?php else: ?>
142
  <?php echo trim(date($datetime_format, $start_time).' - '.date($datetime_format, $end_time), '- '); ?>
143
+ <?php endif; ?>
144
  </div>
145
  <i class="mec-sl-calendar"></i>
146
  </div>
app/features/schema.php CHANGED
@@ -217,8 +217,7 @@ class MEC_feature_schema extends MEC_base
217
 
218
  if(!in_array($event_status, array('EventScheduled', 'EventPostponed', 'EventCancelled', 'EventMovedOnline'))) $event_status = 'EventScheduled';
219
 
220
- $cost = isset($event->data->meta['mec_cost']) ? preg_replace("/[^0-9.]/", '', $event->data->meta['mec_cost']) : '';
221
- $cost = (isset($params['cost']) and trim($params['cost']) != '') ? preg_replace("/[^0-9.]/", '', $params['cost']) : $cost;
222
 
223
  $location_id = $this->main->get_master_location_id($event);
224
  $location = ($location_id ? $this->main->get_location_data($location_id) : array());
@@ -266,7 +265,7 @@ class MEC_feature_schema extends MEC_base
266
  {
267
  "url": "<?php echo $event->data->permalink; ?>",
268
  "price": "<?php echo $cost ?>",
269
- "priceCurrency": "<?php echo isset($this->settings['currency']) ? $this->settings['currency'] : ''; ?>",
270
  "availability": "<?php echo ($soldout ? "https://schema.org/SoldOut" : "https://schema.org/InStock"); ?>",
271
  "validFrom": "<?php echo date('Y-m-d\TH:i', strtotime($event->date['start']['date'])); ?>"
272
  },
217
 
218
  if(!in_array($event_status, array('EventScheduled', 'EventPostponed', 'EventCancelled', 'EventMovedOnline'))) $event_status = 'EventScheduled';
219
 
220
+ $cost = $this->main->get_event_cost($event);
 
221
 
222
  $location_id = $this->main->get_master_location_id($event);
223
  $location = ($location_id ? $this->main->get_location_data($location_id) : array());
265
  {
266
  "url": "<?php echo $event->data->permalink; ?>",
267
  "price": "<?php echo $cost ?>",
268
+ "priceCurrency": "<?php echo $this->main->get_currency_code($event); ?>",
269
  "availability": "<?php echo ($soldout ? "https://schema.org/SoldOut" : "https://schema.org/InStock"); ?>",
270
  "validFrom": "<?php echo date('Y-m-d\TH:i', strtotime($event->date['start']['date'])); ?>"
271
  },
app/features/update.php CHANGED
@@ -46,8 +46,8 @@ class MEC_feature_update extends MEC_base
46
  $version = get_option('mec_version', '1.0.0');
47
 
48
  // It's updated to latest version
49
- if(version_compare($version, $this->main->get_version(), '>=')) return;
50
-
51
  // Run the updates one by one
52
  if(version_compare($version, '1.0.3', '<')) $this->version103();
53
  if(version_compare($version, '1.3.0', '<')) $this->version130();
@@ -77,9 +77,10 @@ class MEC_feature_update extends MEC_base
77
  if(version_compare($version, '5.19.1', '<')) $this->version5191();
78
  if(version_compare($version, '5.22.0', '<')) $this->version5220();
79
  if(version_compare($version, '6.0.0', '<')) $this->version600();
 
80
 
81
  // Update to latest version to prevent running the code twice
82
- update_option('mec_version', $this->main->get_version());
83
  }
84
 
85
  public function update_capabilities($capabilities)
@@ -653,4 +654,43 @@ class MEC_feature_update extends MEC_base
653
  // Add Records for Existing Bookings
654
  foreach($bookings as $booking) $bookingRecord->insert($booking);
655
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  }
46
  $version = get_option('mec_version', '1.0.0');
47
 
48
  // It's updated to latest version
49
+ //if(version_compare($version, $this->main->get_version(), '>=')) return;
50
+
51
  // Run the updates one by one
52
  if(version_compare($version, '1.0.3', '<')) $this->version103();
53
  if(version_compare($version, '1.3.0', '<')) $this->version130();
77
  if(version_compare($version, '5.19.1', '<')) $this->version5191();
78
  if(version_compare($version, '5.22.0', '<')) $this->version5220();
79
  if(version_compare($version, '6.0.0', '<')) $this->version600();
80
+ if(version_compare($version, '6.2.6', '>')) $this->version626();
81
 
82
  // Update to latest version to prevent running the code twice
83
+ //update_option('mec_version', $this->main->get_version());
84
  }
85
 
86
  public function update_capabilities($capabilities)
654
  // Add Records for Existing Bookings
655
  foreach($bookings as $booking) $bookingRecord->insert($booking);
656
  }
657
+
658
+ public function version626(){
659
+ // Get Options
660
+ $options = get_option('mec_options');
661
+ $code = $options['purchase_code'];
662
+ $item_id = $options['product_id'];
663
+ $url = get_home_url();
664
+
665
+ $reActivationOption = get_option( 'reActivationOption' );
666
+
667
+ if (is_null($code) || empty($code) || !isset($code) || $reActivationOption) return;
668
+
669
+ if ( !$reActivationOption ) {
670
+ $verify_url = MEC_API_URL . '/activation/verify?category=mec&license=' . $code . '&url=' . $url . '&item_id=' . $item_id;
671
+
672
+ $JSON = wp_remote_retrieve_body(wp_remote_get($verify_url, array(
673
+ 'body' => null,
674
+ 'timeout' => '120',
675
+ 'redirection' => '10',
676
+ 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
677
+ )));
678
+ if($JSON != ''){
679
+ $data = json_decode($JSON);
680
+ if($data and !is_null($data) and isset($data->item_link) and !is_null($data->item_link))
681
+ {
682
+ update_option('mec_license_status', 'active');
683
+ $options['product_id'] = $data->item_id;
684
+ update_option( 'mec_options', $options);
685
+ update_option( 'reActivationOption', '1' );
686
+ return;
687
+ }
688
+ else
689
+ {
690
+ update_option('mec_license_status', 'faild');
691
+ return;
692
+ }
693
+ }
694
+ }
695
+ }
696
  }
app/libraries/book.php CHANGED
@@ -1159,7 +1159,8 @@ class MEC_book extends MEC_base
1159
 
1160
  public function get_ticket_price($ticket, $date, $event_id)
1161
  {
1162
- return $this->get_ticket_price_key($ticket, $date, $event_id, 'price');
 
1163
  }
1164
 
1165
  public function get_ticket_price_key($ticket, $date, $event_id, $key)
1159
 
1160
  public function get_ticket_price($ticket, $date, $event_id)
1161
  {
1162
+ $price = $this->get_ticket_price_key($ticket, $date, $event_id, 'price');
1163
+ return (trim($price) ? $price : 0);
1164
  }
1165
 
1166
  public function get_ticket_price_key($ticket, $date, $event_id, $key)
app/libraries/envato.php DELETED
@@ -1,384 +0,0 @@
1
- <?php
2
- /** no direct access **/
3
- defined('MECEXEC') or die();
4
-
5
- /**
6
- * Webnus MEC envato class.
7
- * @author Webnus <info@webnus.biz>
8
- */
9
- class MEC_envato extends MEC_base
10
- {
11
- /**
12
- * The plugin current version
13
- */
14
- public $current_version = MEC_VERSION;
15
-
16
- /**
17
- * The plugin ite, id
18
- */
19
- public $itemid = '';
20
-
21
- /**
22
- * The plugin url
23
- */
24
- public $itemurl = '';
25
-
26
- /**
27
- * User for cashing directory
28
- */
29
- public $purchase_code = '';
30
-
31
- /**
32
- * Product name
33
- */
34
- public $product_name = '';
35
-
36
- /**
37
- * The plugin remote update path
38
- */
39
- public $update_path = '';
40
-
41
- /**
42
- * Plugin Slug
43
- */
44
- public $plugin_slug = MEC_BASENAME;
45
-
46
- public $options = '';
47
- public $license_status = '';
48
-
49
- /**
50
- * Plugin name
51
- */
52
- public $slug;
53
-
54
- public $main;
55
- public $factory;
56
- public $settings;
57
-
58
- /**
59
- * MEC update constructor
60
- */
61
- public function __construct()
62
- {
63
- // Import MEC Main
64
- $this->main = $this->getMain();
65
-
66
- // Import MEC Factory
67
- $this->factory = $this->getFactory();
68
-
69
- // MEC Settings
70
- $this->options = get_option('mec_options');
71
- $this->license_status = get_option( 'mec_license_status');
72
-
73
- // Set user purchase code
74
- $this->set_purchase_code(isset($this->options['purchase_code']) ? $this->options['purchase_code'] : '');
75
- $this->set_product_name(isset($this->options['product_name']) ? $this->options['product_name'] : '');
76
- $this->set_item_id(isset($this->options['product_id']) ? $this->options['product_id'] : '');
77
-
78
- // Plugin Slug
79
- list($slice1, $slice2) = explode('/', $this->plugin_slug);
80
- $this->slug = str_replace('.php', '', $slice2);
81
- }
82
-
83
- /**
84
- * Get API URL.
85
- * @author Webnus <info@webnus.biz>
86
- * @return string $api_url
87
- */
88
- public static function get_api_url()
89
- {
90
- stream_context_set_default( [
91
- 'ssl' => [
92
- 'verify_peer' => false,
93
- 'verify_peer_name' => false,
94
- ],
95
- ]);
96
-
97
- $api_url = 'https://webnus.net/api';
98
-
99
- return $api_url;
100
- }
101
-
102
- /**
103
- * Set item id.
104
- * @author Webnus <info@webnus.biz>
105
- * @param string $itemid
106
- */
107
- public function set_item_id($itemid)
108
- {
109
- $this->itemid = $itemid;
110
- }
111
-
112
- /**
113
- * Set purchase code.
114
- * @author Webnus <info@webnus.biz>
115
- * @param string $purchase_code
116
- */
117
- public function set_purchase_code($purchase_code)
118
- {
119
- $this->purchase_code = $purchase_code;
120
- }
121
-
122
- /**
123
- * Set product_name.
124
- * @author Webnus <info@webnus.biz>
125
- * @param string $product_name
126
- */
127
- public function set_product_name($product_name)
128
- {
129
- $this->product_name = $product_name;
130
- }
131
-
132
- /**
133
- * Set update path.
134
- * @author Webnus <info@webnus.biz>
135
- * @param string $update_path
136
- */
137
- public function set_update_path($update_path)
138
- {
139
- $this->update_path = $update_path;
140
- }
141
-
142
- /**
143
- * GET purchase code.
144
- * @author Webnus <info@webnus.biz>
145
- */
146
- public function get_purchase_code()
147
- {
148
- return $this->purchase_code;
149
- }
150
-
151
- /**
152
- * GET product_name.
153
- * @author Webnus <info@webnus.biz>
154
- */
155
- public function get_product_name()
156
- {
157
- return $this->product_name;
158
- }
159
-
160
- /**
161
- * Get update path.
162
- * @author Webnus <info@webnus.biz>
163
- */
164
- public function get_update_path()
165
- {
166
- return $this->update_path;
167
- }
168
-
169
- /**
170
- * Initialize the auto update class
171
- * @author Webnus <info@webnus.biz>
172
- */
173
- public function init()
174
- {
175
- // updating checking
176
- $this->factory->filter('pre_set_site_transient_update_plugins', array($this, 'check_update'));
177
-
178
- // information checking
179
- $this->factory->filter('plugins_api', array($this, 'check_info'), 10, 3);
180
- }
181
-
182
- /**
183
- * Add our self-hosted autoupdate plugin to the filter transien
184
- * @author Webnus <info@webnus.biz>
185
- * @param object $transient
186
- * @return object
187
- */
188
- public function check_update($transient)
189
- {
190
- if(empty($transient->checked)) return $transient;
191
-
192
- // Get the remote version
193
- $version = (isset($this->get_MEC_info('version')->version) and !empty($this->get_MEC_info('version')->version)) ? json_decode(json_encode($this->get_MEC_info('version')->version), true) : get_option('mec_save_version_number');
194
-
195
- // Set mec update path (plugins.php and update-core.php)
196
- $dl_link = (!empty($this->options['purchase_code']) && $this->license_status == 'active') ? $this->set_update_path($this->get_MEC_info('dl')) : NULL;
197
-
198
- // If a newer version is available, add the update
199
- if(version_compare($this->current_version, $version, '<'))
200
- {
201
- $obj = new stdClass();
202
- $obj->id = $this->itemid;
203
- $obj->slug = $this->slug;
204
- $obj->plugin = $this->plugin_slug;
205
- $obj->requires = '4.0';
206
- $obj->tested = '4.9';
207
- $obj->new_version = $version;
208
- $obj->url = $this->itemurl;
209
- $obj->package = '';
210
- $obj->upgrade_notice = '';
211
- $obj->icons = array(
212
- '1x' => 'https://ps.w.org/modern-events-calendar-lite/assets/icon-256x256.png',
213
- '2x' => 'https://ps.w.org/modern-events-calendar-lite/assets/icon-256x256.png'
214
- );
215
- $obj->sections = array
216
- (
217
- 'description' => 'Modern Events Calendar - Responsive Event Scheduler & Booking For WordPress',
218
- 'changelog' => 'Modern Events Calendar - Responsive Event Scheduler & Booking For WordPress'
219
- );
220
-
221
- $transient->response[$this->plugin_slug] = $obj;
222
- }
223
- elseif(isset($transient->response[$this->plugin_slug]))
224
- {
225
- unset($transient->response[$this->plugin_slug]);
226
- }
227
-
228
- return $transient;
229
- }
230
-
231
- /**
232
- * Add our self-hosted description to the filter
233
- * @author Webnus <info@webnus.biz>
234
- */
235
- public function check_info($false, $action, $arg)
236
- {
237
- $dl_link = !is_null($this->get_MEC_info('dl')) ? $this->set_update_path($this->get_MEC_info('dl')) : NULL;
238
- $version = (isset($this->get_MEC_info('version')->version) and !empty($this->get_MEC_info('version')->version)) ? json_decode(json_encode($this->get_MEC_info('version')->version), true) : get_option('mec_save_version_number');
239
- $data_url = 'https://webnus.net/modern-events-calendar/addons-api/addons-api.json';
240
-
241
- if(function_exists('file_get_contents') && ini_get('allow_url_fopen'))
242
- {
243
- $get_data = file_get_contents($data_url);
244
- if($get_data !== false AND !empty($get_data))
245
- {
246
- $obj = json_decode($get_data);
247
- }
248
- }
249
- elseif(function_exists('curl_version'))
250
- {
251
- $ch = curl_init();
252
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
253
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
254
- curl_setopt($ch, CURLOPT_URL, $data_url);
255
-
256
- $result = curl_exec($ch);
257
- curl_close($ch);
258
- $obj = json_decode($result);
259
- }
260
- else $obj = '';
261
-
262
- $addons = '';
263
- if(!empty($obj))
264
- {
265
- $addons .= '<div class="mec-details-addons-container">';
266
- foreach($obj as $key => $value)
267
- {
268
- $addons .= '
269
- <div class="mec-details-addons-wrap">
270
- <a href="https://webnus.net/modern-events-calendar/addons/" target="_blank"><img alt="'.esc_attr($value->name).'" src="'.$value->img.'" /></a>
271
- <div class="mec-details-addons-title"><a href="https://webnus.net/modern-events-calendar/addons/" target="_blank"><span>'. esc_html__($value->name) .'</span></a></div>
272
- <p>'. esc_html__($value->desc) .'</p>
273
- </div>';
274
- }
275
-
276
- $addons .= '</div>';
277
- }
278
-
279
- if(isset($arg->slug) and $arg->slug === $this->slug)
280
- {
281
- $information = $this->getRemote_information();
282
- $information = json_decode($information);
283
-
284
- $information->name = 'Modern Events Calendar';
285
- $information->slug = 'modern-events-calendar';
286
- $information->plugin_name = 'Modern Events Calendar';
287
- $information->version = $version;
288
- $information->download_link = '';
289
- $information->banners['low'] = 'https://ps.w.org/modern-events-calendar-lite/assets/banner-772x250.png?rev=1912767';
290
- $information->tested = '5.2.2';
291
- $information->active_installs = '100000';
292
- $information->upgrade_notice = '';
293
- $information->sections = (array) $information->sections;
294
-
295
- unset($information->sections['installation']);
296
- unset($information->sections['faq']);
297
- unset($information->sections['screenshots']);
298
-
299
- $information->sections['addons'] = $addons;
300
- return $information;
301
- }
302
-
303
- return false;
304
- }
305
-
306
- /**
307
- * Get information about the remote version
308
- * @return bool|object
309
- */
310
- public function getRemote_information()
311
- {
312
- $request = wp_remote_post('https://api.wordpress.org/plugins/info/1.0/modern-events-calendar-lite.json', array( 'timeout' => 30 ));
313
- if(!is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200)
314
- {
315
- return $request['body'];
316
- }
317
-
318
- return false;
319
- }
320
-
321
- /* Save version to database */
322
- public function mec_version_in_database() {
323
- $mec_save_version_date = get_option('mec_save_version_date');
324
- $product_name = $this->get_product_name();
325
-
326
- if ( $mec_save_version_date && ( strtotime(date("Y-m-d")) <= strtotime($mec_save_version_date) ) ) return false;
327
-
328
- $JSON = wp_remote_retrieve_body(wp_remote_get(self::get_api_url() . '/mec/v2/version?item_name=' . urlencode($product_name), array(
329
- 'body' => null,
330
- 'timeout' => '120',
331
- 'redirection' => '10',
332
- 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
333
- )));
334
- $JSON = json_decode($JSON);
335
- update_option('mec_save_version_number', $JSON->version);
336
- update_option('mec_save_version_date', date("Y-m-d"));
337
- return true;
338
- }
339
-
340
- /**
341
- * Return details from envato
342
- * @author Webnus <info@webnus.biz>
343
- * @param string $type
344
- * @return mixed
345
- */
346
- public function get_MEC_info($type = 'dl')
347
- {
348
- // setting the header for the rest of the api
349
- $code = $this->get_purchase_code();
350
- $product_name = $this->get_product_name();
351
- $item_id = $this->itemid;
352
- $url = get_home_url();
353
-
354
- if($type == 'remove') {
355
- $verify_url = 'https://webnus.net/api/remove?id='.$code;
356
- } elseif($type == 'dl') {
357
- $verify_url = self::get_api_url() . '/mec/v2/verify?category=plugins&license=' . $code . '&url=' . $url . '&item_id=' . $this->itemid;
358
- } elseif($type == 'activation') {
359
- $verify_url = self::get_api_url() . '/mec/v2/verify?category=plugins&license=' . $code . '&url=' . $url;
360
- } elseif($type == 'version') {
361
- if ( $this->mec_version_in_database() ) {
362
- $verify_url = self::get_api_url() . '/mec/v2/version?item_name=' . urlencode($product_name);
363
- } else {
364
- return NULL;
365
- }
366
- } else {
367
- return NULL;
368
- }
369
- $JSON = wp_remote_retrieve_body(wp_remote_get($verify_url, array(
370
- 'body' => null,
371
- 'timeout' => '120',
372
- 'redirection' => '10',
373
- 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
374
- )));
375
-
376
- if($JSON != '') {
377
- $data = json_decode($JSON);
378
- if ($type == 'activation') return $data;
379
- else return $data->item_link;
380
- }else {
381
- return false;
382
- }
383
- }
384
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/libraries/eventFields.php CHANGED
@@ -103,7 +103,7 @@ class MEC_eventFields extends MEC_base
103
  <?php if(isset($event_field['options']) and is_array($event_field['options'])): foreach($event_field['options'] as $event_field_option): ?>
104
  <label for="<?php echo esc_attr($id_prefix); ?><?php echo $j.'_'.strtolower(str_replace(' ', '_', $event_field_option['label'])); ?>">
105
  <input type="hidden" name="<?php echo esc_attr($name_prefix); ?>[fields][<?php echo $j; ?>][]" value="" />
106
- <input type="checkbox" id="<?php echo esc_attr($id_prefix); ?><?php echo $j.'_'.strtolower(str_replace(' ', '_', $event_field_option['label'])); ?>" <?php echo ((is_array($value) and in_array($event_field_option['label'], $value)) ? 'checked="checked"' : ''); ?> name="<?php echo esc_attr($name_prefix); ?>[fields][<?php echo $j; ?>][]" value="<?php _e($event_field_option['label'], 'modern-events-calendar-lite'); ?>" <?php if($mandatory_status and isset($event_field['mandatory']) and $event_field['mandatory'] and count($event_field['options']) == 1) echo 'required'; ?> />
107
  <?php _e(stripslashes($event_field_option['label']), 'modern-events-calendar-lite'); ?>
108
  </label>
109
  <?php endforeach; endif; ?>
@@ -114,6 +114,20 @@ class MEC_eventFields extends MEC_base
114
  <?php endforeach; ?>
115
 
116
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  <?php
118
  }
119
  }
103
  <?php if(isset($event_field['options']) and is_array($event_field['options'])): foreach($event_field['options'] as $event_field_option): ?>
104
  <label for="<?php echo esc_attr($id_prefix); ?><?php echo $j.'_'.strtolower(str_replace(' ', '_', $event_field_option['label'])); ?>">
105
  <input type="hidden" name="<?php echo esc_attr($name_prefix); ?>[fields][<?php echo $j; ?>][]" value="" />
106
+ <input type="checkbox" id="<?php echo esc_attr($id_prefix); ?><?php echo $j.'_'.strtolower(str_replace(' ', '_', $event_field_option['label'])); ?>" <?php echo ((is_array($value) and in_array($event_field_option['label'], $value)) ? 'checked="checked"' : ''); ?> name="<?php echo esc_attr($name_prefix); ?>[fields][<?php echo $j; ?>][]" value="<?php _e($event_field_option['label'], 'modern-events-calendar-lite'); ?>" <?php if($mandatory_status and isset($event_field['mandatory']) and $event_field['mandatory']) echo 'required'; ?> />
107
  <?php _e(stripslashes($event_field_option['label']), 'modern-events-calendar-lite'); ?>
108
  </label>
109
  <?php endforeach; endif; ?>
114
  <?php endforeach; ?>
115
 
116
  </div>
117
+ <script>
118
+ jQuery(document).ready(function()
119
+ {
120
+ var requiredCheckboxes = jQuery('#<?php echo esc_attr($id); ?> :checkbox[required]');
121
+ requiredCheckboxes.on('change', function()
122
+ {
123
+ var checkboxGroup = requiredCheckboxes.filter('[name="' + jQuery(this).attr('name') + '"]');
124
+ var isChecked = checkboxGroup.is(':checked');
125
+ checkboxGroup.prop('required', !isChecked);
126
+ });
127
+
128
+ requiredCheckboxes.trigger('change');
129
+ });
130
+ </script>
131
  <?php
132
  }
133
  }
app/libraries/factory.php CHANGED
@@ -580,11 +580,44 @@ class MEC_factory extends MEC_base
580
  */
581
  public function load_auto_update()
582
  {
583
- // Import MEC Envato Class
584
- $envato = MEC::getInstance('app.libraries.envato');
 
 
 
 
 
 
 
 
 
 
585
 
586
- // Initialize the service
587
- $envato->init();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
588
  }
589
 
590
  /**
580
  */
581
  public function load_auto_update()
582
  {
583
+ $options = get_option('mec_options');
584
+ $product_name = (isset($options['product_name']) && !empty($options['product_name'])) ? esc_html__($options['product_name']) : '';
585
+ $product_id = (isset($options['product_id']) && !empty($options['product_id'])) ? esc_html__($options['product_id']) : '';
586
+ $purchase_code = (isset($options['purchase_code']) && !empty($options['purchase_code'])) ? esc_html__($options['purchase_code']) : '';
587
+ $url = urlencode(get_home_url());
588
+
589
+ require_once MEC_ABSPATH.'app/core/puc/plugin-update-checker.php';
590
+ $MyUpdateChecker = Puc_v4_Factory::buildUpdateChecker(
591
+ add_query_arg(array('purchase_code' => $purchase_code, 'url' => $url,'id' => $product_id,'category' => 'mec'), MEC_API_URL . '/updates/?action=get_metadata&slug=modern-events-calendar'), //Metadata URL.
592
+ MEC_ABSPATH.'mec.php', //Full path to the main plugin file.
593
+ 'mec' //Plugin slug. Usually it's the same as the name of the directory.
594
+ );
595
 
596
+ add_filter('puc_request_info_result-mec', function($info){
597
+ if ( !$info ) return;
598
+ unset($info->sections['installation']);
599
+ unset($info->sections['faq']);
600
+ unset($info->sections['screenshots']);
601
+ unset($info->sections['wordpress_event_calendar']);
602
+ unset($info->sections['best_wordpress_event_management_plugin']);
603
+ unset($info->sections['new_designed_beautiful_event_view_layouts:']);
604
+ unset($info->sections['covid-19_(coronavirus)']);
605
+ unset($info->sections['10_best_event_calendar_plugins_and_themes_for_wordpress_2020']);
606
+ unset($info->sections['experts_opinions']);
607
+ unset($info->sections['some_new_features']);
608
+ unset($info->sections['user_reviews']);
609
+ unset($info->sections['convert_your_events_in_a_few_seconds']);
610
+ unset($info->sections['virtual_events_addon']);
611
+ unset($info->sections['main_features']);
612
+ unset($info->sections['integration']);
613
+ unset($info->sections['key_features']);
614
+ unset($info->sections['addons']);
615
+ unset($info->sections['screenshots']);
616
+ unset($info->sections['helpful_documentation']);
617
+ unset($info->sections['developers']);
618
+ unset($info->sections['frequently_asked_questions']);
619
+ return $info;
620
+ });
621
  }
622
 
623
  /**
app/libraries/main.php CHANGED
@@ -3589,21 +3589,23 @@ class MEC_main extends MEC_base
3589
  $stamp = strtotime($event->post->post_date);
3590
  $modified = strtotime($event->post->post_modified);
3591
 
 
 
3592
  $rrules = $this->get_ical_rrules($event);
3593
- $time_format = 'Ymd\\THi00\\Z';
3594
 
3595
  // All Day Event
3596
  if(isset($event->meta['mec_date']) and isset($event->meta['mec_date']['allday']) and $event->meta['mec_date']['allday'])
3597
  {
3598
- $time_format = 'Ymd\\T000000\\Z';
3599
  $end_time = strtotime('+1 Day', $end_time);
3600
  }
3601
 
3602
  $ical = "BEGIN:VEVENT".$crlf;
3603
  $ical .= "CLASS:PUBLIC".$crlf;
3604
  $ical .= "UID:MEC-".md5($event_id)."@".$this->get_domain().$crlf;
3605
- $ical .= "DTSTART:".gmdate($time_format, ($start_time - $gmt_offset_seconds)).$crlf;
3606
- $ical .= "DTEND:".gmdate($time_format, ($end_time - $gmt_offset_seconds)).$crlf;
3607
  $ical .= "DTSTAMP:".gmdate($time_format, ($stamp - $gmt_offset_seconds)).$crlf;
3608
 
3609
  if(is_array($rrules) and count($rrules))
@@ -6895,17 +6897,22 @@ class MEC_main extends MEC_base
6895
  * @param integer $timestamp
6896
  * @param integer|string $limit
6897
  * @param integer $user_id
 
6898
  * @return array
6899
  */
6900
- public function get_bookings($event_id, $timestamp, $limit = '-1', $user_id = NULL)
6901
  {
6902
- $booking_options = get_post_meta($event_id, 'mec_booking', true);
6903
- if(!is_array($booking_options)) $booking_options = array();
 
 
6904
 
6905
- $book_all_occurrences = isset($booking_options['bookings_all_occurrences']) ? (int) $booking_options['bookings_all_occurrences'] : 0;
6906
 
6907
- if(!$book_all_occurrences) $date_query = " AND `timestamp`=".$timestamp;
6908
- else $date_query = " AND `timestamp`<=".$timestamp;
 
 
6909
 
6910
  if($user_id) $user_query = " AND `user_id`=".$user_id;
6911
  else $user_query = "";
@@ -6913,10 +6920,13 @@ class MEC_main extends MEC_base
6913
  if(is_numeric($limit) and $limit > 0) $limit_query = " LIMIT ".$limit;
6914
  else $limit_query = "";
6915
 
 
 
 
6916
  // Database
6917
  $db = $this->getDB();
6918
 
6919
- $records = $db->select("SELECT `id`,`booking_id`,`timestamp` FROM `#__mec_bookings` WHERE `event_id`=".$event_id." AND `status` IN ('publish', 'future') AND `confirmed`='1' AND `verified`='1'".$date_query.$user_query.$limit_query);
6920
 
6921
  $results = array();
6922
  foreach($records as $record)
@@ -9093,59 +9103,7 @@ class MEC_main extends MEC_base
9093
  $occurrence = ($occurrence - 60) + $start_seconds;
9094
  }
9095
 
9096
- $date_query = array();
9097
- if($occurrence)
9098
- {
9099
- $date_query = array(
9100
- array(
9101
- 'year' => date('Y', $occurrence),
9102
- 'month'=> date('m', $occurrence),
9103
- 'day' => date('d', $occurrence),
9104
- 'hour' => date('H', $occurrence),
9105
- 'minute' => date('i', $occurrence),
9106
- ),
9107
- );
9108
- }
9109
-
9110
- $booking_options = get_post_meta($id, 'mec_booking', true);
9111
- $bookings_all_occurrences = (isset($booking_options['bookings_all_occurrences']) ? $booking_options['bookings_all_occurrences'] : 0);
9112
- if($bookings_all_occurrences and $occurrence)
9113
- {
9114
- $date_query = array(
9115
- 'before' => date('Y-m-d', $occurrence).' 23:59:59',
9116
- );
9117
- }
9118
-
9119
- $meta_query = array();
9120
- if($verified)
9121
- {
9122
- $meta_query = array
9123
- (
9124
- 'relation' => 'AND',
9125
- array(
9126
- 'key' => 'mec_verified',
9127
- 'value' => '1',
9128
- 'compare' => '=',
9129
- ),
9130
- array(
9131
- 'key' => 'mec_confirmed',
9132
- 'value' => '1',
9133
- 'compare' => '=',
9134
- ),
9135
- );
9136
- }
9137
-
9138
- // Fetch Bookings
9139
- $bookings = get_posts(array(
9140
- 'posts_per_page' => -1,
9141
- 'post_type' => $this->get_book_post_type(),
9142
- 'post_status' => 'any',
9143
- 'meta_key' => 'mec_event_id',
9144
- 'meta_value' => $id,
9145
- 'meta_compare' => '=',
9146
- 'meta_query' => $meta_query,
9147
- 'date_query' => $date_query,
9148
- ));
9149
 
9150
  // Attendees
9151
  $attendees = array();
3589
  $stamp = strtotime($event->post->post_date);
3590
  $modified = strtotime($event->post->post_modified);
3591
 
3592
+ $timezone = $this->get_timezone($event_id);
3593
+
3594
  $rrules = $this->get_ical_rrules($event);
3595
+ $time_format = 'Ymd\\THi00';
3596
 
3597
  // All Day Event
3598
  if(isset($event->meta['mec_date']) and isset($event->meta['mec_date']['allday']) and $event->meta['mec_date']['allday'])
3599
  {
3600
+ $time_format = 'Ymd\\T000000';
3601
  $end_time = strtotime('+1 Day', $end_time);
3602
  }
3603
 
3604
  $ical = "BEGIN:VEVENT".$crlf;
3605
  $ical .= "CLASS:PUBLIC".$crlf;
3606
  $ical .= "UID:MEC-".md5($event_id)."@".$this->get_domain().$crlf;
3607
+ $ical .= "DTSTART;TZID=".$timezone.":".date($time_format, $start_time).$crlf;
3608
+ $ical .= "DTEND;TZID=".$timezone.":".date($time_format, $end_time).$crlf;
3609
  $ical .= "DTSTAMP:".gmdate($time_format, ($stamp - $gmt_offset_seconds)).$crlf;
3610
 
3611
  if(is_array($rrules) and count($rrules))
6897
  * @param integer $timestamp
6898
  * @param integer|string $limit
6899
  * @param integer $user_id
6900
+ * @param boolean $verified
6901
  * @return array
6902
  */
6903
+ public function get_bookings($event_id, $timestamp = NULL, $limit = '-1', $user_id = NULL, $verified = true)
6904
  {
6905
+ if($timestamp)
6906
+ {
6907
+ $booking_options = get_post_meta($event_id, 'mec_booking', true);
6908
+ if(!is_array($booking_options)) $booking_options = array();
6909
 
6910
+ $book_all_occurrences = isset($booking_options['bookings_all_occurrences']) ? (int) $booking_options['bookings_all_occurrences'] : 0;
6911
 
6912
+ if(!$book_all_occurrences) $date_query = " AND `timestamp`=".$timestamp;
6913
+ else $date_query = " AND `timestamp`<=".$timestamp;
6914
+ }
6915
+ else $date_query = "";
6916
 
6917
  if($user_id) $user_query = " AND `user_id`=".$user_id;
6918
  else $user_query = "";
6920
  if(is_numeric($limit) and $limit > 0) $limit_query = " LIMIT ".$limit;
6921
  else $limit_query = "";
6922
 
6923
+ if($verified) $status_query = " AND `status` IN ('publish', 'future') AND `confirmed`='1' AND `verified`='1'";
6924
+ else $status_query = "";
6925
+
6926
  // Database
6927
  $db = $this->getDB();
6928
 
6929
+ $records = $db->select("SELECT `id`,`booking_id`,`timestamp` FROM `#__mec_bookings` WHERE `event_id`=".$event_id.$status_query.$date_query.$user_query.$limit_query);
6930
 
6931
  $results = array();
6932
  foreach($records as $record)
9103
  $occurrence = ($occurrence - 60) + $start_seconds;
9104
  }
9105
 
9106
+ $bookings = $this->get_bookings($id, $occurrence, '-1', NULL, $verified);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9107
 
9108
  // Attendees
9109
  $attendees = array();
app/modules/next-event/multiple.php CHANGED
@@ -36,6 +36,9 @@ $occurrence_time = isset($_GET['time']) ? (int) sanitize_text_field($_GET['time'
36
  // Event Dates
37
  $dates = $this->get_event_next_occurrences($event, $occurrence, $maximum, $occurrence_time);
38
 
 
 
 
39
  // Remove Current Occurrence
40
  if(is_array($date) and isset($date['start']) and isset($date['start']['timestamp']) and is_array($dates) and isset($dates[0]) and isset($dates[0]['start']) and isset($dates[0]['start']['timestamp']) and $dates[0]['start']['timestamp'] == $date['start']['timestamp']) unset($dates[0]);
41
 
@@ -54,7 +57,11 @@ $hide_end_time = isset($event->data->meta['mec_hide_end_time']) ? $event->data->
54
  <?php foreach($dates as $date): ?>
55
  <li>
56
  <a href="<?php echo $this->get_event_date_permalink($event, $date['start']['date'], true, array('start_raw' => date($time_format, $date['start']['timestamp']))); ?>">
 
 
 
57
  <span class="mec-date"><?php echo $this->date_label($date['start'], (isset($date['end']) ? $date['end'] : NULL), $date_format1); ?></span>
 
58
 
59
  <?php if(!$hide_time): ?>
60
  <span class="mec-time">
36
  // Event Dates
37
  $dates = $this->get_event_next_occurrences($event, $occurrence, $maximum, $occurrence_time);
38
 
39
+ // Midnight Event
40
+ $midnight = $this->is_midnight_event($event);
41
+
42
  // Remove Current Occurrence
43
  if(is_array($date) and isset($date['start']) and isset($date['start']['timestamp']) and is_array($dates) and isset($dates[0]) and isset($dates[0]['start']) and isset($dates[0]['start']['timestamp']) and $dates[0]['start']['timestamp'] == $date['start']['timestamp']) unset($dates[0]);
44
 
57
  <?php foreach($dates as $date): ?>
58
  <li>
59
  <a href="<?php echo $this->get_event_date_permalink($event, $date['start']['date'], true, array('start_raw' => date($time_format, $date['start']['timestamp']))); ?>">
60
+ <?php if($midnight): $date['end']['date'] = date('Y-m-d', strtotime('Yesterday', strtotime($date['end']['date']))); ?>
61
+ <span class="mec-date"><?php echo $this->date_label($date['start'], (isset($date['end']) ? $date['end'] : NULL), $date_format1); ?></span>
62
+ <?php else: ?>
63
  <span class="mec-date"><?php echo $this->date_label($date['start'], (isset($date['end']) ? $date['end'] : NULL), $date_format1); ?></span>
64
+ <?php endif; ?>
65
 
66
  <?php if(!$hide_time): ?>
67
  <span class="mec-time">
app/skins/single.php CHANGED
@@ -1111,9 +1111,7 @@ class MEC_skin_single extends MEC_skins
1111
  */
1112
  public function display_cost_widget($event)
1113
  {
1114
- $cost = (isset($event->data->meta) and isset($event->data->meta['mec_cost']) and trim($event->data->meta['mec_cost'])) ? $event->data->meta['mec_cost'] : '';
1115
- if(isset($event->date) and isset($event->date['start']) and isset($event->date['start']['timestamp'])) $cost = MEC_feature_occurrences::param($event->ID, $event->date['start']['timestamp'], 'cost', $cost);
1116
-
1117
  if($cost)
1118
  {
1119
  echo '<div class="mec-event-meta">';
@@ -1123,13 +1121,10 @@ class MEC_skin_single extends MEC_skins
1123
  <h3 class="mec-cost"><?php echo $this->main->m('cost', __('Cost', 'modern-events-calendar-lite')); ?></h3>
1124
  <dl><dd class="mec-events-event-cost">
1125
  <?php
1126
- if(is_numeric($cost)){
1127
- $rendered_cost = $this->main->render_price($cost, $event->ID);
1128
- }else{
1129
- $rendered_cost = $cost;
1130
- }
1131
 
1132
- echo apply_filters( 'mec_display_event_cost', $rendered_cost, $cost );
1133
  ?>
1134
  </dd></dl>
1135
  </div>
@@ -1766,8 +1761,12 @@ class MEC_skin_single extends MEC_skins
1766
  $url = wp_get_attachment_url($file_id);
1767
  if(!$url) return;
1768
 
 
 
 
1769
  echo '<div class="mec-public-download-details mec-frontbox">
1770
- <a class="button" href="'.esc_url($url).'">'.esc_html__('Download', 'modern-events-calendar-lite').'</a>
 
1771
  </div>';
1772
  }
1773
  }
1111
  */
1112
  public function display_cost_widget($event)
1113
  {
1114
+ $cost = $this->main->get_event_cost($event);
 
 
1115
  if($cost)
1116
  {
1117
  echo '<div class="mec-event-meta">';
1121
  <h3 class="mec-cost"><?php echo $this->main->m('cost', __('Cost', 'modern-events-calendar-lite')); ?></h3>
1122
  <dl><dd class="mec-events-event-cost">
1123
  <?php
1124
+ if(is_numeric($cost)) $rendered_cost = $this->main->render_price($cost, $event->ID);
1125
+ else $rendered_cost = $cost;
 
 
 
1126
 
1127
+ echo apply_filters('mec_display_event_cost', $rendered_cost, $cost);
1128
  ?>
1129
  </dd></dl>
1130
  </div>
1761
  $url = wp_get_attachment_url($file_id);
1762
  if(!$url) return;
1763
 
1764
+ $title = ($event and isset($event->data) and isset($event->data->meta) and isset($event->data->meta['mec_public_dl_title']) and $event->data->meta['mec_public_dl_title']) ? $event->data->meta['mec_public_dl_title'] : NULL;
1765
+ $description = ($event and isset($event->data) and isset($event->data->meta) and isset($event->data->meta['mec_public_dl_description']) and $event->data->meta['mec_public_dl_description']) ? $event->data->meta['mec_public_dl_description'] : NULL;
1766
+
1767
  echo '<div class="mec-public-download-details mec-frontbox">
1768
+ '.($description ? '<p>'.wp_kses(wpautop($description), array('p' => array(), 'br' => array())).'</p>' : '').'
1769
+ <a class="button" href="'.esc_url($url).'">'.(trim($title) ? esc_html($title) : esc_html__('Download', 'modern-events-calendar-lite')).'</a>
1770
  </div>';
1771
  }
1772
  }
assets/js/frontend.js CHANGED
@@ -263,6 +263,8 @@ var mec_search_callback2;
263
  month = '';
264
  }
265
 
 
 
266
  var addation_attr = '';
267
  if (settings.fields && settings.fields.length > 0) {
268
  for (var k in settings.fields) {
263
  month = '';
264
  }
265
 
266
+ if(!year) year = '';
267
+
268
  var addation_attr = '';
269
  if (settings.fields && settings.fields.length > 0) {
270
  for (var k in settings.fields) {
changelog.txt CHANGED
@@ -1,4 +1,24 @@
1
- v 6.2.55 January 2022
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  - Added: A new option to display event price based on lowest ticket price (pro)
3
  - Added: An invoice feature for MEC cart (pro)
4
  - Added: A new feature to sort the events in descending order
1
+ v 6.2.712 January 2022
2
+ - Fixed: "Add new plugin" page error
3
+
4
+ v 6.2.6 – 12 January 2022
5
+ - Added: Some new options for the “Assets Per Page” feature
6
+ - Added: Title and description fields for public download module
7
+ - Improved: The UX of MEC Cart (pro)
8
+ - Improved: The mandatory checkbox validation on event custom fields
9
+ - Fixed: A search issue on tile skin
10
+ - Fixed: The ticket pricing system (pro)
11
+ - Fixed: The next event module
12
+ - Fixed: Some issues on iCal feed
13
+ - Fixed: An issue in showing the sold-out label
14
+ - Fixed: Some issues on event structured data
15
+ - Fixed: An issue in the reports menu
16
+ - Fixed: An issue on profile short-code
17
+ - Fixed: Some issues in the export feature (pro)
18
+ - Fixed: A conflict with other plugins
19
+ - Fixed: Some PHP notices and warnings
20
+
21
+ v 6.2.5 – 5 January 2022
22
  - Added: A new option to display event price based on lowest ticket price (pro)
23
  - Added: An invoice feature for MEC cart (pro)
24
  - Added: A new feature to sort the events in descending order
languages/modern-events-calendar-lite-cs_CZ.mo CHANGED
Binary file
languages/modern-events-calendar-lite-cs_CZ.po CHANGED
@@ -1,8 +1,8 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: Modern Events Calendar Lite\n"
4
- "POT-Creation-Date: 2022-01-05 14:48+0330\n"
5
- "PO-Revision-Date: 2022-01-05 14:53+0330\n"
6
  "Last-Translator: \n"
7
  "Language-Team: \n"
8
  "Language: cs_CZ\n"
@@ -23,8 +23,8 @@ msgstr ""
23
 
24
  #: app/addons/KC.php:68 app/addons/VC.php:59 app/features/ix/import.php:24
25
  #: app/features/ix/import.php:48 app/features/ix/import.php:77
26
- #: app/features/ix/thirdparty.php:26 app/features/mec.php:1302
27
- #: app/features/mec.php:1326 app/features/mec/dashboard.php:65
28
  #: app/features/mec/wizard.php:489 app/widgets/MEC.php:33
29
  msgid "Modern Events Calendar"
30
  msgstr "Moderní kalendář událostí"
@@ -35,8 +35,8 @@ msgstr "Moderní kalendář událostí"
35
  msgid "Content"
36
  msgstr "Obsah"
37
 
38
- #: app/addons/KC.php:75 app/addons/VC.php:70 app/features/mec.php:568
39
- #: app/features/mec.php:599 app/features/mec.php:629
40
  msgid "Shortcode"
41
  msgstr "Zkrácený kód"
42
 
@@ -104,40 +104,85 @@ msgstr ""
104
  msgid "Select Shortcode"
105
  msgstr "Přidat nový zkrácený kód"
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  #: app/core/src/Books/Book.php:106 app/features/ix.php:284
108
- #: app/libraries/main.php:7751 app/libraries/main.php:7778
109
  msgid "Rejected"
110
  msgstr "Odmítnuto"
111
 
112
  #: app/core/src/Books/Book.php:111 app/features/ix.php:283
113
- #: app/libraries/main.php:3232 app/libraries/main.php:7750
114
- #: app/libraries/main.php:7770
115
  msgid "Confirmed"
116
  msgstr "Potvrzeno"
117
 
118
  #: app/core/src/Books/Book.php:117 app/features/mec/settings.php:742
119
- #: app/libraries/main.php:7752 app/libraries/main.php:7774
120
  msgid "Pending"
121
  msgstr "Nevyřízený"
122
 
123
  #: app/core/src/Books/Book.php:186 app/features/ix.php:289
124
  #: app/features/labels.php:119 app/features/labels.php:145
125
- #: app/libraries/main.php:7799
126
  msgid "Canceled"
127
  msgstr "Zrušená"
128
 
129
  #: app/core/src/Books/Book.php:191 app/features/ix.php:288
130
- #: app/features/mec/booking.php:1246 app/features/mec/booking.php:1268
131
  #: app/features/mec/integrations.php:449 app/features/mec/integrations.php:471
132
  #: app/features/mec/modules.php:406 app/features/mec/modules.php:428
133
  #: app/features/mec/notifications.php:1922
134
  #: app/features/mec/notifications.php:1945 app/features/mec/settings.php:1599
135
  #: app/features/mec/settings.php:1621 app/features/mec/single.php:595
136
- #: app/features/mec/single.php:617 app/libraries/main.php:7798
137
  msgid "Verified"
138
  msgstr "Ověřeno"
139
 
140
- #: app/core/src/Books/Book.php:197 app/libraries/main.php:7800
141
  msgid "Waiting"
142
  msgstr "Čekající"
143
 
@@ -164,22 +209,23 @@ msgstr "Název vstupenky"
164
  #: app/core/src/Forms/FormFields.php:188 app/core/src/Forms/SettingsForm.php:93
165
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:70
166
  #: app/features/autoemails.php:60 app/features/events.php:606
167
- #: app/features/events.php:2658 app/features/events.php:2725
168
- #: app/features/events.php:2814 app/features/events.php:4422
169
  #: app/features/fes.php:280 app/features/fes/form.php:810
170
- #: app/features/login/login.php:5 app/features/mec/booking.php:57
171
- #: app/features/mec/booking.php:794 app/features/mec/booking.php:892
172
- #: app/features/mec/settings.php:295 app/features/mec/single.php:303
173
- #: app/features/organizers.php:112 app/features/organizers.php:153
174
- #: app/features/profile/profile.php:195 app/features/speakers.php:128
175
- #: app/features/speakers.php:205 app/libraries/main.php:618
176
- #: app/libraries/main.php:2093 app/libraries/main.php:2162
177
- #: app/libraries/main.php:3987 app/libraries/notifications.php:2091
178
- #: app/modules/booking/steps/form.php:69 app/modules/booking/steps/form.php:218
179
- #: app/skins/single.php:1399 app/skins/single.php:1466
180
- #: app/skins/single/default.php:347 app/skins/single/default.php:596
181
- #: app/skins/single/m1.php:141 app/skins/single/m2.php:61
182
- #: app/skins/single/modern.php:94
 
183
  msgid "Email"
184
  msgstr "Email"
185
 
@@ -197,21 +243,21 @@ msgstr "Vložte štítek pro toto pole"
197
  #: app/core/src/Forms/FormFields.php:396 app/core/src/Forms/FormFields.php:442
198
  #: app/core/src/Forms/FormFields.php:488 app/core/src/Forms/FormFields.php:544
199
  #: app/core/src/Forms/FormFields.php:596 app/features/organizers.php:340
200
- #: app/features/organizers.php:348 app/libraries/main.php:3895
201
- #: app/libraries/main.php:3926 app/libraries/main.php:3956
202
- #: app/libraries/main.php:3986 app/libraries/main.php:4017
203
- #: app/libraries/main.php:4048 app/libraries/main.php:4078
204
- #: app/libraries/main.php:4109 app/libraries/main.php:4140
205
- #: app/libraries/main.php:4178 app/libraries/main.php:4202
206
- #: app/libraries/main.php:4250 app/libraries/main.php:4298
207
- #: app/libraries/main.php:4356 app/libraries/main.php:4406
208
  msgid "Sort"
209
  msgstr "Seřadit"
210
 
211
  #: app/core/src/Forms/FormFields.php:52 app/core/src/Forms/SettingsForm.php:88
212
- #: app/features/events.php:2724 app/features/events.php:2813
213
  #: app/features/mec/booking.php:793 app/features/mec/booking.php:891
214
- #: app/features/mec/single.php:302 app/libraries/main.php:3896
215
  #: app/libraries/skins.php:1377
216
  msgid "Text"
217
  msgstr "Text"
@@ -222,13 +268,13 @@ msgstr "Text"
222
  #: app/core/src/Forms/FormFields.php:286 app/core/src/Forms/FormFields.php:317
223
  #: app/core/src/Forms/FormFields.php:348 app/core/src/Forms/FormFields.php:403
224
  #: app/core/src/Forms/FormFields.php:449 app/core/src/Forms/FormFields.php:495
225
- #: app/core/src/Forms/FormFields.php:551 app/libraries/main.php:3903
226
- #: app/libraries/main.php:3934 app/libraries/main.php:3964
227
- #: app/libraries/main.php:3994 app/libraries/main.php:4025
228
- #: app/libraries/main.php:4056 app/libraries/main.php:4086
229
- #: app/libraries/main.php:4117 app/libraries/main.php:4149
230
- #: app/libraries/main.php:4210 app/libraries/main.php:4258
231
- #: app/libraries/main.php:4306 app/libraries/main.php:4364
232
  msgid "Required Field"
233
  msgstr "Požadovaná pole"
234
 
@@ -240,21 +286,21 @@ msgstr "Požadovaná pole"
240
  #: app/core/src/Forms/FormFields.php:406 app/core/src/Forms/FormFields.php:452
241
  #: app/core/src/Forms/FormFields.php:505 app/core/src/Forms/FormFields.php:554
242
  #: app/core/src/Forms/FormFields.php:597 app/features/events.php:2121
243
- #: app/features/events.php:2147 app/features/events.php:2361
244
- #: app/features/events.php:2498 app/features/events.php:2535
245
  #: app/features/mec/booking.php:611 app/features/mec/booking.php:641
246
  #: app/features/mec/booking.php:709 app/features/mec/booking.php:741
247
  #: app/features/organizers.php:340 app/features/organizers.php:349
248
  #: app/libraries/hourlyschedule.php:53 app/libraries/hourlyschedule.php:74
249
  #: app/libraries/hourlyschedule.php:102 app/libraries/hourlyschedule.php:130
250
- #: app/libraries/hourlyschedule.php:154 app/libraries/main.php:3906
251
- #: app/libraries/main.php:3937 app/libraries/main.php:3967
252
- #: app/libraries/main.php:3997 app/libraries/main.php:4028
253
- #: app/libraries/main.php:4059 app/libraries/main.php:4089
254
- #: app/libraries/main.php:4120 app/libraries/main.php:4158
255
- #: app/libraries/main.php:4180 app/libraries/main.php:4213
256
- #: app/libraries/main.php:4261 app/libraries/main.php:4316
257
- #: app/libraries/main.php:4367 app/libraries/main.php:4407
258
  #: app/libraries/ticketVariations.php:72
259
  msgid "Remove"
260
  msgstr "Odstranit"
@@ -265,13 +311,13 @@ msgstr "Odstranit"
265
  #: app/core/src/Forms/FormFields.php:292 app/core/src/Forms/FormFields.php:323
266
  #: app/core/src/Forms/FormFields.php:354 app/core/src/Forms/FormFields.php:409
267
  #: app/core/src/Forms/FormFields.php:455 app/core/src/Forms/FormFields.php:508
268
- #: app/core/src/Forms/FormFields.php:557 app/libraries/main.php:3909
269
- #: app/libraries/main.php:3940 app/libraries/main.php:3970
270
- #: app/libraries/main.php:4000 app/libraries/main.php:4031
271
- #: app/libraries/main.php:4062 app/libraries/main.php:4092
272
- #: app/libraries/main.php:4123 app/libraries/main.php:4161
273
- #: app/libraries/main.php:4216 app/libraries/main.php:4264
274
- #: app/libraries/main.php:4319 app/libraries/main.php:4370
275
  msgid "Insert a label for this field"
276
  msgstr "Vložte štítek pro toto pole"
277
 
@@ -287,97 +333,97 @@ msgstr "Název vstupenky"
287
  msgid "MEC Last Name"
288
  msgstr "MEC Jméno"
289
 
290
- #: app/core/src/Forms/FormFields.php:93 app/features/events.php:2722
291
- #: app/features/mec/booking.php:791 app/libraries/main.php:3927
292
  msgid "MEC Name"
293
  msgstr "MEC Jméno"
294
 
295
  #: app/core/src/Forms/FormFields.php:158 app/core/src/Forms/SettingsForm.php:83
296
- #: app/features/events.php:2723 app/features/mec/booking.php:792
297
- #: app/libraries/main.php:3957
298
  msgid "MEC Email"
299
  msgstr "MEC Email"
300
 
301
  #: app/core/src/Forms/FormFields.php:219 app/features/mec/single.php:304
302
- #: app/libraries/main.php:4018
303
  msgid "URL"
304
  msgstr ""
305
 
306
  #: app/core/src/Forms/FormFields.php:250
307
- #: app/core/src/Forms/SettingsForm.php:108 app/features/events.php:2728
308
- #: app/features/mec/booking.php:797 app/libraries/main.php:4049
309
  msgid "File"
310
  msgstr "Soubor"
311
 
312
  #: app/core/src/Forms/FormFields.php:280 app/core/src/Forms/SettingsForm.php:98
313
  #: app/core/src/SingleBuilder/Widgets/EventDate/EventDate.php:47
314
- #: app/features/events.php:1396 app/features/events.php:2726
315
- #: app/features/events.php:2815 app/features/fes.php:280
316
  #: app/features/mec/booking.php:795 app/features/mec/booking.php:893
317
  #: app/features/mec/single.php:305 app/features/profile/profile.php:59
318
- #: app/features/wc.php:79 app/libraries/main.php:4079
319
  #: app/libraries/skins.php:1289 app/modules/booking/steps/tickets.php:136
320
- #: app/modules/next-event/details.php:145 app/skins/single.php:1191
321
  #: app/skins/single/default.php:171 app/skins/single/default.php:423
322
  #: app/skins/single/m1.php:40 app/skins/single/modern.php:253
323
  msgid "Date"
324
  msgstr "Datum"
325
 
326
  #: app/core/src/Forms/FormFields.php:311
327
- #: app/core/src/Forms/SettingsForm.php:103 app/features/events.php:2727
328
- #: app/features/events.php:2816 app/features/mec/booking.php:796
329
  #: app/features/mec/booking.php:894 app/features/mec/single.php:306
330
  #: app/features/organizers.php:104 app/features/organizers.php:149
331
  #: app/features/speakers.php:120 app/features/speakers.php:201
332
- #: app/features/speakers.php:288 app/libraries/main.php:4110
333
  msgid "Tel"
334
  msgstr "Tel"
335
 
336
  #: app/core/src/Forms/FormFields.php:342
337
- #: app/core/src/Forms/SettingsForm.php:113 app/features/events.php:2729
338
- #: app/features/events.php:2817 app/features/mec/booking.php:798
339
  #: app/features/mec/booking.php:895 app/features/mec/single.php:307
340
- #: app/libraries/main.php:4141
341
  msgid "Textarea"
342
  msgstr "Plocha textu"
343
 
344
  #: app/core/src/Forms/FormFields.php:373
345
- #: app/core/src/Forms/SettingsForm.php:138 app/features/events.php:2734
346
- #: app/features/events.php:2822 app/features/mec/booking.php:803
347
  #: app/features/mec/booking.php:900 app/features/mec/settings.php:351
348
- #: app/features/mec/single.php:308 app/libraries/main.php:4179
349
  msgid "Paragraph"
350
  msgstr "Paragraf"
351
 
352
- #: app/core/src/Forms/FormFields.php:378 app/libraries/main.php:4185
353
  msgid "HTML and shortcode are allowed."
354
  msgstr "HTML a zkrácené kódy jsou povoleny."
355
 
356
  #: app/core/src/Forms/FormFields.php:397
357
- #: app/core/src/Forms/SettingsForm.php:118 app/features/events.php:2730
358
- #: app/features/events.php:2818 app/features/mec/booking.php:127
359
  #: app/features/mec/booking.php:799 app/features/mec/booking.php:896
360
- #: app/features/mec/single.php:309 app/libraries/main.php:4203
361
  msgid "Checkboxes"
362
  msgstr "Zatržítko"
363
 
364
  #: app/core/src/Forms/FormFields.php:421 app/core/src/Forms/FormFields.php:467
365
- #: app/core/src/Forms/FormFields.php:520 app/libraries/main.php:4230
366
- #: app/libraries/main.php:4278 app/libraries/main.php:4333
367
  msgid "Option"
368
  msgstr "Možnost"
369
 
370
  #: app/core/src/Forms/FormFields.php:443
371
- #: app/core/src/Forms/SettingsForm.php:123 app/features/events.php:2731
372
- #: app/features/events.php:2819 app/features/mec/booking.php:800
373
  #: app/features/mec/booking.php:897 app/features/mec/single.php:310
374
- #: app/libraries/main.php:4251
375
  msgid "Radio Buttons"
376
  msgstr "Přepínače"
377
 
378
  #: app/core/src/Forms/FormFields.php:489
379
- #: app/core/src/Forms/SettingsForm.php:128 app/features/events.php:2732
380
- #: app/features/events.php:2820 app/features/mec/booking.php:125
381
  #: app/features/mec/booking.php:801 app/features/mec/booking.php:898
382
  #: app/features/mec/meta_boxes/search_form.php:67
383
  #: app/features/mec/meta_boxes/search_form.php:75
@@ -460,7 +506,7 @@ msgstr "Přepínače"
460
  #: app/features/mec/meta_boxes/search_form.php:1094
461
  #: app/features/mec/meta_boxes/search_form.php:1116
462
  #: app/features/mec/single.php:311 app/features/popup/settings.php:348
463
- #: app/libraries/main.php:4299
464
  msgid "Dropdown"
465
  msgstr "Rozbalovací"
466
 
@@ -469,40 +515,40 @@ msgid "Consider first item as placeholder"
469
  msgstr ""
470
 
471
  #: app/core/src/Forms/FormFields.php:545
472
- #: app/core/src/Forms/SettingsForm.php:133 app/features/events.php:2733
473
- #: app/features/events.php:2821 app/features/mec/booking.php:802
474
- #: app/features/mec/booking.php:899 app/libraries/main.php:4357
475
  msgid "Agreement"
476
  msgstr "Smlouva"
477
 
478
- #: app/core/src/Forms/FormFields.php:557 app/libraries/main.php:4370
479
  #, php-format
480
  msgid "Instead of %s, the page title with a link will be show."
481
  msgstr "Místo%s se zobrazí název stránky s odkazem."
482
 
483
  #: app/core/src/Forms/FormFields.php:559 app/features/mec/settings.php:1145
484
- #: app/libraries/main.php:4372
485
  msgid "Agreement Page"
486
  msgstr "Stránka smlouvy"
487
 
488
  #: app/core/src/Forms/FormFields.php:570 app/features/profile/profile.php:62
489
- #: app/libraries/main.php:4381
490
  msgid "Status"
491
  msgstr "Stav"
492
 
493
- #: app/core/src/Forms/FormFields.php:572 app/libraries/main.php:4383
494
  msgid "Checked by default"
495
  msgstr "Ve výchozím nastavení zaškrtnuto"
496
 
497
- #: app/core/src/Forms/FormFields.php:573 app/libraries/main.php:4384
498
  msgid "Unchecked by default"
499
  msgstr "Ve výchozím nastavení není zaškrtnuto"
500
 
501
- #: app/core/src/Forms/FormFields.php:598 app/libraries/main.php:4408
502
  msgid "Insert a label for this option"
503
  msgstr "Vložte štítek pro tuto možnost"
504
 
505
- #: app/core/src/Forms/FormFields.php:606 app/libraries/main.php:8974
506
  msgid "Mapping with Profile Fields"
507
  msgstr ""
508
 
@@ -650,20 +696,25 @@ msgstr "Vložte e-maily oddělené čárkami pro více příjemců."
650
  #: app/features/events.php:1404 app/features/events.php:1541
651
  #: app/features/events.php:1666 app/features/events.php:1836
652
  #: app/features/events.php:1849 app/features/events.php:2020
653
- #: app/features/events.php:2035 app/features/events.php:2278
654
- #: app/features/events.php:2291 app/features/events.php:2484
655
- #: app/features/events.php:2521 app/features/fes/form.php:458
656
  #: app/features/fes/form.php:766 app/features/fes/form.php:901
657
- #: app/features/locations.php:341 app/features/mec/booking.php:109
658
- #: app/features/mec/booking.php:185 app/features/mec/booking.php:198
659
- #: app/features/mec/booking.php:234 app/features/mec/booking.php:299
660
- #: app/features/mec/booking.php:332 app/features/mec/booking.php:345
661
- #: app/features/mec/booking.php:411 app/features/mec/booking.php:462
662
- #: app/features/mec/booking.php:598 app/features/mec/booking.php:628
663
- #: app/features/mec/booking.php:694 app/features/mec/booking.php:704
664
- #: app/features/mec/booking.php:726 app/features/mec/booking.php:736
665
- #: app/features/mec/booking.php:1001 app/features/mec/booking.php:1029
666
- #: app/features/mec/dashboard.php:73 app/features/mec/integrations.php:57
 
 
 
 
 
667
  #: app/features/mec/integrations.php:70 app/features/mec/integrations.php:86
668
  #: app/features/mec/meta_boxes/display_options.php:98
669
  #: app/features/mec/meta_boxes/display_options.php:111
@@ -735,7 +786,7 @@ msgstr "Vložte e-maily oddělené čárkami pro více příjemců."
735
  #: app/features/popup/settings.php:78 app/features/popup/settings.php:161
736
  #: app/features/popup/settings.php:182 app/features/popup/settings.php:300
737
  #: app/libraries/ticketVariations.php:50 app/libraries/ticketVariations.php:65
738
- #: app/skins/single.php:1218 app/skins/single.php:1334
739
  #: app/skins/single/default.php:25 app/skins/single/m1.php:16
740
  #: app/skins/single/m2.php:16 app/skins/single/modern.php:26
741
  msgid "Read More"
@@ -855,7 +906,7 @@ msgid "How to set category"
855
  msgstr ""
856
 
857
  #: app/core/src/SingleBuilder/Widgets/EventCategories/EventCategories.php:47
858
- #: app/features/events.php:218 app/features/events.php:3854
859
  #: app/features/mec/meta_boxes/display_options.php:1657
860
  #: app/features/mec/meta_boxes/search_form.php:64
861
  #: app/features/mec/meta_boxes/search_form.php:152
@@ -872,8 +923,8 @@ msgstr ""
872
  #: app/features/mec/settings.php:1165 app/features/mec/settings.php:1228
873
  #: app/features/mec/single.php:460 app/features/mec/single.php:513
874
  #: app/features/popup/settings.php:220 app/features/popup/settings.php:259
875
- #: app/features/search.php:91 app/libraries/main.php:7401
876
- #: app/libraries/main.php:7462 app/libraries/search.php:256
877
  #: app/libraries/skins.php:1090 app/skins/single.php:1090
878
  #: app/skins/single/default.php:299 app/skins/single/default.php:549
879
  #: app/skins/single/m1.php:231 app/skins/single/m2.php:151
@@ -896,9 +947,9 @@ msgstr ""
896
  #: app/core/src/SingleBuilder/Widgets/EventCost/EventCost.php:47
897
  #: app/features/events.php:432 app/features/events.php:1283
898
  #: app/features/fes/form.php:868 app/features/mec/settings.php:1162
899
- #: app/features/occurrences.php:511 app/libraries/main.php:7447
900
- #: app/libraries/main.php:7494 app/libraries/skins.php:1405
901
- #: app/skins/single.php:1123 app/skins/single/default.php:215
902
  #: app/skins/single/default.php:467 app/skins/single/m1.php:80
903
  #: app/skins/single/modern.php:293
904
  msgid "Cost"
@@ -975,11 +1026,11 @@ msgid "How to set label"
975
  msgstr ""
976
 
977
  #: app/core/src/SingleBuilder/Widgets/EventLabels/EventLabels.php:48
978
- #: app/features/events.php:4176 app/features/fes/form.php:998
979
  #: app/features/labels.php:61 app/features/labels.php:227
980
- #: app/features/mec.php:495 app/features/mec/meta_boxes/filter.php:72
981
- #: app/features/mec/meta_boxes/filter.php:135 app/libraries/main.php:7402
982
- #: app/libraries/main.php:7463 app/skins/single.php:1253
983
  #: app/skins/single/default.php:247 app/skins/single/default.php:496
984
  #: app/skins/single/m1.php:95 app/skins/single/modern.php:308
985
  msgid "Labels"
@@ -1011,7 +1062,7 @@ msgid "How to set location"
1011
  msgstr "Skrýt místo"
1012
 
1013
  #: app/core/src/SingleBuilder/Widgets/EventLocations/EventLocations.php:54
1014
- #: app/features/events.php:3855 app/features/events.php:4169
1015
  #: app/features/locations.php:58 app/features/locations.php:267
1016
  #: app/features/locations.php:329 app/features/locations.php:331
1017
  #: app/features/locations.php:340
@@ -1034,10 +1085,10 @@ msgstr "Skrýt místo"
1034
  #: app/features/popup/event.php:118 app/features/popup/event.php:127
1035
  #: app/features/popup/settings.php:228 app/features/popup/settings.php:267
1036
  #: app/features/search.php:97 app/libraries/main.php:2961
1037
- #: app/libraries/main.php:3238 app/libraries/main.php:7405
1038
- #: app/libraries/main.php:7466 app/libraries/search.php:294
1039
  #: app/libraries/skins.php:1145 app/skins/single.php:1017
1040
- #: app/skins/single.php:1525 app/skins/single/default.php:268
1041
  #: app/skins/single/default.php:519 app/skins/single/m1.php:201
1042
  #: app/skins/single/m2.php:121 app/skins/single/modern.php:153
1043
  msgid "Location"
@@ -1046,7 +1097,7 @@ msgstr "Umístění"
1046
  #: app/core/src/SingleBuilder/Widgets/EventLocations/EventLocations.php:63
1047
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:77
1048
  #: app/features/speakers.php:136 app/features/speakers.php:209
1049
- #: app/skins/single.php:1406 app/skins/single.php:1473
1050
  #: app/skins/single/default.php:276 app/skins/single/default.php:354
1051
  #: app/skins/single/default.php:526 app/skins/single/default.php:603
1052
  #: app/skins/single/m1.php:148 app/skins/single/m1.php:209
@@ -1069,8 +1120,8 @@ msgstr ""
1069
  #: app/core/src/SingleBuilder/Widgets/EventMoreInfo/EventMoreInfo.php:48
1070
  #: app/features/events.php:1525 app/features/events.php:1538
1071
  #: app/features/fes/form.php:836 app/features/occurrences.php:525
1072
- #: app/libraries/main.php:7445 app/libraries/main.php:7492
1073
- #: app/skins/single.php:1223 app/skins/single/default.php:232
1074
  #: app/skins/single/default.php:481 app/skins/single/m1.php:257
1075
  #: app/skins/single/m2.php:178 app/skins/single/modern.php:211
1076
  #: app/widgets/single.php:105
@@ -1118,9 +1169,9 @@ msgid "How to set organizer"
1118
  msgstr "Skrýt organizátora"
1119
 
1120
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:53
1121
- #: app/features/events.php:431 app/features/events.php:3856
1122
- #: app/features/events.php:4171 app/features/events.php:4172
1123
- #: app/features/events.php:4173
1124
  #: app/features/mec/meta_boxes/display_options.php:1660
1125
  #: app/features/mec/meta_boxes/search_form.php:80
1126
  #: app/features/mec/meta_boxes/search_form.php:168
@@ -1142,16 +1193,16 @@ msgstr "Skrýt organizátora"
1142
  #: app/features/organizers.php:288 app/features/popup/event.php:165
1143
  #: app/features/popup/event.php:174 app/features/popup/settings.php:224
1144
  #: app/features/popup/settings.php:263 app/features/search.php:103
1145
- #: app/libraries/main.php:7407 app/libraries/main.php:7468
1146
  #: app/libraries/search.php:314 app/libraries/skins.php:1174
1147
- #: app/skins/single.php:1381 app/skins/single/default.php:329
1148
  #: app/skins/single/default.php:578 app/skins/single/m1.php:123
1149
  #: app/skins/single/m2.php:43 app/skins/single/modern.php:76
1150
  msgid "Organizer"
1151
  msgstr "Organizátor"
1152
 
1153
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:63
1154
- #: app/skins/single.php:1392 app/skins/single.php:1459
1155
  #: app/skins/single/default.php:340 app/skins/single/default.php:589
1156
  #: app/skins/single/m1.php:134 app/skins/single/m2.php:54
1157
  #: app/skins/single/modern.php:87
@@ -1183,13 +1234,13 @@ msgid "How to set register button"
1183
  msgstr "Registrační tlačítko"
1184
 
1185
  #: app/core/src/SingleBuilder/Widgets/EventRegisterButton/EventRegisterButton.php:48
1186
- #: app/libraries/main.php:7441 app/libraries/main.php:7488
1187
  #: app/skins/available_spot/tpl.php:204 app/skins/carousel/render.php:105
1188
  #: app/skins/carousel/render.php:145 app/skins/grid/render.php:94
1189
  #: app/skins/grid/render.php:153 app/skins/grid/render.php:214
1190
  #: app/skins/grid/render.php:237 app/skins/list/render.php:90
1191
  #: app/skins/list/render.php:210 app/skins/masonry/render.php:151
1192
- #: app/skins/single.php:548 app/skins/single.php:1329 app/skins/single.php:1340
1193
  #: app/skins/single/default.php:374 app/skins/single/default.php:376
1194
  #: app/skins/single/default.php:621 app/skins/single/default.php:623
1195
  #: app/skins/single/m1.php:166 app/skins/single/m1.php:168
@@ -1254,7 +1305,7 @@ msgstr "Značky: "
1254
  #: app/core/src/SingleBuilder/Widgets/EventTime/EventTime.php:43
1255
  #: app/features/emails/details.php:24 app/features/emails/details.php:27
1256
  #: app/libraries/skins.php:1362 app/modules/next-event/details.php:151
1257
- #: app/skins/single.php:1297 app/skins/single/default.php:190
1258
  #: app/skins/single/default.php:442 app/skins/single/m1.php:59
1259
  #: app/skins/single/modern.php:272
1260
  msgid "Time"
@@ -1262,14 +1313,14 @@ msgstr "Čas"
1262
 
1263
  #: app/core/src/SingleBuilder/Widgets/EventTime/EventTime.php:49
1264
  #: app/features/booking/calendar_novel.php:140
1265
- #: app/features/search_bar/search_result.php:12 app/libraries/main.php:7450
1266
- #: app/libraries/main.php:7497 app/libraries/notifications.php:1632
1267
  #: app/libraries/render.php:554 app/libraries/render.php:758
1268
  #: app/libraries/render.php:816 app/libraries/render.php:977
1269
  #: app/modules/local-time/details.php:52 app/modules/local-time/type1.php:47
1270
  #: app/modules/local-time/type2.php:83 app/modules/local-time/type3.php:47
1271
  #: app/modules/next-event/details.php:157
1272
- #: app/modules/next-event/multiple.php:65 app/skins/single.php:1303
1273
  #: app/skins/single/default.php:196 app/skins/single/default.php:448
1274
  #: app/skins/single/m1.php:65 app/skins/single/modern.php:278
1275
  #, fuzzy
@@ -1310,7 +1361,7 @@ msgstr ""
1310
  msgid "%s notification(s) sent."
1311
  msgstr "Upozornění"
1312
 
1313
- #: app/features/autoemails.php:61 app/features/mec.php:512
1314
  #, fuzzy
1315
  #| msgid "Email"
1316
  msgid "Emails"
@@ -1370,7 +1421,12 @@ msgstr ""
1370
  msgid "Coupon was not valid or applicable."
1371
  msgstr ""
1372
 
1373
- #: app/features/cart.php:174
 
 
 
 
 
1374
  #, fuzzy
1375
  #| msgid "Request is not valid."
1376
  msgid "Request is invalid!"
@@ -1380,7 +1436,7 @@ msgstr "Požadavek není platný."
1380
  msgid "Your cart is not free!"
1381
  msgstr ""
1382
 
1383
- #: app/features/cart.php:191
1384
  #, fuzzy
1385
  #| msgid "Thanks for your booking."
1386
  msgid "Thanks for your booking."
@@ -1398,7 +1454,7 @@ msgstr "Výchozí hodnota je prázdná"
1398
  msgid "Go to events page"
1399
  msgstr "Zobrazit Mapy Google na stránce události"
1400
 
1401
- #: app/features/cart/cart.php:43 app/features/events.php:4715
1402
  #: app/features/fes.php:280 app/features/mec/booking.php:351
1403
  #: app/features/wc.php:81 app/libraries/main.php:3013
1404
  #: app/libraries/main.php:3127 app/libraries/main.php:3230
@@ -1419,7 +1475,7 @@ msgstr "Událost"
1419
 
1420
  #: app/features/cart/cart.php:45 app/features/events.php:1564
1421
  #: app/features/events.php:1930 app/libraries/book.php:172
1422
- #: app/libraries/main.php:7435 app/modules/booking/steps/tickets.php:168
1423
  #: app/modules/booking/steps/tickets.php:174
1424
  msgid "Tickets"
1425
  msgstr "Vstupenky"
@@ -1464,13 +1520,14 @@ msgid "Free %s"
1464
  msgstr "Zdarma"
1465
 
1466
  #: app/features/cart/checkout.php:96 app/features/contextual.php:308
1467
- #: app/features/events.php:397 app/features/mec/booking.php:88
1468
- #: app/features/mec/notifications.php:45 app/features/mec/support-page.php:110
1469
- #: app/features/mec/support-page.php:114 app/libraries/main.php:647
1470
- #: app/libraries/main.php:648 app/libraries/main.php:652
1471
- #: app/libraries/main.php:677 app/libraries/main.php:795
1472
- #: app/libraries/main.php:3022 app/libraries/main.php:7425
1473
- #: app/libraries/main.php:7427 app/modules/booking/steps/checkout.php:146
 
1474
  msgid "Booking"
1475
  msgstr "Rezervace"
1476
 
@@ -1491,8 +1548,8 @@ msgstr "Barva události"
1491
  msgid "Recent Colors"
1492
  msgstr "Barva události"
1493
 
1494
- #: app/features/contextual.php:55 app/features/mec.php:516
1495
- #: app/features/mec/dashboard.php:143 app/features/mec/support.php:20
1496
  #: app/features/mec/wizard.php:521 app/features/popup/event.php:61
1497
  #: app/features/popup/settings.php:30 app/features/popup/shortcode.php:39
1498
  #: app/libraries/main.php:703
@@ -1500,8 +1557,8 @@ msgid "Settings"
1500
  msgstr "Nastavení"
1501
 
1502
  #: app/features/contextual.php:62 app/features/events.php:1571
1503
- #: app/features/events.php:2663 app/features/mec/booking.php:756
1504
- #: app/features/mec/booking.php:1027 app/features/mec/settings.php:1018
1505
  #: app/features/mec/support.php:29
1506
  msgid "Booking Form"
1507
  msgstr "Rezervační formulář"
@@ -1682,7 +1739,7 @@ msgid "Exceptional Days"
1682
  msgstr "Výjimečné dny"
1683
 
1684
  #: app/features/contextual.php:318 app/features/mec/booking.php:553
1685
- #: app/features/mec/booking.php:984 app/libraries/main.php:649
1686
  msgid "Coupons"
1687
  msgstr "Kupóny"
1688
 
@@ -1705,42 +1762,63 @@ msgstr "Aktivace MEC"
1705
  msgid "Downloadable File"
1706
  msgstr "Stáhnout ICS soubor"
1707
 
1708
- #: app/features/dlfile.php:142 app/features/dlfile.php:288
1709
  msgid "pdf,zip,png,jpg and gif files are allowed."
1710
  msgstr ""
1711
 
1712
- #: app/features/dlfile.php:144 app/features/dlfile.php:290
1713
  #, fuzzy
1714
  #| msgid "Remove image"
1715
  msgid "Remove File"
1716
  msgstr "Odebrat obrázek"
1717
 
1718
- #: app/features/dlfile.php:162 app/features/dlfile.php:308
1719
  #, fuzzy
1720
  #| msgid "Please upload the feed file."
1721
  msgid "Please upload a file."
1722
  msgstr "Nahrajte prosím zdrojový soubor."
1723
 
1724
- #: app/features/dlfile.php:170 app/features/dlfile.php:316
1725
  #, php-format
1726
  msgid "File extension is invalid. You can upload %s files."
1727
  msgstr ""
1728
 
1729
- #: app/features/dlfile.php:176 app/features/dlfile.php:322
1730
  #, php-format
1731
  msgid "File is too big. Maximum size is %s KB."
1732
  msgstr ""
1733
 
1734
- #: app/features/dlfile.php:206 app/features/dlfile.php:352
1735
  #, fuzzy
1736
  #| msgid "The image is uploaded!"
1737
  msgid "File uploaded!"
1738
  msgstr "Obrázek je nahraný!"
1739
 
1740
- #: app/features/dlfile.php:284
1741
  msgid "Public File to Download"
1742
  msgstr ""
1743
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1744
  #: app/features/emails/details.php:26
1745
  #, fuzzy
1746
  #| msgid "Organizer Email"
@@ -1793,8 +1871,8 @@ msgid "event occurrence."
1793
  msgstr "Další výskyt"
1794
 
1795
  #: app/features/emails/details.php:40 app/features/events.php:192
1796
- #: app/features/ix/export.php:37 app/features/mec/dashboard.php:234
1797
- #: app/libraries/main.php:6428 app/libraries/main.php:6448
1798
  #: app/skins/daily_view/tpl.php:84 app/skins/monthly_view/calendar_clean.php:46
1799
  #: app/skins/monthly_view/tpl.php:76 app/skins/tile/tpl.php:85
1800
  #: app/skins/yearly_view/tpl.php:73
@@ -1809,12 +1887,12 @@ msgstr "Všechny události"
1809
  msgid "Placeholders"
1810
  msgstr ""
1811
 
1812
- #: app/features/events.php:194 app/features/mec.php:492
1813
  #: app/features/mec/wizard.php:511
1814
  msgid "Add Event"
1815
  msgstr "Přidat událost"
1816
 
1817
- #: app/features/events.php:195 app/features/mec/dashboard.php:142
1818
  msgid "Add New Event"
1819
  msgstr "Přidat novou událost"
1820
 
@@ -1837,11 +1915,11 @@ msgstr "Zobrazit událost"
1837
  msgid "No events found in Trash!"
1838
  msgstr "V koši nebyly nalezeny žádné události!"
1839
 
1840
- #: app/features/events.php:219 app/features/events.php:3810
1841
- #: app/features/events.php:4177 app/features/fes/form.php:972
1842
- #: app/features/mec.php:494 app/features/mec/meta_boxes/filter.php:69
1843
- #: app/features/mec/meta_boxes/filter.php:81 app/libraries/main.php:7400
1844
- #: app/libraries/main.php:7461
1845
  msgid "Categories"
1846
  msgstr "Kategorie"
1847
 
@@ -1960,7 +2038,7 @@ msgid "Event Data"
1960
  msgstr "Zobrazit událost"
1961
 
1962
  #: app/features/events.php:428 app/features/mec/settings.php:943
1963
- #: app/libraries/hourlyschedule.php:36 app/skins/single.php:1565
1964
  msgid "Hourly Schedule"
1965
  msgstr "Hodinový rozvrh"
1966
 
@@ -1994,11 +2072,14 @@ msgstr "Poznámka pro recenzenta"
1994
  msgid "Guest Data"
1995
  msgstr "Údaje hosta"
1996
 
1997
- #: app/features/events.php:605 app/features/events.php:2649
1998
- #: app/features/events.php:4419 app/features/fes.php:280
1999
- #: app/features/fes/form.php:814 app/features/labels.php:184
 
 
 
2000
  #: app/features/mec/booking.php:45 app/features/organizers.php:296
2001
- #: app/features/popup/event.php:184 app/features/profile/profile.php:192
2002
  #: app/libraries/notifications.php:2090 app/modules/booking/steps/form.php:60
2003
  msgid "Name"
2004
  msgstr "Jméno"
@@ -2014,9 +2095,9 @@ msgid "Date and Time"
2014
  msgstr "Datum a čas"
2015
 
2016
  #: app/features/events.php:622 app/features/events.php:626
2017
- #: app/features/events.php:3857 app/features/events.php:4164
2018
  #: app/features/fes/form.php:286 app/features/fes/form.php:290
2019
- #: app/features/ix/import_g_calendar.php:38 app/features/mec.php:1525
2020
  #: app/features/mec/meta_boxes/display_options.php:57
2021
  #: app/features/mec/meta_boxes/display_options.php:312
2022
  #: app/features/mec/meta_boxes/display_options.php:578
@@ -2038,9 +2119,9 @@ msgid "Start Date"
2038
  msgstr "Počátečná den"
2039
 
2040
  #: app/features/events.php:642 app/features/events.php:646
2041
- #: app/features/events.php:3858 app/features/events.php:4166
2042
  #: app/features/fes/form.php:306 app/features/fes/form.php:310
2043
- #: app/features/ix/import_g_calendar.php:44 app/features/mec.php:1526
2044
  #: app/features/mec/meta_boxes/display_options.php:73
2045
  #: app/features/mec/meta_boxes/display_options.php:328
2046
  #: app/features/mec/meta_boxes/display_options.php:594
@@ -2095,8 +2176,8 @@ msgstr "Časové pásmo: %s"
2095
  #: app/features/events.php:716 app/features/events.php:729
2096
  #: app/features/events.php:1768 app/features/events.php:1778
2097
  #: app/features/events.php:1799 app/features/events.php:1819
2098
- #: app/features/events.php:1874 app/features/events.php:2446
2099
- #: app/features/events.php:2569 app/features/events.php:2680
2100
  #: app/features/fes/form.php:347 app/features/fes/form.php:360
2101
  msgid "Inherit from global options"
2102
  msgstr "Zdědí z globálních možností"
@@ -2158,7 +2239,7 @@ msgid "Repeats"
2158
  msgstr "Opakování"
2159
 
2160
  #: app/features/events.php:770 app/features/fes/form.php:390
2161
- #: app/features/mec.php:1528 app/skins/default_full_calendar/tpl.php:79
2162
  #: app/skins/full_calendar/tpl.php:140
2163
  msgid "Daily"
2164
  msgstr "Děnně"
@@ -2182,13 +2263,13 @@ msgid "Weekly"
2182
  msgstr "Týdně"
2183
 
2184
  #: app/features/events.php:805 app/features/fes/form.php:395
2185
- #: app/features/mec.php:1529 app/skins/default_full_calendar/tpl.php:77
2186
  #: app/skins/full_calendar/tpl.php:138
2187
  msgid "Monthly"
2188
  msgstr "Měsíčně"
2189
 
2190
  #: app/features/events.php:812 app/features/fes/form.php:396
2191
- #: app/features/mec.php:1530 app/skins/default_full_calendar/tpl.php:76
2192
  #: app/skins/full_calendar/tpl.php:137
2193
  msgid "Yearly"
2194
  msgstr "Ročně"
@@ -2222,7 +2303,7 @@ msgid ""
2222
  msgstr "Pro verze doplňku Modern Events Calendar"
2223
 
2224
  #: app/features/events.php:860 app/features/events.php:2107
2225
- #: app/features/events.php:2135 app/features/events.php:2351
2226
  #: app/features/fes/form.php:420 app/features/ix/import_f_calendar.php:42
2227
  #: app/features/ix/import_g_calendar.php:51
2228
  #: app/features/ix/import_meetup.php:40 app/features/ix/thirdparty.php:35
@@ -2232,8 +2313,8 @@ msgstr "Začátek"
2232
 
2233
  #: app/features/events.php:874 app/features/events.php:1398
2234
  #: app/features/events.php:2091 app/features/events.php:2173
2235
- #: app/features/events.php:2340 app/features/events.php:2384
2236
- #: app/features/events.php:2457 app/features/events.php:2574
2237
  #: app/features/fes/form.php:451 app/features/fes/form.php:1070
2238
  #: app/features/occurrences.php:113 app/features/organizers.php:340
2239
  #: app/libraries/hourlyschedule.php:57 app/libraries/hourlyschedule.php:134
@@ -2260,7 +2341,7 @@ msgstr ""
2260
  "datum zahájení a ukončení musí odpovídat počátečnímu datu."
2261
 
2262
  #: app/features/events.php:891 app/features/events.php:2111
2263
- #: app/features/events.php:2139 app/features/events.php:2355
2264
  #: app/features/fes/form.php:436 app/libraries/skins.php:1356
2265
  msgid "End"
2266
  msgstr "Konec"
@@ -2321,7 +2402,7 @@ msgstr ""
2321
  msgid "Show only one occurrence of this event"
2322
  msgstr "Další výskyt dalších událostí"
2323
 
2324
- #: app/features/events.php:1277 app/features/events.php:4174
2325
  #: app/features/fes/form.php:865
2326
  #: app/features/mec/meta_boxes/search_form.php:116
2327
  #: app/features/mec/meta_boxes/search_form.php:204
@@ -2347,7 +2428,7 @@ msgstr "Další výskyt dalších událostí"
2347
  #: app/features/mec/notifications.php:1628
2348
  #: app/features/mec/notifications.php:1778 app/features/mec/settings.php:860
2349
  #: app/features/notifications.php:160 app/features/occurrences.php:508
2350
- #: app/libraries/main.php:7446 app/libraries/main.php:7493
2351
  #: app/widgets/single.php:101
2352
  msgid "Event Cost"
2353
  msgstr "Cena události"
@@ -2448,8 +2529,8 @@ msgstr "Odkazy na událost"
2448
 
2449
  #: app/features/events.php:1507 app/features/events.php:1515
2450
  #: app/features/fes/form.php:831 app/features/mec/settings.php:1163
2451
- #: app/features/occurrences.php:520 app/libraries/main.php:7444
2452
- #: app/libraries/main.php:7491
2453
  msgid "Event Link"
2454
  msgstr "Odkaz na událost"
2455
 
@@ -2484,13 +2565,13 @@ msgid "More Information"
2484
  msgstr "Více informací"
2485
 
2486
  #: app/features/events.php:1533 app/features/fes/form.php:840
2487
- #: app/features/mec.php:1084 app/features/occurrences.php:529
2488
  #: app/features/popup/shortcode.php:481
2489
  msgid "Current Window"
2490
  msgstr "Aktuální okno"
2491
 
2492
  #: app/features/events.php:1534 app/features/fes/form.php:841
2493
- #: app/features/mec.php:1085 app/features/occurrences.php:530
2494
  #: app/features/popup/shortcode.php:485
2495
  msgid "New Window"
2496
  msgstr "Nové okno"
@@ -2514,22 +2595,22 @@ msgstr "Možnosti rezervace"
2514
  msgid "Total User Booking Limits"
2515
  msgstr "Celkové limity rezervace uživatelů"
2516
 
2517
- #: app/features/events.php:1566 app/features/events.php:2434
2518
  msgid "Fees"
2519
  msgstr "Poplatky"
2520
 
2521
- #: app/features/events.php:1569 app/features/events.php:2564
2522
  #: app/features/mec/settings.php:1030
2523
  msgid "Ticket Variations / Options"
2524
  msgstr "Varianty vstupenky / možnosti"
2525
 
2526
- #: app/features/events.php:1573 app/features/mec/booking.php:1058
2527
  #: app/features/mec/support-page.php:118
2528
  msgid "Organizer Payment"
2529
  msgstr "Platba organizátora"
2530
 
2531
  #: app/features/events.php:1581 app/features/ix/export.php:58
2532
- #: app/libraries/main.php:7428
2533
  msgid "Bookings"
2534
  msgstr "Rezervace"
2535
 
@@ -2540,7 +2621,7 @@ msgid "Total booking limit"
2540
  msgstr "Celkové limity rezervace"
2541
 
2542
  #: app/features/events.php:1659 app/features/events.php:2057
2543
- #: app/features/events.php:2306 app/modules/booking/default.php:116
2544
  #: app/modules/booking/default.php:221
2545
  #: app/modules/booking/steps/tickets.php:168
2546
  #: app/modules/booking/steps/tickets.php:174
@@ -2642,9 +2723,10 @@ msgid "Email Verification"
2642
  msgstr "Ověřovací email"
2643
 
2644
  #: app/features/events.php:1769 app/features/events.php:1779
2645
- #: app/features/mec/booking.php:210 app/features/mec/booking.php:277
2646
- #: app/features/mec/booking.php:292 app/features/mec/booking.php:374
2647
- #: app/features/mec/booking.php:995 app/features/mec/booking.php:1022
 
2648
  #: app/features/mec/meta_boxes/search_form.php:66
2649
  #: app/features/mec/meta_boxes/search_form.php:74
2650
  #: app/features/mec/meta_boxes/search_form.php:82
@@ -2781,10 +2863,11 @@ msgid "Disabled"
2781
  msgstr "Zakázaný"
2782
 
2783
  #: app/features/events.php:1770 app/features/events.php:1780
2784
- #: app/features/mec/booking.php:209 app/features/mec/booking.php:276
2785
- #: app/features/mec/booking.php:293 app/features/mec/booking.php:994
2786
- #: app/features/mec/booking.php:1023 app/features/mec/modules.php:155
2787
- #: app/features/mec/settings.php:99 app/features/popup/settings.php:357
 
2788
  msgid "Enabled"
2789
  msgstr "Povoleno"
2790
 
@@ -2880,7 +2963,7 @@ msgid "Ticket ID"
2880
  msgstr "Vstupenka"
2881
 
2882
  #: app/features/events.php:1950 app/features/events.php:2217
2883
- #: app/features/events.php:4161 app/features/fes.php:280
2884
  #: app/features/labels.php:183 app/features/locations.php:266
2885
  #: app/features/organizers.php:207 app/features/speakers.php:285
2886
  msgid "ID"
@@ -2891,21 +2974,15 @@ msgid "Ticket Name"
2891
  msgstr "Název vstupenky"
2892
 
2893
  #: app/features/events.php:1962 app/features/events.php:2225
2894
- #: app/features/events.php:4165 app/libraries/skins.php:1370
2895
  msgid "Start Time"
2896
  msgstr "Začátek"
2897
 
2898
  #: app/features/events.php:1976 app/features/events.php:2239
2899
- #: app/features/events.php:4167 app/libraries/skins.php:1371
2900
  msgid "End Time"
2901
  msgstr "Konec"
2902
 
2903
- #: app/features/events.php:1994 app/features/events.php:2254
2904
- #: app/features/events.php:4163 app/libraries/hourlyschedule.php:72
2905
- #: app/libraries/hourlyschedule.php:100 app/libraries/hourlyschedule.php:152
2906
- msgid "Description"
2907
- msgstr "Popis"
2908
-
2909
  #: app/features/events.php:2000 app/features/events.php:2003
2910
  #: app/features/events.php:2259 app/features/events.php:2262
2911
  #: app/features/mec/settings.php:1012
@@ -2923,8 +3000,8 @@ msgstr ""
2923
 
2924
  #: app/features/events.php:2013 app/features/events.php:2017
2925
  #: app/features/events.php:2115 app/features/events.php:2142
2926
- #: app/features/events.php:2272 app/features/events.php:2275
2927
- #: app/features/events.php:2357 app/features/events.php:4718
2928
  #: app/features/mec/booking.php:690 app/features/mec/booking.php:693
2929
  #: app/features/mec/booking.php:722 app/features/mec/booking.php:725
2930
  #: app/libraries/ticketVariations.php:43 app/libraries/ticketVariations.php:46
@@ -2932,7 +3009,7 @@ msgstr ""
2932
  msgid "Price"
2933
  msgstr "Cena"
2934
 
2935
- #: app/features/events.php:2018 app/features/events.php:2276
2936
  #, fuzzy
2937
  #| msgid "Insert 0 for free ticket. Only numbers please."
2938
  msgid ""
@@ -2941,60 +3018,60 @@ msgid ""
2941
  msgstr "Vložte 0 pro vstupenku zdarma. Prosím pouze čísla."
2942
 
2943
  #: app/features/events.php:2027 app/features/events.php:2032
2944
- #: app/features/events.php:2285 app/features/events.php:2288
2945
  msgid "Price Label"
2946
  msgstr "Cenový štítek"
2947
 
2948
- #: app/features/events.php:2033 app/features/events.php:2289
2949
  msgid "For showing on website. e.g. $15"
2950
  msgstr "Pro zobrazení na webu. např. 15 $"
2951
 
2952
- #: app/features/events.php:2044 app/features/events.php:2300
2953
  msgid "Available Tickets"
2954
  msgstr "Dostupné vstupenky"
2955
 
2956
- #: app/features/events.php:2063 app/features/events.php:2312
2957
  #, fuzzy
2958
  #| msgid "Maximum Per Ticket"
2959
  msgid "Minimum Ticket e.g. 3"
2960
  msgstr "Maximum na jednu vstupenku"
2961
 
2962
- #: app/features/events.php:2066 app/features/events.php:2315
2963
  #, fuzzy
2964
  #| msgid "Maximum Per Ticket"
2965
  msgid "MinimumTicket"
2966
  msgstr "Maximum na jednu vstupenku"
2967
 
2968
- #: app/features/events.php:2068 app/features/events.php:2317
2969
  msgid "Set a number for the minimum ticket reservation possible"
2970
  msgstr ""
2971
 
2972
- #: app/features/events.php:2077 app/features/events.php:2326
2973
  msgid "e.g. 0"
2974
  msgstr ""
2975
 
2976
- #: app/features/events.php:2079 app/features/events.php:2328
2977
  #, fuzzy
2978
  #| msgid "Days"
2979
  msgid "Day"
2980
  msgstr "Dny"
2981
 
2982
- #: app/features/events.php:2080 app/features/events.php:2329
2983
  #: app/features/mec/notifications.php:1734
2984
  msgid "Hour"
2985
  msgstr ""
2986
 
2987
- #: app/features/events.php:2082 app/features/events.php:2331
2988
  #, php-format
2989
  msgid "Stop selling ticket %s before event start."
2990
  msgstr ""
2991
 
2992
- #: app/features/events.php:2089 app/features/events.php:2338
2993
  msgid "Price per Date"
2994
  msgstr "Cena za datum"
2995
 
2996
  #: app/features/events.php:2119 app/features/events.php:2145
2997
- #: app/features/events.php:2359 app/features/labels.php:60
2998
  #: app/features/mec/meta_boxes/display_options.php:1658
2999
  #: app/features/mec/meta_boxes/search_form.php:101
3000
  #: app/features/mec/meta_boxes/search_form.php:189
@@ -3016,31 +3093,32 @@ msgstr "Cena za datum"
3016
  msgid "Label"
3017
  msgstr "Štítek"
3018
 
3019
- #: app/features/events.php:2163 app/features/events.php:2374
3020
  #, fuzzy
3021
  #| msgid "Maximum Per Ticket"
3022
  msgid "Variations Per Ticket"
3023
  msgstr "Maximum na jednu vstupenku"
3024
 
3025
- #: app/features/events.php:2168 app/features/events.php:2379
3026
  #, fuzzy
3027
  #| msgid "Inherit from global options"
3028
  msgid "Inherit from event options"
3029
  msgstr "Zdědí z globálních možností"
3030
 
3031
- #: app/features/events.php:2471 app/features/events.php:2510
3032
  #: app/features/mec/booking.php:590 app/features/mec/booking.php:620
3033
  msgid "Fee Title"
3034
  msgstr "Název poplatku"
3035
 
3036
- #: app/features/events.php:2477 app/features/events.php:2481
3037
- #: app/features/events.php:2515 app/features/events.php:2518
3038
- #: app/features/mec/booking.php:594 app/features/mec/booking.php:597
3039
- #: app/features/mec/booking.php:624 app/features/mec/booking.php:627
 
3040
  msgid "Amount"
3041
  msgstr "Množství"
3042
 
3043
- #: app/features/events.php:2482 app/features/events.php:2519
3044
  #: app/features/mec/booking.php:598 app/features/mec/booking.php:628
3045
  msgid ""
3046
  "Fee amount, considered as fixed amount if you set the type to amount "
@@ -3049,29 +3127,30 @@ msgstr ""
3049
  "Výše poplatku, je považovaná za pevnou částku, pokud nastavíte typ na částku "
3050
  "odpovídající procentuální hodnotě"
3051
 
3052
- #: app/features/events.php:2491 app/features/events.php:2528
3053
- #: app/features/mec/booking.php:605 app/features/mec/booking.php:635
 
3054
  msgid "Percent"
3055
  msgstr "Procent"
3056
 
3057
- #: app/features/events.php:2492 app/features/events.php:2529
3058
  #: app/features/mec/booking.php:606 app/features/mec/booking.php:636
3059
  msgid "Amount (Per Ticket)"
3060
  msgstr "Částka (za vstupenku)"
3061
 
3062
- #: app/features/events.php:2493 app/features/events.php:2530
3063
  #: app/features/mec/booking.php:607 app/features/mec/booking.php:637
3064
  #, fuzzy
3065
  #| msgid "Amount (Per Ticket)"
3066
  msgid "Amount (Per Date)"
3067
  msgstr "Částka (za vstupenku)"
3068
 
3069
- #: app/features/events.php:2494 app/features/events.php:2531
3070
  #: app/features/mec/booking.php:608 app/features/mec/booking.php:638
3071
  msgid "Amount (Per Booking)"
3072
  msgstr "Částka (za rezervaci)"
3073
 
3074
- #: app/features/events.php:2666
3075
  #, fuzzy
3076
  #| msgid ""
3077
  #| "You're translating an event so MEC will use the original event for "
@@ -3087,130 +3166,120 @@ msgstr ""
3087
  "vstupenek a rezervace. Můžete přeložit pouze název a popis vstupenky. Prosím "
3088
  "definujte určité vstupenky, které jste definovali v původní události."
3089
 
3090
- #: app/features/events.php:2692 app/features/mec/booking.php:758
3091
  #, fuzzy
3092
  #| msgid "Attendees Limit"
3093
  msgid "Per Attendee Fields"
3094
  msgstr "Limit účastníků"
3095
 
3096
- #: app/features/events.php:2783 app/features/mec/booking.php:856
3097
  #, fuzzy
3098
  #| msgid "Required Field"
3099
  msgid "Fixed Fields"
3100
  msgstr "Požadovaná pole"
3101
 
3102
- #: app/features/events.php:2895 app/features/events.php:4712
3103
  #: app/features/mec/settings.php:1036 app/features/profile/profile.php:65
3104
  #: app/libraries/main.php:3048 app/libraries/main.php:3293
3105
  msgid "Attendees"
3106
  msgstr "Účastníci"
3107
 
3108
- #: app/features/events.php:2898 app/features/occurrences.php:104
3109
  #, fuzzy
3110
  #| msgid "Next Occurrence"
3111
  msgid "Occurrence"
3112
  msgstr "Další výskyt"
3113
 
3114
- #: app/features/events.php:2899 app/features/mec.php:1731
3115
  #: app/features/occurrences.php:105
3116
  #, fuzzy
3117
  #| msgid "Next Occurrence"
3118
  msgid "Previous Occurrences"
3119
  msgstr "Další výskyt"
3120
 
3121
- #: app/features/events.php:2904 app/features/mec.php:1741
3122
- #: app/features/occurrences.php:110 app/modules/next-event/multiple.php:52
3123
  #, fuzzy
3124
  #| msgid "Next Occurrence"
3125
  msgid "Next Occurrences"
3126
  msgstr "Další výskyt"
3127
 
3128
- #: app/features/events.php:3735 app/features/mec/meta_boxes/filter.php:199
3129
  #: app/features/mec/settings.php:517
3130
  msgid "Expired Events"
3131
  msgstr "Události vypršely"
3132
 
3133
- #: app/features/events.php:3736 app/features/mec.php:1335
3134
- #: app/features/mec/dashboard.php:266 app/features/mec/settings.php:516
3135
  msgid "Upcoming Events"
3136
  msgstr "Nadcházející události"
3137
 
3138
- #: app/features/events.php:3756 app/features/events.php:3774
3139
- #: app/features/events.php:3792 app/features/events.php:3810
3140
  #, php-format
3141
  msgid "Show all %s"
3142
  msgstr "Ukázat všechny %s"
3143
 
3144
- #: app/features/events.php:3756
3145
  msgid "labels"
3146
  msgstr "štítky"
3147
 
3148
- #: app/features/events.php:3774
3149
  msgid "locations"
3150
  msgstr "umístění"
3151
 
3152
- #: app/features/events.php:3792
3153
  msgid "organizers"
3154
  msgstr "organizátoři"
3155
 
3156
- #: app/features/events.php:3826
3157
  #, fuzzy
3158
  #| msgid "Attendees Limit"
3159
  msgid "Attendees List"
3160
  msgstr "Limit účastníků"
3161
 
3162
- #: app/features/events.php:3853 app/features/events.php:4162
3163
- #: app/features/events.php:4709 app/features/fes/form.php:260
3164
- #: app/features/mec/booking.php:686 app/features/mec/booking.php:718
3165
- #: app/features/mec/styling.php:134 app/libraries/hourlyschedule.php:49
3166
- #: app/libraries/hourlyschedule.php:65 app/libraries/hourlyschedule.php:93
3167
- #: app/libraries/hourlyschedule.php:125 app/libraries/hourlyschedule.php:145
3168
- #: app/libraries/ticketVariations.php:39
3169
- msgid "Title"
3170
- msgstr "Název"
3171
-
3172
- #: app/features/events.php:3861
3173
  #, fuzzy
3174
  #| msgid "Tickets"
3175
  msgid "Sold Tickets"
3176
  msgstr "Vstupenky"
3177
 
3178
- #: app/features/events.php:3863
3179
  msgid "Repeat"
3180
  msgstr "Opakovat"
3181
 
3182
- #: app/features/events.php:4032 app/features/events.php:4033
3183
  #, fuzzy
3184
  #| msgid "iCal Export"
3185
  msgid "iCal / Outlook Export"
3186
  msgstr "iCal Export"
3187
 
3188
- #: app/features/events.php:4035 app/features/events.php:4036
3189
  msgid "CSV Export"
3190
  msgstr "CSV Export"
3191
 
3192
- #: app/features/events.php:4038 app/features/events.php:4039
3193
  msgid "MS Excel Export"
3194
  msgstr "MS Excel Export"
3195
 
3196
- #: app/features/events.php:4041 app/features/events.php:4042
3197
  msgid "XML Export"
3198
  msgstr "XML Export"
3199
 
3200
- #: app/features/events.php:4044 app/features/events.php:4045
3201
  msgid "JSON Export"
3202
  msgstr "JSON Export"
3203
 
3204
- #: app/features/events.php:4047 app/features/events.php:4048
3205
- #: app/features/events.php:4274
3206
  msgid "Duplicate"
3207
  msgstr "Duplikát"
3208
 
3209
- #: app/features/events.php:4168
3210
  msgid "Link"
3211
  msgstr "Odkaz"
3212
 
3213
- #: app/features/events.php:4170 app/features/locations.php:111
3214
  #: app/features/locations.php:181 app/features/locations.php:268
3215
  #: app/features/mec/meta_boxes/search_form.php:108
3216
  #: app/features/mec/meta_boxes/search_form.php:196
@@ -3228,73 +3297,73 @@ msgstr "Odkaz"
3228
  msgid "Address"
3229
  msgstr "Adresa"
3230
 
3231
- #: app/features/events.php:4172
3232
  #, php-format
3233
  msgid "%s Tel"
3234
  msgstr "%s Tel"
3235
 
3236
- #: app/features/events.php:4173
3237
  #, php-format
3238
  msgid "%s Email"
3239
  msgstr "%s Email"
3240
 
3241
  # v kontextu
3242
- #: app/features/events.php:4175 app/features/fes/form.php:951
3243
  #: app/features/mec/settings.php:866
3244
  msgid "Featured Image"
3245
  msgstr "Hlavní obrázek"
3246
 
3247
- #: app/features/events.php:4178 app/features/fes/form.php:1044
3248
- #: app/features/mec.php:493 app/features/mec/meta_boxes/filter.php:73
3249
  #: app/features/mec/meta_boxes/filter.php:153 app/features/tag.php:59
3250
  msgid "Tags"
3251
  msgstr "Tagy"
3252
 
3253
- #: app/features/events.php:4182 app/features/fes/form.php:1066
3254
- #: app/features/mec.php:502 app/features/mec/modules.php:34
3255
  #: app/features/mec/modules.php:43 app/features/mec/settings.php:937
3256
  #: app/features/popup/settings.php:299 app/features/speakers.php:61
3257
  #: app/libraries/hourlyschedule.php:77 app/libraries/hourlyschedule.php:105
3258
  #: app/libraries/hourlyschedule.php:157 app/libraries/main.php:659
3259
- #: app/libraries/main.php:7408 app/libraries/main.php:7469
3260
  #: app/modules/speakers/details.php:18
3261
  msgid "Speakers"
3262
  msgstr "Řečníci"
3263
 
3264
- #: app/features/events.php:4425 app/features/fes.php:280
3265
- #: app/features/profile/profile.php:198 app/libraries/cart.php:64
3266
- #: app/libraries/main.php:3064 app/libraries/main.php:3310
3267
- #: app/libraries/main.php:7434
3268
  msgid "Ticket"
3269
  msgstr "Vstupenka"
3270
 
3271
- #: app/features/events.php:4428 app/features/profile/profile.php:201
3272
  msgid "Variations"
3273
  msgstr "Variace"
3274
 
3275
- #: app/features/events.php:4443 app/features/fes.php:356
3276
  msgid "Unknown"
3277
  msgstr "Neznámý"
3278
 
3279
- #: app/features/events.php:4471
3280
  msgid ""
3281
  "If you want to send an email, first select your attendees and then click in "
3282
  "the button below, please."
3283
  msgstr ""
3284
 
3285
- #: app/features/events.php:4471 app/features/mec/report.php:57
3286
  #, fuzzy
3287
  #| msgid "Organizer Email"
3288
  msgid "Send Email"
3289
  msgstr "Organizátor Email"
3290
 
3291
- #: app/features/events.php:4475
3292
  #, fuzzy
3293
  #| msgid "Attendees Form"
3294
  msgid "No Attendees Found!"
3295
  msgstr "Formulář účastníků"
3296
 
3297
- #: app/features/events.php:4773
3298
  #, fuzzy
3299
  #| msgid "No bookings found!"
3300
  msgid "No Bookings Found!"
@@ -3358,8 +3427,8 @@ msgstr "Konec"
3358
  msgid "Total Price"
3359
  msgstr "Celková cena"
3360
 
3361
- #: app/features/fes.php:280 app/libraries/main.php:3122
3362
- #: app/libraries/main.php:3369
3363
  #, fuzzy
3364
  #| msgid "Payment Gateways"
3365
  msgid "Gateway"
@@ -3433,13 +3502,13 @@ msgstr "Zadejte alespoň 3 znaky"
3433
  msgid "Please select at-least one label!"
3434
  msgstr "Vyberte události, které chcete importovat!"
3435
 
3436
- #: app/features/fes.php:1370
3437
  #, fuzzy
3438
  #| msgid "The event submitted. It will publish as soon as possible."
3439
  msgid "Event submitted. It will publish as soon as possible."
3440
  msgstr "Událost byla odeslána. Zveřejní se co nejdříve."
3441
 
3442
- #: app/features/fes.php:1371
3443
  msgid "The event published."
3444
  msgstr "Událost byla publikována."
3445
 
@@ -3613,6 +3682,563 @@ msgstr ""
3613
  msgid "No events found! %s"
3614
  msgstr "Nebyly nalezeny žádné události! %s"
3615
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3616
  #: app/features/ix.php:108
3617
  msgid "MEC - Import / Export"
3618
  msgstr "MEC Import / Export"
@@ -3966,7 +4592,7 @@ msgstr "Účastníci akce"
3966
  msgid "Add to Google Calendar"
3967
  msgstr "Přidat do Google kalendáře"
3968
 
3969
- #: app/features/ix/export_g_calendar.php:100 app/features/mec/booking.php:1248
3970
  #: app/features/mec/integrations.php:451 app/features/mec/modules.php:408
3971
  #: app/features/mec/notifications.php:1924 app/features/mec/settings.php:1601
3972
  #: app/features/mec/single.php:597
@@ -4085,7 +4711,7 @@ msgstr "Import z Facebook kalendáře"
4085
  msgid "Import all of your Facebook events into MEC."
4086
  msgstr "Importujte všechny své události na Facebooku do MEC."
4087
 
4088
- #: app/features/ix/import_f_calendar.php:27 app/features/mec/dashboard.php:144
4089
  #: app/features/mec/support-page.php:11 app/features/mec/support.php:100
4090
  msgid "Documentation"
4091
  msgstr "Dokumentace"
@@ -4478,10 +5104,10 @@ msgstr "Slug"
4478
  msgid "Event %s"
4479
  msgstr "Událost %s"
4480
 
4481
- #: app/features/locations.php:59 app/features/mec.php:496
4482
- #: app/features/mec/dashboard.php:248 app/features/mec/meta_boxes/filter.php:70
4483
- #: app/features/mec/meta_boxes/filter.php:99 app/libraries/main.php:7404
4484
- #: app/libraries/main.php:7465
4485
  msgid "Locations"
4486
  msgstr "Umístění"
4487
 
@@ -4598,8 +5224,8 @@ msgstr "Vyberte obrázek"
4598
  msgid "Don't show map in single event page"
4599
  msgstr "Nezobrazovat mapu na jednostránkové události"
4600
 
4601
- #: app/features/locations.php:409 app/libraries/main.php:7449
4602
- #: app/libraries/main.php:7496
4603
  msgid "Other Locations"
4604
  msgstr "Další místa"
4605
 
@@ -4628,7 +5254,7 @@ msgstr ""
4628
  msgid "Forgot Password?"
4629
  msgstr ""
4630
 
4631
- #: app/features/mec.php:223
4632
  #, fuzzy
4633
  #| msgid ""
4634
  #| "Activation faild. Please check your purchase code or license type."
@@ -4641,21 +5267,21 @@ msgstr ""
4641
  "<br> <b> Poznámka: Váš nákupní kód by se měl shodovat s vaším typem licence. "
4642
  "</b>"
4643
 
4644
- #: app/features/mec.php:223 app/features/mec/support-page.php:136
4645
  msgid "Troubleshooting"
4646
  msgstr "Odstraňování problémů"
4647
 
4648
- #: app/features/mec.php:312
4649
  #, fuzzy
4650
  #| msgid "Select Type"
4651
  msgid "Select Date"
4652
  msgstr "Vyberte typ"
4653
 
4654
- #: app/features/mec.php:316 app/skins/masonry.php:265
4655
  msgid "All"
4656
  msgstr "Vše"
4657
 
4658
- #: app/features/mec.php:358
4659
  #, fuzzy
4660
  #| msgid ""
4661
  #| "Your options is not in JSON format. Please insert correct options in this "
@@ -4667,249 +5293,249 @@ msgstr ""
4667
  "Vaše možnosti nejsou ve formátu JSON. Do tohoto pole vložte správné možnosti "
4668
  "a zkuste to znovu."
4669
 
4670
- #: app/features/mec.php:365
4671
  msgid "Your options field can not be empty!"
4672
  msgstr "Pole možností nemůže být prázdné!"
4673
 
4674
- #: app/features/mec.php:371
4675
  msgid "Your options imported successfuly."
4676
  msgstr "Vaše možnosti byly úspěšně importovány."
4677
 
4678
- #: app/features/mec.php:476
4679
  msgid "MEC - Support"
4680
  msgstr "MEC - podpora"
4681
 
4682
- #: app/features/mec.php:476 app/features/mec/support-page.php:9
4683
  #: app/features/mec/support.php:80 app/features/mec/support.php:93
4684
  msgid "Support"
4685
  msgstr "Podpora"
4686
 
4687
- #: app/features/mec.php:497 app/features/mec/dashboard.php:255
4688
  #: app/features/mec/meta_boxes/filter.php:71
4689
  #: app/features/mec/meta_boxes/filter.php:117 app/features/organizers.php:59
4690
- #: app/libraries/main.php:7406 app/libraries/main.php:7467
4691
  msgid "Organizers"
4692
  msgstr "Organizátoři"
4693
 
4694
- #: app/features/mec.php:506 app/features/mec.php:567
4695
- #: app/features/mec/dashboard.php:241
4696
  msgid "Shortcodes"
4697
  msgstr "Zkrácené kódy"
4698
 
4699
- #: app/features/mec.php:516
4700
  msgid "MEC - Settings"
4701
  msgstr "MEC - Nastavení"
4702
 
4703
- #: app/features/mec.php:518
4704
  msgid "MEC - Addons"
4705
  msgstr "MEC - doplňky"
4706
 
4707
- #: app/features/mec.php:518 app/features/mec/addons.php:11
4708
  msgid "Addons"
4709
  msgstr "Doplňky"
4710
 
4711
- #: app/features/mec.php:519
4712
  msgid "MEC - Wizard"
4713
  msgstr ""
4714
 
4715
- #: app/features/mec.php:519 app/features/mec/wizard.php:512
4716
  #: app/features/mec/wizard.php:517 app/features/mec/wizard.php:522
4717
  msgid "Wizard"
4718
  msgstr ""
4719
 
4720
- #: app/features/mec.php:523
4721
  #, fuzzy
4722
  #| msgid "MEC - Support"
4723
  msgid "MEC - Report"
4724
  msgstr "MEC - podpora"
4725
 
4726
- #: app/features/mec.php:523
4727
  #, fuzzy
4728
  #| msgid "Export"
4729
  msgid "Report"
4730
  msgstr "Export"
4731
 
4732
- #: app/features/mec.php:526
4733
  #, fuzzy
4734
  #| msgid "MEC - Support"
4735
  msgid "MEC - Go Pro"
4736
  msgstr "MEC - podpora"
4737
 
4738
- #: app/features/mec.php:526 app/features/mec.php:1406
4739
  #: app/features/mec/go-pro.php:9
4740
  msgid "Go Pro"
4741
  msgstr ""
4742
 
4743
- #: app/features/mec.php:569 app/features/mec/wizard.php:516
4744
  msgid "Add Shortcode"
4745
  msgstr "Přidat zkrácený kód"
4746
 
4747
- #: app/features/mec.php:570
4748
  msgid "Add New Shortcode"
4749
  msgstr "Přidat nový zkrácený kód"
4750
 
4751
- #: app/features/mec.php:571
4752
  msgid "No shortcodes found!"
4753
  msgstr "Nebyly nalezeny žádné zkrácené kódy!"
4754
 
4755
- #: app/features/mec.php:572
4756
  msgid "All Shortcodes"
4757
  msgstr "Všechny zkrácené kódy"
4758
 
4759
- #: app/features/mec.php:573
4760
  msgid "Edit shortcodes"
4761
  msgstr "Editace zkrácených kódů"
4762
 
4763
- #: app/features/mec.php:574
4764
  msgid "No shortcodes found in Trash!"
4765
  msgstr "V koši nebyly nalezeny žádné zkrácené kódy!"
4766
 
4767
- #: app/features/mec.php:627
4768
  msgid "Display Options"
4769
  msgstr "Zobrazit možnosti"
4770
 
4771
- #: app/features/mec.php:628
4772
  msgid "Filter Options"
4773
  msgstr "Filtrovat možnosti"
4774
 
4775
- #: app/features/mec.php:630
4776
  msgid "Search Form"
4777
  msgstr "Vyhledávací formulář"
4778
 
4779
- #: app/features/mec.php:1065
4780
  msgid "Display content's images as Popup"
4781
  msgstr "Zobrazit obrázky obsahu jako vyskakovací okno"
4782
 
4783
- #: app/features/mec.php:1079 app/features/popup/shortcode.php:477
4784
  msgid "Single Event Display Method"
4785
  msgstr "Metoda zobrazení jedné události"
4786
 
4787
- #: app/features/mec.php:1086 app/features/popup/shortcode.php:489
4788
  #, fuzzy
4789
  #| msgid "Modal 1"
4790
  msgid "Modal Popup"
4791
  msgstr "Modal 1"
4792
 
4793
- #: app/features/mec.php:1087
4794
  #, fuzzy
4795
  #| msgid "Disabled"
4796
  msgid "Disable Link"
4797
  msgstr "Zakázaný"
4798
 
4799
- #: app/features/mec.php:1097
4800
  msgid "Descending Order"
4801
  msgstr ""
4802
 
4803
- #: app/features/mec.php:1113
4804
  #, fuzzy
4805
  #| msgid "Booking Options"
4806
  msgid "Booking Button / Icon"
4807
  msgstr "Možnosti rezervace"
4808
 
4809
- #: app/features/mec.php:1126
4810
  #, fuzzy
4811
  #| msgid "Organizers"
4812
  msgid "Display Organizers"
4813
  msgstr "Organizátoři"
4814
 
4815
- #: app/features/mec.php:1139
4816
  #, fuzzy
4817
  #| msgid "Custom Styles"
4818
  msgid "Display Custom Fields"
4819
  msgstr "Vlastní styly"
4820
 
4821
- #: app/features/mec.php:1152
4822
  #, fuzzy
4823
  #| msgid "Date and Time"
4824
  msgid "Detailed Time"
4825
  msgstr "Datum a čas"
4826
 
4827
- #: app/features/mec.php:1153
4828
  #, fuzzy
4829
  #| msgid "Multiple Day Events"
4830
  msgid "For Multiple Day Events"
4831
  msgstr "Vícedenní událost"
4832
 
4833
- #: app/features/mec.php:1310 app/features/mec.php:1486
4834
  msgid "Total Bookings"
4835
  msgstr "Celkový počet rezervací"
4836
 
4837
- #: app/features/mec.php:1326 app/features/mec/dashboard.php:65
4838
  msgid "Modern Events Calendar (Lite)"
4839
  msgstr "Modern Events Calendar (Lite)"
4840
 
4841
- #: app/features/mec.php:1392
4842
  #, fuzzy
4843
  #| msgid "Update %s"
4844
  msgid "News & Updates"
4845
  msgstr "Aktualizovat %s"
4846
 
4847
- #: app/features/mec.php:1405
4848
  msgid "Blog"
4849
  msgstr ""
4850
 
4851
- #: app/features/mec.php:1405
4852
  msgid "Help"
4853
  msgstr ""
4854
 
4855
- #: app/features/mec.php:1460
4856
  #, fuzzy, php-format
4857
  #| msgid "Total Sells (%s)"
4858
  msgid "Total Sales (%s)"
4859
  msgstr "Celkový prodej %s"
4860
 
4861
- #: app/features/mec.php:1495
4862
  msgid "This Month"
4863
  msgstr "Tento měsíc"
4864
 
4865
- #: app/features/mec.php:1501
4866
  msgid "Last Month"
4867
  msgstr "Minulý měsíc"
4868
 
4869
- #: app/features/mec.php:1507
4870
  msgid "This Year"
4871
  msgstr "Tento rok"
4872
 
4873
- #: app/features/mec.php:1513
4874
  msgid "Last Year"
4875
  msgstr "Minulý rok"
4876
 
4877
- #: app/features/mec.php:1533
4878
  msgid "Bar"
4879
  msgstr "Pruh"
4880
 
4881
- #: app/features/mec.php:1534
4882
  msgid "Line"
4883
  msgstr "Čára"
4884
 
4885
- #: app/features/mec.php:1536 app/skins/general_calendar/tpl.php:145
4886
  msgid "Filter"
4887
  msgstr "Filtr"
4888
 
4889
- #: app/features/mec.php:1560
4890
  #, fuzzy
4891
  #| msgid "Modern Events Calendar"
4892
  msgid "Print Calendar"
4893
  msgstr "Moderní kalendář událostí"
4894
 
4895
- #: app/features/mec.php:1575
4896
  #, fuzzy
4897
  #| msgid "Display Event Price"
4898
  msgid "Display Events"
4899
  msgstr "Zobrazit cenu události"
4900
 
4901
- #: app/features/mec.php:1621
4902
  #, fuzzy
4903
  #| msgid "Include Expired Events"
4904
  msgid "Include MEC Assets"
4905
  msgstr "Zahrnout uplynulé události"
4906
 
4907
- #: app/features/mec.php:1632
4908
  msgid "Include Modern Events Calendar Assets (CSS, JavaScript, etc files.)"
4909
  msgstr ""
4910
 
4911
  #: app/features/mec/addons.php:16 app/features/mec/addons.php:62
4912
- #: app/features/mec/dashboard.php:84 app/features/mec/go-pro.php:14
4913
  #: app/features/mec/report.php:21 app/features/mec/support-page.php:21
4914
  msgid "Version"
4915
  msgstr "Verze"
@@ -4936,9 +5562,9 @@ msgid "Search..."
4936
  msgstr "Vyhledávání ..."
4937
 
4938
  #: app/features/mec/booking.php:72 app/features/mec/booking.php:906
4939
- #: app/features/mec/booking.php:1098 app/features/mec/booking.php:1173
4940
- #: app/features/mec/booking.php:1183 app/features/mec/booking.php:1265
4941
- #: app/features/mec/booking.php:1279 app/features/mec/integrations.php:24
4942
  #: app/features/mec/integrations.php:400 app/features/mec/integrations.php:410
4943
  #: app/features/mec/integrations.php:468 app/features/mec/integrations.php:482
4944
  #: app/features/mec/messages.php:20 app/features/mec/messages.php:60
@@ -5397,7 +6023,7 @@ msgstr ""
5397
  "Po povolení a uložení nastavení byste měli stránku znovu načíst a zobrazit "
5398
  "novou nabídku na řídícím panelu > Rezervace"
5399
 
5400
- #: app/features/mec/booking.php:571 app/features/mec/booking.php:986
5401
  #: app/libraries/main.php:650
5402
  msgid "Taxes / Fees"
5403
  msgstr "Daně / poplatky"
@@ -5490,93 +6116,95 @@ msgid ""
5490
  "fields etc, you need to configure WooCommerce on your website."
5491
  msgstr ""
5492
 
5493
- #: app/features/mec/booking.php:980
 
 
 
 
 
 
5494
  msgid ""
5495
  "You cannot use following MEC features so you should use WooCommerc and its "
5496
  "addons if you need them."
5497
  msgstr ""
5498
 
5499
- #: app/features/mec/booking.php:982
5500
  #, fuzzy
5501
  #| msgid "Payment Gateways"
5502
  msgid "Payment gateways"
5503
  msgstr "Platební brány"
5504
 
5505
- #: app/features/mec/booking.php:983
5506
  #, fuzzy
5507
  #| msgid "Price per Date"
5508
  msgid "Price per dates of tickets"
5509
  msgstr "Cena za datum"
5510
 
5511
- #: app/features/mec/booking.php:985
5512
  #, fuzzy
5513
  #| msgid "Ticket Variations / Options"
5514
  msgid "Ticket variations"
5515
  msgstr "Varianty vstupenky / možnosti"
5516
 
5517
- #: app/features/mec/booking.php:987
5518
  #, fuzzy
5519
  #| msgid "Discount"
5520
  msgid "Discount Per Roles"
5521
  msgstr "Sleva"
5522
 
5523
- #: app/features/mec/booking.php:991
5524
  msgid "Automatically complete WooCommerce orders"
5525
  msgstr ""
5526
 
5527
- #: app/features/mec/booking.php:999
5528
  #, fuzzy
5529
  #| msgid "WooCommerce gateways"
5530
  msgid "Auto WooCommerce orders"
5531
  msgstr "Brána WooCommerce"
5532
 
5533
- #: app/features/mec/booking.php:1000
5534
- msgid "It applies only to the orders that are related to MEC."
5535
- msgstr ""
5536
-
5537
- #: app/features/mec/booking.php:1008 app/features/mec/booking.php:1146
5538
  msgid "After Add to Cart"
5539
  msgstr ""
5540
 
5541
- #: app/features/mec/booking.php:1011 app/features/mec/booking.php:1149
5542
  #, fuzzy
5543
  #| msgid "Get Directions"
5544
  msgid "Redirect to Cart"
5545
  msgstr "Získat směr"
5546
 
5547
- #: app/features/mec/booking.php:1012 app/features/mec/booking.php:1150
5548
  #, fuzzy
5549
  #| msgid "Get Directions"
5550
  msgid "Redirect to Checkout"
5551
  msgstr "Získat směr"
5552
 
5553
- #: app/features/mec/booking.php:1013 app/features/mec/booking.php:1151
5554
  #, fuzzy
5555
  #| msgid "View Detail Button"
5556
  msgid "Optional View Cart Button"
5557
  msgstr "Tlačítko Zobrazit detail"
5558
 
5559
- #: app/features/mec/booking.php:1014 app/features/mec/booking.php:1152
5560
  msgid "Optional Checkout Button"
5561
  msgstr ""
5562
 
5563
- #: app/features/mec/booking.php:1019
5564
  #, fuzzy
5565
  #| msgid "Booking Form"
5566
  msgid "MEC Booking Form"
5567
  msgstr "Rezervační formulář"
5568
 
5569
- #: app/features/mec/booking.php:1028
5570
  msgid ""
5571
  "If enabled then users should fill the booking form in MEC and then they will "
5572
  "be redirected to checkout."
5573
  msgstr ""
5574
 
5575
- #: app/features/mec/booking.php:1054
5576
  msgid "Enable Organizer Payment Module"
5577
  msgstr "Povolit platební modul organizátora"
5578
 
5579
- #: app/features/mec/booking.php:1059
5580
  msgid ""
5581
  "By enabling this module, organizers are able to insert their own payment "
5582
  "credentials for enabled gateways per event and receive the payments directly!"
@@ -5584,17 +6212,17 @@ msgstr ""
5584
  "Po aktivaci tohoto modulu mohou organizátoři vkládat své vlastní platební "
5585
  "údaje pro povolené brány pro události a přijímat platby přímo!"
5586
 
5587
- #: app/features/mec/booking.php:1069
5588
  msgid "Disable / Enable payment gateways per event"
5589
  msgstr ""
5590
 
5591
- #: app/features/mec/booking.php:1073
5592
  #, fuzzy
5593
  #| msgid "Payment Gateways"
5594
  msgid "Payment Gateways Per Event"
5595
  msgstr "Platební brány"
5596
 
5597
- #: app/features/mec/booking.php:1074
5598
  #, fuzzy
5599
  #| msgid ""
5600
  #| "By enabling this module, organizers are able to insert their own payment "
@@ -5607,89 +6235,89 @@ msgstr ""
5607
  "Po aktivaci tohoto modulu mohou organizátoři vkládat své vlastní platební "
5608
  "údaje pro povolené brány pro události a přijímat platby přímo!"
5609
 
5610
- #: app/features/mec/booking.php:1084
5611
  msgid "Automatically refund the payment"
5612
  msgstr ""
5613
 
5614
- #: app/features/mec/booking.php:1088
5615
  msgid "Auto Refund"
5616
  msgstr ""
5617
 
5618
- #: app/features/mec/booking.php:1089
5619
  msgid ""
5620
  "Automatically refund the payment when a booking paid by applicable gateways "
5621
  "(Stripe) got canceled."
5622
  msgstr ""
5623
 
5624
- #: app/features/mec/booking.php:1108
5625
  msgid "Use MEC Cart System"
5626
  msgstr ""
5627
 
5628
- #: app/features/mec/booking.php:1110
5629
  msgid ""
5630
  "If you don't want to use WooCommerce for any reason you can use MEC Cart for "
5631
  "adding a simple cart and checkout system to your website."
5632
  msgstr ""
5633
 
5634
- #: app/features/mec/booking.php:1112
5635
  msgid "You cannot use following MEC features while using MEC Cart."
5636
  msgstr ""
5637
 
5638
- #: app/features/mec/booking.php:1114
5639
  #, fuzzy
5640
  #| msgid "Set Up a Payment Gateway"
5641
  msgid "WooCommerce as Payment Gateway"
5642
  msgstr "Nastavení platební brány"
5643
 
5644
- #: app/features/mec/booking.php:1115
5645
  #, fuzzy
5646
  #| msgid "Next Occurrence of Other Events"
5647
  msgid "Currency Per Event"
5648
  msgstr "Další výskyt dalších událostí"
5649
 
5650
- #: app/features/mec/booking.php:1116
5651
  #, fuzzy
5652
  #| msgid "Payment Gateways"
5653
  msgid "Disable Gateways Per Event"
5654
  msgstr "Platební brány"
5655
 
5656
- #: app/features/mec/booking.php:1117
5657
  #, fuzzy
5658
  #| msgid "Set Up WooCommerce Gateway"
5659
  msgid "Stripe Connect Gateway"
5660
  msgstr "Nastavit bránu WooCommerce"
5661
 
5662
- #: app/features/mec/booking.php:1118
5663
  #, fuzzy
5664
  #| msgid "Set Up WooCommerce Gateway"
5665
  msgid "Pay By WooCommerce Gateway"
5666
  msgstr "Nastavit bránu WooCommerce"
5667
 
5668
- #: app/features/mec/booking.php:1122
5669
  #, fuzzy
5670
  #| msgid "Start Date"
5671
  msgid "Cart Page"
5672
  msgstr "Počátečná den"
5673
 
5674
- #: app/features/mec/booking.php:1130 app/features/mec/booking.php:1142
5675
  #: app/features/mec/settings.php:722 app/features/mec/settings.php:734
5676
  #, php-format
5677
  msgid "Put %s shortcode into the page."
5678
  msgstr "Vložte %s na stránku zkrácené kódy."
5679
 
5680
- #: app/features/mec/booking.php:1134
5681
  #, fuzzy
5682
  #| msgid "Checkout"
5683
  msgid "Checkout Page"
5684
  msgstr "Překontrolovat"
5685
 
5686
- #: app/features/mec/booking.php:1160
5687
  #, fuzzy
5688
  #| msgid "Enable Invoice"
5689
  msgid "Enable Cart Invoice"
5690
  msgstr "Povolit fakturu"
5691
 
5692
- #: app/features/mec/booking.php:1243 app/features/mec/integrations.php:446
5693
  #: app/features/mec/messages.php:90 app/features/mec/modules.php:403
5694
  #: app/features/mec/notifications.php:1919 app/features/mec/settings.php:1596
5695
  #: app/features/mec/single.php:592 app/features/mec/styles.php:62
@@ -5697,7 +6325,7 @@ msgstr "Povolit fakturu"
5697
  msgid "Saved"
5698
  msgstr "Uloženo"
5699
 
5700
- #: app/features/mec/booking.php:1244 app/features/mec/integrations.php:447
5701
  #: app/features/mec/messages.php:91 app/features/mec/modules.php:404
5702
  #: app/features/mec/notifications.php:1920 app/features/mec/settings.php:1597
5703
  #: app/features/mec/single.php:593 app/features/mec/styles.php:63
@@ -5705,32 +6333,28 @@ msgstr "Uloženo"
5705
  msgid "Settings Saved!"
5706
  msgstr "Nastavení uložena!"
5707
 
5708
- #: app/features/mec/booking.php:1270 app/features/mec/integrations.php:473
5709
  #: app/features/mec/modules.php:430 app/features/mec/notifications.php:1947
5710
  #: app/features/mec/settings.php:1623 app/features/mec/single.php:619
5711
  msgid "Please Refresh Page"
5712
  msgstr "Prosím obnovte stránku"
5713
 
5714
- #: app/features/mec/dashboard.php:62
5715
  #, php-format
5716
  msgid "Welcome %s"
5717
  msgstr "Vítejte %s"
5718
 
5719
- #: app/features/mec/dashboard.php:65
5720
  #, php-format
5721
  msgid "%s - Most Powerful & Easy to Use Events Management System"
5722
  msgstr "%s - Nejvýkonnější a snadno použitelný systém pro správu událostí"
5723
 
5724
- #: app/features/mec/dashboard.php:67 app/libraries/factory.php:215
5725
  msgctxt "plugin rate"
5726
  msgid "Rate the plugin ★★★★★"
5727
  msgstr "Ohodnoťe doplněk ★★★★★"
5728
 
5729
- #: app/features/mec/dashboard.php:72
5730
- msgid "Update"
5731
- msgstr "Aktualizovat"
5732
-
5733
- #: app/features/mec/dashboard.php:99 app/features/mec/go-pro.php:66
5734
  #, php-format
5735
  msgid ""
5736
  "You're using %s version of Modern Events Calendar. To use advanced booking "
@@ -5741,16 +6365,16 @@ msgstr ""
5741
  "pokročilý rezervační systém, moderní vzhledy jako Agenda, Rozvrh, Roční "
5742
  "pohled, Dostupná místa atd., Měli byste upgradovat na verzi Pro."
5743
 
5744
- #: app/features/mec/dashboard.php:99 app/features/mec/go-pro.php:66
5745
  msgid "lite"
5746
  msgstr " omezenou"
5747
 
5748
- #: app/features/mec/dashboard.php:102 app/features/mec/go-pro.php:69
5749
  #: app/features/mec/support.php:126
5750
  msgid "GO PREMIUM"
5751
  msgstr "PŘEJÍT NA PREMIUM"
5752
 
5753
- #: app/features/mec/dashboard.php:105 app/features/mec/go-pro.php:72
5754
  #, php-format
5755
  msgid ""
5756
  "Easily get a discount coupon by rating us on %s or following and reposting "
@@ -5759,19 +6383,19 @@ msgstr ""
5759
  "Jednoduše získejte slevový kupón tím, že nás ohodnocíte na% s nebo poté a "
5760
  "uložíte nás na sociální média. Stačí poslat screenshot do % s a obdržíte % s"
5761
 
5762
- #: app/features/mec/dashboard.php:105 app/features/mec/go-pro.php:72
5763
  msgid "WordPress"
5764
  msgstr "WordPress"
5765
 
5766
- #: app/features/mec/dashboard.php:105 app/features/mec/go-pro.php:72
5767
  msgid "Copouns!"
5768
  msgstr "Kupóny!"
5769
 
5770
- #: app/features/mec/dashboard.php:135
5771
  msgid "Getting started with Modern Events Calendar"
5772
  msgstr "Začínáme s Modern Events Calendar"
5773
 
5774
- #: app/features/mec/dashboard.php:136
5775
  msgid ""
5776
  "In this short video, you can learn how to make an event and put a calendar "
5777
  "on your website. Please watch this 2 minutes video to the end."
@@ -5779,21 +6403,21 @@ msgstr ""
5779
  "V tomto krátkém videu se dozvíte, jak vytvořit událost a umístit kalendář na "
5780
  "svoje stránky. Sledujte prosím toto 2minutové video až do konce."
5781
 
5782
- #: app/features/mec/dashboard.php:152 app/features/mec/dashboard.php:176
5783
  #, fuzzy
5784
  #| msgid "MEC Activation"
5785
  msgid "License Activation"
5786
  msgstr "Aktivace MEC"
5787
 
5788
- #: app/features/mec/dashboard.php:158 app/features/mec/dashboard.php:213
5789
  msgid "Activate Addons"
5790
  msgstr "Aktivovat doplňky"
5791
 
5792
- #: app/features/mec/dashboard.php:166 app/features/mec/dashboard.php:222
5793
  msgid "You cannot access this section."
5794
  msgstr "Nemáte přístup do této části."
5795
 
5796
- #: app/features/mec/dashboard.php:182
5797
  msgid ""
5798
  "In order to use all plugin features and options, please enter your purchase "
5799
  "code."
@@ -5801,11 +6425,11 @@ msgstr ""
5801
  "Chcete-li využívat všechny funkce a možnosti doplňku, zadejte prosím "
5802
  "zakoupený kód."
5803
 
5804
- #: app/features/mec/dashboard.php:290
5805
  msgid "Popular Gateways"
5806
  msgstr "Oblíbené platební brány"
5807
 
5808
- #: app/features/mec/dashboard.php:348
5809
  msgid "Change Log"
5810
  msgstr "Změna logu"
5811
 
@@ -6179,12 +6803,6 @@ msgstr "Minimální"
6179
  msgid "Modern"
6180
  msgstr "Moderní"
6181
 
6182
- #: app/features/mec/meta_boxes/display_options.php:51
6183
- #: app/features/mec/settings.php:404 app/features/mec/settings.php:481
6184
- #: app/features/popup/settings.php:131 app/features/popup/shortcode.php:85
6185
- msgid "Standard"
6186
- msgstr "Standardní"
6187
-
6188
  #: app/features/mec/meta_boxes/display_options.php:52
6189
  #: app/features/mec/settings.php:405 app/features/mec/settings.php:482
6190
  #: app/features/popup/settings.php:132 app/features/popup/shortcode.php:90
@@ -7357,7 +7975,7 @@ msgstr ""
7357
  #: app/features/mec/single.php:526 app/features/popup/settings.php:233
7358
  #: app/features/popup/settings.php:272 app/features/search.php:109
7359
  #: app/features/speakers.php:60 app/features/speakers.php:286
7360
- #: app/libraries/main.php:7409 app/libraries/main.php:7470
7361
  #: app/libraries/search.php:334 app/libraries/skins.php:1203
7362
  #: app/modules/speakers/details.php:18
7363
  msgid "Speaker"
@@ -8687,8 +9305,8 @@ msgstr ""
8687
  msgid "only once per hour"
8688
  msgstr "pouze jednou denně"
8689
 
8690
- #: app/features/mec/notifications.php:1314 app/libraries/main.php:8654
8691
- #: app/libraries/main.php:8674
8692
  #, fuzzy
8693
  #| msgid "hours"
8694
  msgid "Hours"
@@ -9025,8 +9643,8 @@ msgid "You can enable/disable Schema scripts"
9025
  msgstr "Můžete povolit nebo zakázat skripty schématu"
9026
 
9027
  #: app/features/mec/settings.php:137 app/features/mec/settings.php:148
9028
- #: app/features/popup/settings.php:41 app/libraries/main.php:7413
9029
- #: app/libraries/main.php:7474
9030
  msgid "Weekdays"
9031
  msgstr "Pracovní dny"
9032
 
@@ -9455,10 +10073,6 @@ msgstr "Povolit ve formuláři „Odesílání událostí z frontendu“"
9455
  msgid "Site Key"
9456
  msgstr "Klíč webu"
9457
 
9458
- #: app/features/mec/settings.php:685
9459
- msgid "Secret Key"
9460
- msgstr "Tajný klíč"
9461
-
9462
  #: app/features/mec/settings.php:697 app/features/mec/settings.php:705
9463
  msgid "Time Format"
9464
  msgstr "Formát času"
@@ -9698,8 +10312,8 @@ msgstr "Ve výchozím nastavení zaškrtnuto"
9698
  msgid "Required Fields"
9699
  msgstr "Požadovaná pole"
9700
 
9701
- #: app/features/mec/settings.php:1164 app/libraries/main.php:7445
9702
- #: app/libraries/main.php:7492
9703
  msgid "More Info Link"
9704
  msgstr "Odkaz na více informací"
9705
 
@@ -11069,8 +11683,8 @@ msgstr "např. info@itreseni.cz"
11069
  msgid "eg. https://webnus.net"
11070
  msgstr "např. https://webnus.net"
11071
 
11072
- #: app/features/organizers.php:329 app/libraries/main.php:7448
11073
- #: app/libraries/main.php:7495 app/skins/single.php:1439
11074
  msgid "Other Organizers"
11075
  msgstr "Další organizátoři"
11076
 
@@ -11300,7 +11914,7 @@ msgstr ""
11300
  msgid "MEC Pro"
11301
  msgstr "MEC - podpora"
11302
 
11303
- #: app/features/profile/profile.php:53 app/features/profile/profile.php:189
11304
  msgid "#"
11305
  msgstr "#"
11306
 
@@ -11312,16 +11926,16 @@ msgstr "Faktura"
11312
  msgid "Cancel"
11313
  msgstr "Zrušit"
11314
 
11315
- #: app/features/profile/profile.php:122
11316
  msgid "N/A"
11317
  msgstr ""
11318
 
11319
- #: app/features/profile/profile.php:150
11320
  #, php-format
11321
  msgid "<i class=\"mec-sl-eye\"></i> %s"
11322
  msgstr "<i class=\"mec-sl-eye\"></i> %s"
11323
 
11324
- #: app/features/profile/profile.php:250
11325
  msgid "No bookings found!"
11326
  msgstr "Nebyly nalezeny žádné rezervace!"
11327
 
@@ -11455,12 +12069,7 @@ msgstr ""
11455
  msgid "%s ticket is sold out!"
11456
  msgstr ""
11457
 
11458
- #: app/features/wc.php:212 app/features/wc.php:238
11459
- #, php-format
11460
- msgid "Only %s slots remained for %s ticket so you cannot book %s ones."
11461
- msgstr ""
11462
-
11463
- #: app/features/wc.php:246 app/libraries/main.php:7432
11464
  #, php-format
11465
  msgid "Maximum allowed number of tickets that you can book is %s."
11466
  msgstr ""
@@ -11478,11 +12087,6 @@ msgstr "%s Cena"
11478
  msgid "Discount"
11479
  msgstr "Sleva"
11480
 
11481
- #: app/libraries/book.php:1104 app/modules/booking/default.php:665
11482
- #: app/modules/booking/default.php:778
11483
- msgid "Download Invoice"
11484
- msgstr "Stáhnout fakturu"
11485
-
11486
  #: app/libraries/cart.php:69 app/libraries/wc.php:107
11487
  #, fuzzy
11488
  #| msgid "View Event"
@@ -11498,83 +12102,78 @@ msgstr[0] ""
11498
  msgstr[1] ""
11499
  msgstr[2] ""
11500
 
11501
- #: app/libraries/cart.php:71 app/libraries/wc.php:109
11502
- #: app/modules/booking/steps/checkout.php:55
11503
- msgid "Checkout"
11504
- msgstr "Překontrolovat"
11505
-
11506
- #: app/libraries/factory.php:175
11507
  msgid "M.E. Calendar"
11508
  msgstr "M.E. Kalendář"
11509
 
11510
- #: app/libraries/factory.php:214
11511
  msgctxt "plugin link"
11512
  msgid "Upgrade to Pro Version"
11513
  msgstr "Upgrade na verzi PRO"
11514
 
11515
- #: app/libraries/factory.php:232
11516
  msgctxt "plugin link"
11517
  msgid "Settings"
11518
  msgstr "Nastavení"
11519
 
11520
- #: app/libraries/factory.php:237
11521
  msgctxt "plugin link"
11522
  msgid "Upgrade"
11523
  msgstr "Upgrade"
11524
 
11525
- #: app/libraries/factory.php:385
11526
  msgid "day"
11527
  msgstr "den"
11528
 
11529
- #: app/libraries/factory.php:386 app/modules/countdown/details.php:190
11530
  #: app/skins/available_spot/tpl.php:143 app/skins/countdown/tpl.php:125
11531
  #: app/skins/countdown/tpl.php:171 app/skins/countdown/tpl.php:222
11532
  msgid "days"
11533
  msgstr "dny"
11534
 
11535
- #: app/libraries/factory.php:387
11536
  msgid "hour"
11537
  msgstr "hodina"
11538
 
11539
- #: app/libraries/factory.php:388 app/modules/countdown/details.php:197
11540
  #: app/skins/available_spot/tpl.php:147 app/skins/countdown/tpl.php:131
11541
  #: app/skins/countdown/tpl.php:177 app/skins/countdown/tpl.php:228
11542
  msgid "hours"
11543
  msgstr "hodiny"
11544
 
11545
- #: app/libraries/factory.php:389
11546
  msgid "minute"
11547
  msgstr "minuta"
11548
 
11549
- #: app/libraries/factory.php:390 app/modules/countdown/details.php:204
11550
  #: app/skins/available_spot/tpl.php:151 app/skins/countdown/tpl.php:137
11551
  #: app/skins/countdown/tpl.php:183 app/skins/countdown/tpl.php:234
11552
  msgid "minutes"
11553
  msgstr "minuty"
11554
 
11555
- #: app/libraries/factory.php:391
11556
  msgid "second"
11557
  msgstr "vteřina"
11558
 
11559
- #: app/libraries/factory.php:392 app/modules/countdown/details.php:211
11560
  #: app/skins/available_spot/tpl.php:155 app/skins/countdown/tpl.php:143
11561
  #: app/skins/countdown/tpl.php:189 app/skins/countdown/tpl.php:240
11562
  msgid "seconds"
11563
  msgstr "vteřiny"
11564
 
11565
- #: app/libraries/factory.php:468
11566
  msgid "MEC Single Sidebar"
11567
  msgstr "MEC Postranní panel"
11568
 
11569
- #: app/libraries/factory.php:469
11570
  msgid "Custom sidebar for single and modal page of MEC."
11571
  msgstr "Vlastní postranní panel pro jednu a modální stránku MEC."
11572
 
11573
- #: app/libraries/factory.php:1151
11574
  msgid "Notice:"
11575
  msgstr ""
11576
 
11577
- #: app/libraries/factory.php:1152
11578
  msgid "This update includes only bug fixes."
11579
  msgstr ""
11580
 
@@ -11681,38 +12280,38 @@ msgstr "Zobrazení rozvrhu"
11681
  msgid "General Calendar"
11682
  msgstr "Kalendář Google"
11683
 
11684
- #: app/libraries/main.php:439 app/libraries/main.php:7415
11685
- #: app/libraries/main.php:7476
11686
  msgid "SU"
11687
  msgstr "NE"
11688
 
11689
- #: app/libraries/main.php:440 app/libraries/main.php:7416
11690
- #: app/libraries/main.php:7477
11691
  msgid "MO"
11692
  msgstr "PO"
11693
 
11694
- #: app/libraries/main.php:441 app/libraries/main.php:7417
11695
- #: app/libraries/main.php:7478
11696
  msgid "TU"
11697
  msgstr "ÚT"
11698
 
11699
- #: app/libraries/main.php:442 app/libraries/main.php:7418
11700
- #: app/libraries/main.php:7479
11701
  msgid "WE"
11702
  msgstr "ST"
11703
 
11704
- #: app/libraries/main.php:443 app/libraries/main.php:7419
11705
- #: app/libraries/main.php:7480
11706
  msgid "TH"
11707
  msgstr "ČT"
11708
 
11709
- #: app/libraries/main.php:444 app/libraries/main.php:7420
11710
- #: app/libraries/main.php:7481
11711
  msgid "FR"
11712
  msgstr "PÁ"
11713
 
11714
- #: app/libraries/main.php:445 app/libraries/main.php:7421
11715
- #: app/libraries/main.php:7482
11716
  msgid "SA"
11717
  msgstr "SO"
11718
 
@@ -12049,210 +12648,194 @@ msgstr "Požadavek není platný."
12049
  msgid "iCal export stopped!"
12050
  msgstr "iCal export byl zastaven!"
12051
 
12052
- #: app/libraries/main.php:4155
12053
  #, fuzzy
12054
  #| msgid "Block Editor"
12055
  msgid "HTML Editor"
12056
  msgstr "Editor bloků"
12057
 
12058
- #: app/libraries/main.php:4313
12059
  msgid "Consider the first item as a placeholder"
12060
  msgstr ""
12061
 
12062
- #: app/libraries/main.php:4422
12063
- msgid "Free"
12064
- msgstr "Zdarma"
12065
-
12066
- #: app/libraries/main.php:5202 app/libraries/main.php:7813
12067
  msgid "M.E. Calender"
12068
  msgstr "M.E. Kalendář"
12069
 
12070
- #: app/libraries/main.php:5381
12071
  #, php-format
12072
  msgid "Copy of %s"
12073
  msgstr "Kopie %s"
12074
 
12075
- #: app/libraries/main.php:6352
12076
  msgid "Booked an event."
12077
  msgstr "Událost byla rezervována."
12078
 
12079
- #: app/libraries/main.php:6393
12080
  #, php-format
12081
  msgid "%s booked %s event."
12082
  msgstr "%s zarezervoval %s událost."
12083
 
12084
- #: app/libraries/main.php:7398 app/libraries/main.php:7459
12085
  msgid "Taxonomies"
12086
  msgstr "Taxonomie"
12087
 
12088
  # Mrknout na kontext
12089
- #: app/libraries/main.php:7400 app/libraries/main.php:7461
12090
  msgid "Category Plural Label"
12091
  msgstr "Štítek množné kategorie"
12092
 
12093
  # Mrknout na kontext
12094
- #: app/libraries/main.php:7401 app/libraries/main.php:7462
12095
  msgid "Category Singular Label"
12096
  msgstr "Štítek jednotné kategorie"
12097
 
12098
- #: app/libraries/main.php:7402 app/libraries/main.php:7463
12099
  msgid "Label Plural Label"
12100
  msgstr "Štítek množného štítku"
12101
 
12102
- #: app/libraries/main.php:7403 app/libraries/main.php:7464
12103
  msgid "Label Singular Label"
12104
  msgstr "Štítek jednotného štítku"
12105
 
12106
- #: app/libraries/main.php:7403 app/libraries/main.php:7464
12107
  msgid "label"
12108
  msgstr "štítek"
12109
 
12110
- #: app/libraries/main.php:7404 app/libraries/main.php:7465
12111
  msgid "Location Plural Label"
12112
  msgstr "Štítek množného umístění"
12113
 
12114
- #: app/libraries/main.php:7405 app/libraries/main.php:7466
12115
  msgid "Location Singular Label"
12116
  msgstr "Štítek jednotného umístění"
12117
 
12118
- #: app/libraries/main.php:7406 app/libraries/main.php:7467
12119
  msgid "Organizer Plural Label"
12120
  msgstr "Štítek množného organizátora"
12121
 
12122
- #: app/libraries/main.php:7407 app/libraries/main.php:7468
12123
  msgid "Organizer Singular Label"
12124
  msgstr "Štítek jednotného organizátora"
12125
 
12126
- #: app/libraries/main.php:7408 app/libraries/main.php:7469
12127
  msgid "Speaker Plural Label"
12128
  msgstr "Štítek množného řečníka"
12129
 
12130
- #: app/libraries/main.php:7409 app/libraries/main.php:7470
12131
  msgid "Speaker Singular Label"
12132
  msgstr "Štítek jednotného řečníka"
12133
 
12134
- #: app/libraries/main.php:7415 app/libraries/main.php:7476
12135
  msgid "Sunday abbreviation"
12136
  msgstr "Neděle zkratka"
12137
 
12138
- #: app/libraries/main.php:7416 app/libraries/main.php:7477
12139
  msgid "Monday abbreviation"
12140
  msgstr "Pondělí zkratka"
12141
 
12142
- #: app/libraries/main.php:7417 app/libraries/main.php:7478
12143
  msgid "Tuesday abbreviation"
12144
  msgstr "Úterý zkratka"
12145
 
12146
- #: app/libraries/main.php:7418 app/libraries/main.php:7479
12147
  msgid "Wednesday abbreviation"
12148
  msgstr "Středa zkratka"
12149
 
12150
- #: app/libraries/main.php:7419 app/libraries/main.php:7480
12151
  msgid "Thursday abbreviation"
12152
  msgstr "Čtvrtek zkratka"
12153
 
12154
- #: app/libraries/main.php:7420 app/libraries/main.php:7481
12155
  msgid "Friday abbreviation"
12156
  msgstr "Pátek zkratka"
12157
 
12158
- #: app/libraries/main.php:7421 app/libraries/main.php:7482
12159
  msgid "Saturday abbreviation"
12160
  msgstr "Sobota zkratka"
12161
 
12162
- #: app/libraries/main.php:7427
12163
  #, fuzzy
12164
  #| msgid "Ticket (Singular)"
12165
  msgid "Booking (Singular)"
12166
  msgstr "Vstupenka (Jednotné)"
12167
 
12168
- #: app/libraries/main.php:7428
12169
  #, fuzzy
12170
  #| msgid "Tickets (Plural)"
12171
  msgid "Bookings (Plural)"
12172
  msgstr "Vstupenky (Množné)"
12173
 
12174
- #: app/libraries/main.php:7429
12175
  msgid "Booking Success Message"
12176
  msgstr "Zpráva o úspěchu rezervace"
12177
 
12178
- #: app/libraries/main.php:7429
12179
- #, fuzzy
12180
- #| msgid ""
12181
- #| "Thanks for your booking. Your tickets booked, booking verification might "
12182
- #| "be needed, please check your email."
12183
- msgid ""
12184
- "Thank you for booking. Your tickets are booked, booking verification might "
12185
- "be needed, please check your email."
12186
- msgstr ""
12187
- "Děkujeme za vaši rezervaci. Vaše vstupenky jsou rezervovány, může být nutné "
12188
- "ověřit rezervaci. Zkontrolujte prosím svůj e-mail."
12189
-
12190
- #: app/libraries/main.php:7430
12191
  #, fuzzy
12192
  #| msgid "Booking Success Message"
12193
  msgid "Booking Restriction Message 1"
12194
  msgstr "Zpráva o úspěchu rezervace"
12195
 
12196
- #: app/libraries/main.php:7430
12197
  #, php-format
12198
  msgid ""
12199
  "You selected %s tickets to book but maximum number of tikets per user is %s "
12200
  "tickets."
12201
  msgstr ""
12202
 
12203
- #: app/libraries/main.php:7431
12204
  #, fuzzy
12205
  #| msgid "Booking Success Message"
12206
  msgid "Booking Restriction Message 2"
12207
  msgstr "Zpráva o úspěchu rezervace"
12208
 
12209
- #: app/libraries/main.php:7431
12210
  #, php-format
12211
  msgid ""
12212
  "You booked %s tickets till now but maximum number of tickets per user is %s "
12213
  "tickets."
12214
  msgstr ""
12215
 
12216
- #: app/libraries/main.php:7432
12217
  #, fuzzy
12218
  #| msgid "Booking Success Message"
12219
  msgid "Booking IP Restriction Message"
12220
  msgstr "Zpráva o úspěchu rezervace"
12221
 
12222
- #: app/libraries/main.php:7433
12223
  #, fuzzy
12224
  #| msgid "Booking Options"
12225
  msgid "Booking Button"
12226
  msgstr "Možnosti rezervace"
12227
 
12228
- #: app/libraries/main.php:7433
12229
  #, fuzzy
12230
  #| msgid "Booking Form"
12231
  msgid "Book Now"
12232
  msgstr "Rezervační formulář"
12233
 
12234
- #: app/libraries/main.php:7434
12235
  msgid "Ticket (Singular)"
12236
  msgstr "Vstupenka (Jednotné)"
12237
 
12238
- #: app/libraries/main.php:7435
12239
  msgid "Tickets (Plural)"
12240
  msgstr "Vstupenky (Množné)"
12241
 
12242
- #: app/libraries/main.php:7439 app/libraries/main.php:7486
12243
  msgid "Others"
12244
  msgstr "Další"
12245
 
12246
- #: app/libraries/main.php:7441 app/libraries/main.php:7488
12247
  #: app/widgets/single.php:129
12248
  msgid "Register Button"
12249
  msgstr "Registrační tlačítko"
12250
 
12251
- #: app/libraries/main.php:7442 app/libraries/main.php:7489
12252
  msgid "View Detail Button"
12253
  msgstr "Tlačítko Zobrazit detail"
12254
 
12255
- #: app/libraries/main.php:7442 app/libraries/main.php:7489
12256
  #: app/skins/carousel/render.php:105 app/skins/carousel/render.php:145
12257
  #: app/skins/grid/render.php:94 app/skins/grid/render.php:153
12258
  #: app/skins/grid/render.php:214 app/skins/grid/render.php:237
@@ -12264,148 +12847,148 @@ msgstr "Tlačítko Zobrazit detail"
12264
  msgid "View Detail"
12265
  msgstr "Zobrazit detail"
12266
 
12267
- #: app/libraries/main.php:7443 app/libraries/main.php:7490
12268
  msgid "Event Detail Button"
12269
  msgstr "Tlačítko Detail události"
12270
 
12271
- #: app/libraries/main.php:7443 app/libraries/main.php:7490
12272
  msgid "Event Detail"
12273
  msgstr "Zobrazit událost"
12274
 
12275
- #: app/libraries/main.php:7605
12276
  msgid "EventON"
12277
  msgstr "EventON"
12278
 
12279
- #: app/libraries/main.php:7606
12280
  msgid "The Events Calendar"
12281
  msgstr "The Events Calendar"
12282
 
12283
- #: app/libraries/main.php:7607
12284
  msgid "Events Schedule WP Plugin"
12285
  msgstr "Events Schedule WP Plugin"
12286
 
12287
- #: app/libraries/main.php:7608
12288
  msgid "Calendarize It"
12289
  msgstr "Calendarize It"
12290
 
12291
- #: app/libraries/main.php:7609
12292
  #, fuzzy
12293
  #| msgid "Event Speakers"
12294
  msgid "Event Espresso"
12295
  msgstr "Řečník události"
12296
 
12297
- #: app/libraries/main.php:7610
12298
  #, fuzzy
12299
  #| msgid "Event Repeating (Recurring events)"
12300
  msgid "Events Manager (Recurring)"
12301
  msgstr "Opakování události (opakující se události)"
12302
 
12303
- #: app/libraries/main.php:7611
12304
  #, fuzzy
12305
  #| msgid "Modern Events Calendar (Lite)"
12306
  msgid "Events Manager (Single)"
12307
  msgstr "Modern Events Calendar (Lite)"
12308
 
12309
- #: app/libraries/main.php:7612
12310
  #, fuzzy
12311
  #| msgid "Modern Events Calendar (Lite)"
12312
  msgid "WP Event Manager"
12313
  msgstr "Modern Events Calendar (Lite)"
12314
 
12315
- #: app/libraries/main.php:7843
12316
  #, fuzzy
12317
  #| msgid "Sunday"
12318
  msgid "Sun"
12319
  msgstr "Neděle"
12320
 
12321
- #: app/libraries/main.php:7843
12322
  #, fuzzy
12323
  #| msgid "Monday"
12324
  msgid "Mon"
12325
  msgstr "Pondělí"
12326
 
12327
- #: app/libraries/main.php:7843
12328
  #, fuzzy
12329
  #| msgid "Tel"
12330
  msgid "Tue"
12331
  msgstr "Tel"
12332
 
12333
- #: app/libraries/main.php:7843
12334
  msgid "Wed"
12335
  msgstr ""
12336
 
12337
- #: app/libraries/main.php:7843
12338
  msgid "Thu"
12339
  msgstr ""
12340
 
12341
- #: app/libraries/main.php:7843
12342
  #, fuzzy
12343
  #| msgid "Friday"
12344
  msgid "Fri"
12345
  msgstr "Pátek"
12346
 
12347
- #: app/libraries/main.php:7843
12348
  #, fuzzy
12349
  #| msgid "Start"
12350
  msgid "Sat"
12351
  msgstr "Začátek"
12352
 
12353
- #: app/libraries/main.php:8049 app/libraries/render.php:82
12354
  #: app/libraries/render.php:467
12355
  msgid "Skin controller does not exist."
12356
  msgstr "Ovladač vzhledu neexistuje."
12357
 
12358
- #: app/libraries/main.php:8289
12359
  msgid "Sold Out"
12360
  msgstr "Vyprodáno"
12361
 
12362
- #: app/libraries/main.php:8320
12363
  #, fuzzy
12364
  #| msgid "Ticket"
12365
  msgid "Last Few Tickets"
12366
  msgstr "Vstupenka"
12367
 
12368
- #: app/libraries/main.php:8592
12369
  #, fuzzy
12370
  #| msgid "Upcoming Events"
12371
  msgid "Ongoing"
12372
  msgstr "Nadcházející události"
12373
 
12374
- #: app/libraries/main.php:8594
12375
  #, fuzzy
12376
  #| msgid "Expired Events"
12377
  msgid "Expired"
12378
  msgstr "Události vypršely"
12379
 
12380
- #: app/libraries/main.php:8660 app/libraries/main.php:8680
12381
  #, fuzzy
12382
  #| msgid "minutes"
12383
  msgid "Minutes"
12384
  msgstr "minuty"
12385
 
12386
- #: app/libraries/main.php:8685
12387
  msgid "AM / PM"
12388
  msgstr ""
12389
 
12390
- #: app/libraries/main.php:8686
12391
  msgid "AM"
12392
  msgstr "dop."
12393
 
12394
- #: app/libraries/main.php:8687
12395
  msgid "PM"
12396
  msgstr "odp."
12397
 
12398
- #: app/libraries/main.php:8695
12399
  msgid "Ongoing..."
12400
  msgstr ""
12401
 
12402
- #: app/libraries/main.php:8696 app/skins/single.php:229
12403
  #, fuzzy
12404
  #| msgid "Expired Events"
12405
  msgid "Expired!"
12406
  msgstr "Události vypršely"
12407
 
12408
- #: app/libraries/main.php:9306
12409
  #, fuzzy
12410
  #| msgid "Categories"
12411
  msgid "Uncategorized"
@@ -12612,10 +13195,6 @@ msgstr ""
12612
  msgid "Add to Cart"
12613
  msgstr "Umístění"
12614
 
12615
- #: app/modules/booking/steps/form.php:385
12616
- msgid "Submit"
12617
- msgstr "Potvrdit"
12618
-
12619
  #: app/modules/booking/steps/tickets.php:148
12620
  msgid ""
12621
  "By booking this event you can attend all occurrences. Some of them are "
@@ -12872,11 +13451,11 @@ msgstr "Nová událost"
12872
  msgid "Home"
12873
  msgstr "Domů"
12874
 
12875
- #: app/skins/single.php:1579
12876
  msgid "Speakers:"
12877
  msgstr "Řečník:"
12878
 
12879
- #: app/skins/single.php:1770
12880
  #, fuzzy
12881
  #| msgid "Download Invoice"
12882
  msgid "Download"
@@ -12999,6 +13578,9 @@ msgstr "Webnus Team"
12999
  msgid "http://webnus.net"
13000
  msgstr "http://webnus.net"
13001
 
 
 
 
13002
  #~ msgid "All of the day"
13003
  #~ msgstr "Celý den"
13004
 
@@ -13391,11 +13973,6 @@ msgstr "http://webnus.net"
13391
  #~ msgid "Insert -1 for unlimited usage"
13392
  #~ msgstr "Vložte URL stránky na Twitteru"
13393
 
13394
- #, fuzzy
13395
- #~| msgid "Exceptional Days"
13396
- #~ msgid "Expiration Date"
13397
- #~ msgstr "Výjimečné dny"
13398
-
13399
  #, fuzzy
13400
  #~| msgid "Next Event"
13401
  #~ msgid "Target Event"
@@ -13422,93 +13999,6 @@ msgstr "http://webnus.net"
13422
  #~ msgstr ""
13423
  #~ "Událost se neopakuje. Pro tuto událost neexistují žádná data!álosti)"
13424
 
13425
- #, fuzzy
13426
- #~| msgid "Unknown"
13427
- #~ msgid "Unknown Error!"
13428
- #~ msgstr "Neznámý"
13429
-
13430
- #, fuzzy
13431
- #~| msgid "Transaction ID"
13432
- #~ msgid "MEC Transaction ID: %s"
13433
- #~ msgstr "ID transakce"
13434
-
13435
- #, fuzzy
13436
- #~| msgid "day"
13437
- #~ msgid "Pay"
13438
- #~ msgstr "den"
13439
-
13440
- #, fuzzy
13441
- #~| msgid "Time Comment"
13442
- #~ msgid "Comment"
13443
- #~ msgstr "Časový komentář"
13444
-
13445
- #, fuzzy
13446
- #~| msgid "You should set %s as redirect page in Google App Console."
13447
- #~ msgid "You should set %s as Redirect URI in your stripe dashboard."
13448
- #~ msgstr ""
13449
- #~ "V aplikaci Google App Console byste měli nastavit % s jako stránku "
13450
- #~ "přesměrování."
13451
-
13452
- #, fuzzy
13453
- #~| msgid "Event Organizer"
13454
- #~ msgid "Comment for Organizer"
13455
- #~ msgstr "Organizátor události"
13456
-
13457
- #, fuzzy
13458
- #~| msgid "App Client ID"
13459
- #~ msgid "Client ID"
13460
- #~ msgstr "ID klienta aplikace"
13461
-
13462
- #, fuzzy
13463
- #~| msgid "Select Type"
13464
- #~ msgid "Fee Type"
13465
- #~ msgstr "Vyberte typ"
13466
-
13467
- #, fuzzy
13468
- #~| msgid "Percent"
13469
- #~ msgid "Per"
13470
- #~ msgstr "Procent"
13471
-
13472
- #, fuzzy
13473
- #~| msgid "The events are imported successfully!"
13474
- #~ msgid "User get connected sucessfully!"
13475
- #~ msgstr "Události byly úspěšně importovány!"
13476
-
13477
- #, fuzzy
13478
- #~| msgid "Confirmation"
13479
- #~ msgid "Disable Auto Confirmation"
13480
- #~ msgstr "Potvrzení"
13481
-
13482
- #, fuzzy
13483
- #~| msgid "Modern"
13484
- #~ msgid "Mode"
13485
- #~ msgstr "Moderní"
13486
-
13487
- #, fuzzy
13488
- #~| msgid "Modern Type"
13489
- #~ msgid "Card Type"
13490
- #~ msgstr "Moderní typ"
13491
-
13492
- #, fuzzy
13493
- #~| msgid "Discount"
13494
- #~ msgid "Discover"
13495
- #~ msgstr "Sleva"
13496
-
13497
- #, fuzzy
13498
- #~| msgid "Invoice is invalid."
13499
- #~ msgid "Payment is invalid."
13500
- #~ msgstr "Faktura je neplatná."
13501
-
13502
- #, fuzzy
13503
- #~| msgid "Booking Form"
13504
- #~ msgid "Booking fee for %s"
13505
- #~ msgstr "Rezervační formulář"
13506
-
13507
- #, fuzzy
13508
- #~| msgid "Your booking is confirmed."
13509
- #~ msgid "This booking is not free!"
13510
- #~ msgstr "Vaše rezervace je potvrzena."
13511
-
13512
  #, fuzzy
13513
  #~| msgid "Organizer Payment"
13514
  #~ msgid "Organizer Payment Credentials"
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: Modern Events Calendar Lite\n"
4
+ "POT-Creation-Date: 2022-01-12 09:53+0330\n"
5
+ "PO-Revision-Date: 2022-01-12 10:05+0330\n"
6
  "Last-Translator: \n"
7
  "Language-Team: \n"
8
  "Language: cs_CZ\n"
23
 
24
  #: app/addons/KC.php:68 app/addons/VC.php:59 app/features/ix/import.php:24
25
  #: app/features/ix/import.php:48 app/features/ix/import.php:77
26
+ #: app/features/ix/thirdparty.php:26 app/features/mec.php:1322
27
+ #: app/features/mec.php:1346 app/features/mec/dashboard.php:57
28
  #: app/features/mec/wizard.php:489 app/widgets/MEC.php:33
29
  msgid "Modern Events Calendar"
30
  msgstr "Moderní kalendář událostí"
35
  msgid "Content"
36
  msgstr "Obsah"
37
 
38
+ #: app/addons/KC.php:75 app/addons/VC.php:70 app/features/mec.php:588
39
+ #: app/features/mec.php:619 app/features/mec.php:649
40
  msgid "Shortcode"
41
  msgstr "Zkrácený kód"
42
 
104
  msgid "Select Shortcode"
105
  msgstr "Přidat nový zkrácený kód"
106
 
107
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:54
108
+ #, fuzzy
109
+ #| msgid "View Detail"
110
+ msgid "View details"
111
+ msgstr "Zobrazit detail"
112
+
113
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:77
114
+ #, fuzzy, php-format
115
+ #| msgid "More Information"
116
+ msgid "More information about %s"
117
+ msgstr "Více informací"
118
+
119
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:128
120
+ #, fuzzy
121
+ #| msgid "Checkout"
122
+ msgid "Check for updates"
123
+ msgstr "Překontrolovat"
124
+
125
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:214
126
+ #, php-format
127
+ msgctxt "the plugin title"
128
+ msgid "The %s plugin is up to date."
129
+ msgstr ""
130
+
131
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:216
132
+ #, php-format
133
+ msgctxt "the plugin title"
134
+ msgid "A new version of the %s plugin is available."
135
+ msgstr ""
136
+
137
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:218
138
+ #, php-format
139
+ msgctxt "the plugin title"
140
+ msgid "Could not determine if updates are available for %s."
141
+ msgstr ""
142
+
143
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:224
144
+ #, php-format
145
+ msgid "Unknown update checker status \"%s\""
146
+ msgstr ""
147
+
148
+ #: app/core/puc/Puc/v4p11/Vcs/PluginUpdateChecker.php:100
149
+ msgid "There is no changelog available."
150
+ msgstr ""
151
+
152
  #: app/core/src/Books/Book.php:106 app/features/ix.php:284
153
+ #: app/libraries/main.php:7761 app/libraries/main.php:7788
154
  msgid "Rejected"
155
  msgstr "Odmítnuto"
156
 
157
  #: app/core/src/Books/Book.php:111 app/features/ix.php:283
158
+ #: app/libraries/main.php:3232 app/libraries/main.php:7760
159
+ #: app/libraries/main.php:7780
160
  msgid "Confirmed"
161
  msgstr "Potvrzeno"
162
 
163
  #: app/core/src/Books/Book.php:117 app/features/mec/settings.php:742
164
+ #: app/libraries/main.php:7762 app/libraries/main.php:7784
165
  msgid "Pending"
166
  msgstr "Nevyřízený"
167
 
168
  #: app/core/src/Books/Book.php:186 app/features/ix.php:289
169
  #: app/features/labels.php:119 app/features/labels.php:145
170
+ #: app/libraries/main.php:7809
171
  msgid "Canceled"
172
  msgstr "Zrušená"
173
 
174
  #: app/core/src/Books/Book.php:191 app/features/ix.php:288
175
+ #: app/features/mec/booking.php:1251 app/features/mec/booking.php:1273
176
  #: app/features/mec/integrations.php:449 app/features/mec/integrations.php:471
177
  #: app/features/mec/modules.php:406 app/features/mec/modules.php:428
178
  #: app/features/mec/notifications.php:1922
179
  #: app/features/mec/notifications.php:1945 app/features/mec/settings.php:1599
180
  #: app/features/mec/settings.php:1621 app/features/mec/single.php:595
181
+ #: app/features/mec/single.php:617 app/libraries/main.php:7808
182
  msgid "Verified"
183
  msgstr "Ověřeno"
184
 
185
+ #: app/core/src/Books/Book.php:197 app/libraries/main.php:7810
186
  msgid "Waiting"
187
  msgstr "Čekající"
188
 
209
  #: app/core/src/Forms/FormFields.php:188 app/core/src/Forms/SettingsForm.php:93
210
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:70
211
  #: app/features/autoemails.php:60 app/features/events.php:606
212
+ #: app/features/events.php:2656 app/features/events.php:2723
213
+ #: app/features/events.php:2812 app/features/events.php:4426
214
  #: app/features/fes.php:280 app/features/fes/form.php:810
215
+ #: app/features/gateways.php:1288 app/features/gateways.php:1531
216
+ #: app/features/gateways.php:3199 app/features/login/login.php:5
217
+ #: app/features/mec/booking.php:57 app/features/mec/booking.php:794
218
+ #: app/features/mec/booking.php:892 app/features/mec/settings.php:295
219
+ #: app/features/mec/single.php:303 app/features/organizers.php:112
220
+ #: app/features/organizers.php:153 app/features/profile/profile.php:206
221
+ #: app/features/speakers.php:128 app/features/speakers.php:205
222
+ #: app/libraries/main.php:618 app/libraries/main.php:2093
223
+ #: app/libraries/main.php:2162 app/libraries/main.php:3989
224
+ #: app/libraries/notifications.php:2091 app/modules/booking/steps/form.php:69
225
+ #: app/modules/booking/steps/form.php:218 app/skins/single.php:1394
226
+ #: app/skins/single.php:1461 app/skins/single/default.php:347
227
+ #: app/skins/single/default.php:596 app/skins/single/m1.php:141
228
+ #: app/skins/single/m2.php:61 app/skins/single/modern.php:94
229
  msgid "Email"
230
  msgstr "Email"
231
 
243
  #: app/core/src/Forms/FormFields.php:396 app/core/src/Forms/FormFields.php:442
244
  #: app/core/src/Forms/FormFields.php:488 app/core/src/Forms/FormFields.php:544
245
  #: app/core/src/Forms/FormFields.php:596 app/features/organizers.php:340
246
+ #: app/features/organizers.php:348 app/libraries/main.php:3897
247
+ #: app/libraries/main.php:3928 app/libraries/main.php:3958
248
+ #: app/libraries/main.php:3988 app/libraries/main.php:4019
249
+ #: app/libraries/main.php:4050 app/libraries/main.php:4080
250
+ #: app/libraries/main.php:4111 app/libraries/main.php:4142
251
+ #: app/libraries/main.php:4180 app/libraries/main.php:4204
252
+ #: app/libraries/main.php:4252 app/libraries/main.php:4300
253
+ #: app/libraries/main.php:4358 app/libraries/main.php:4408
254
  msgid "Sort"
255
  msgstr "Seřadit"
256
 
257
  #: app/core/src/Forms/FormFields.php:52 app/core/src/Forms/SettingsForm.php:88
258
+ #: app/features/events.php:2722 app/features/events.php:2811
259
  #: app/features/mec/booking.php:793 app/features/mec/booking.php:891
260
+ #: app/features/mec/single.php:302 app/libraries/main.php:3898
261
  #: app/libraries/skins.php:1377
262
  msgid "Text"
263
  msgstr "Text"
268
  #: app/core/src/Forms/FormFields.php:286 app/core/src/Forms/FormFields.php:317
269
  #: app/core/src/Forms/FormFields.php:348 app/core/src/Forms/FormFields.php:403
270
  #: app/core/src/Forms/FormFields.php:449 app/core/src/Forms/FormFields.php:495
271
+ #: app/core/src/Forms/FormFields.php:551 app/libraries/main.php:3905
272
+ #: app/libraries/main.php:3936 app/libraries/main.php:3966
273
+ #: app/libraries/main.php:3996 app/libraries/main.php:4027
274
+ #: app/libraries/main.php:4058 app/libraries/main.php:4088
275
+ #: app/libraries/main.php:4119 app/libraries/main.php:4151
276
+ #: app/libraries/main.php:4212 app/libraries/main.php:4260
277
+ #: app/libraries/main.php:4308 app/libraries/main.php:4366
278
  msgid "Required Field"
279
  msgstr "Požadovaná pole"
280
 
286
  #: app/core/src/Forms/FormFields.php:406 app/core/src/Forms/FormFields.php:452
287
  #: app/core/src/Forms/FormFields.php:505 app/core/src/Forms/FormFields.php:554
288
  #: app/core/src/Forms/FormFields.php:597 app/features/events.php:2121
289
+ #: app/features/events.php:2147 app/features/events.php:2359
290
+ #: app/features/events.php:2496 app/features/events.php:2533
291
  #: app/features/mec/booking.php:611 app/features/mec/booking.php:641
292
  #: app/features/mec/booking.php:709 app/features/mec/booking.php:741
293
  #: app/features/organizers.php:340 app/features/organizers.php:349
294
  #: app/libraries/hourlyschedule.php:53 app/libraries/hourlyschedule.php:74
295
  #: app/libraries/hourlyschedule.php:102 app/libraries/hourlyschedule.php:130
296
+ #: app/libraries/hourlyschedule.php:154 app/libraries/main.php:3908
297
+ #: app/libraries/main.php:3939 app/libraries/main.php:3969
298
+ #: app/libraries/main.php:3999 app/libraries/main.php:4030
299
+ #: app/libraries/main.php:4061 app/libraries/main.php:4091
300
+ #: app/libraries/main.php:4122 app/libraries/main.php:4160
301
+ #: app/libraries/main.php:4182 app/libraries/main.php:4215
302
+ #: app/libraries/main.php:4263 app/libraries/main.php:4318
303
+ #: app/libraries/main.php:4369 app/libraries/main.php:4409
304
  #: app/libraries/ticketVariations.php:72
305
  msgid "Remove"
306
  msgstr "Odstranit"
311
  #: app/core/src/Forms/FormFields.php:292 app/core/src/Forms/FormFields.php:323
312
  #: app/core/src/Forms/FormFields.php:354 app/core/src/Forms/FormFields.php:409
313
  #: app/core/src/Forms/FormFields.php:455 app/core/src/Forms/FormFields.php:508
314
+ #: app/core/src/Forms/FormFields.php:557 app/libraries/main.php:3911
315
+ #: app/libraries/main.php:3942 app/libraries/main.php:3972
316
+ #: app/libraries/main.php:4002 app/libraries/main.php:4033
317
+ #: app/libraries/main.php:4064 app/libraries/main.php:4094
318
+ #: app/libraries/main.php:4125 app/libraries/main.php:4163
319
+ #: app/libraries/main.php:4218 app/libraries/main.php:4266
320
+ #: app/libraries/main.php:4321 app/libraries/main.php:4372
321
  msgid "Insert a label for this field"
322
  msgstr "Vložte štítek pro toto pole"
323
 
333
  msgid "MEC Last Name"
334
  msgstr "MEC Jméno"
335
 
336
+ #: app/core/src/Forms/FormFields.php:93 app/features/events.php:2720
337
+ #: app/features/mec/booking.php:791 app/libraries/main.php:3929
338
  msgid "MEC Name"
339
  msgstr "MEC Jméno"
340
 
341
  #: app/core/src/Forms/FormFields.php:158 app/core/src/Forms/SettingsForm.php:83
342
+ #: app/features/events.php:2721 app/features/mec/booking.php:792
343
+ #: app/libraries/main.php:3959
344
  msgid "MEC Email"
345
  msgstr "MEC Email"
346
 
347
  #: app/core/src/Forms/FormFields.php:219 app/features/mec/single.php:304
348
+ #: app/libraries/main.php:4020
349
  msgid "URL"
350
  msgstr ""
351
 
352
  #: app/core/src/Forms/FormFields.php:250
353
+ #: app/core/src/Forms/SettingsForm.php:108 app/features/events.php:2726
354
+ #: app/features/mec/booking.php:797 app/libraries/main.php:4051
355
  msgid "File"
356
  msgstr "Soubor"
357
 
358
  #: app/core/src/Forms/FormFields.php:280 app/core/src/Forms/SettingsForm.php:98
359
  #: app/core/src/SingleBuilder/Widgets/EventDate/EventDate.php:47
360
+ #: app/features/events.php:1396 app/features/events.php:2724
361
+ #: app/features/events.php:2813 app/features/fes.php:280
362
  #: app/features/mec/booking.php:795 app/features/mec/booking.php:893
363
  #: app/features/mec/single.php:305 app/features/profile/profile.php:59
364
+ #: app/features/wc.php:79 app/libraries/main.php:4081
365
  #: app/libraries/skins.php:1289 app/modules/booking/steps/tickets.php:136
366
+ #: app/modules/next-event/details.php:145 app/skins/single.php:1186
367
  #: app/skins/single/default.php:171 app/skins/single/default.php:423
368
  #: app/skins/single/m1.php:40 app/skins/single/modern.php:253
369
  msgid "Date"
370
  msgstr "Datum"
371
 
372
  #: app/core/src/Forms/FormFields.php:311
373
+ #: app/core/src/Forms/SettingsForm.php:103 app/features/events.php:2725
374
+ #: app/features/events.php:2814 app/features/mec/booking.php:796
375
  #: app/features/mec/booking.php:894 app/features/mec/single.php:306
376
  #: app/features/organizers.php:104 app/features/organizers.php:149
377
  #: app/features/speakers.php:120 app/features/speakers.php:201
378
+ #: app/features/speakers.php:288 app/libraries/main.php:4112
379
  msgid "Tel"
380
  msgstr "Tel"
381
 
382
  #: app/core/src/Forms/FormFields.php:342
383
+ #: app/core/src/Forms/SettingsForm.php:113 app/features/events.php:2727
384
+ #: app/features/events.php:2815 app/features/mec/booking.php:798
385
  #: app/features/mec/booking.php:895 app/features/mec/single.php:307
386
+ #: app/libraries/main.php:4143
387
  msgid "Textarea"
388
  msgstr "Plocha textu"
389
 
390
  #: app/core/src/Forms/FormFields.php:373
391
+ #: app/core/src/Forms/SettingsForm.php:138 app/features/events.php:2732
392
+ #: app/features/events.php:2820 app/features/mec/booking.php:803
393
  #: app/features/mec/booking.php:900 app/features/mec/settings.php:351
394
+ #: app/features/mec/single.php:308 app/libraries/main.php:4181
395
  msgid "Paragraph"
396
  msgstr "Paragraf"
397
 
398
+ #: app/core/src/Forms/FormFields.php:378 app/libraries/main.php:4187
399
  msgid "HTML and shortcode are allowed."
400
  msgstr "HTML a zkrácené kódy jsou povoleny."
401
 
402
  #: app/core/src/Forms/FormFields.php:397
403
+ #: app/core/src/Forms/SettingsForm.php:118 app/features/events.php:2728
404
+ #: app/features/events.php:2816 app/features/mec/booking.php:127
405
  #: app/features/mec/booking.php:799 app/features/mec/booking.php:896
406
+ #: app/features/mec/single.php:309 app/libraries/main.php:4205
407
  msgid "Checkboxes"
408
  msgstr "Zatržítko"
409
 
410
  #: app/core/src/Forms/FormFields.php:421 app/core/src/Forms/FormFields.php:467
411
+ #: app/core/src/Forms/FormFields.php:520 app/libraries/main.php:4232
412
+ #: app/libraries/main.php:4280 app/libraries/main.php:4335
413
  msgid "Option"
414
  msgstr "Možnost"
415
 
416
  #: app/core/src/Forms/FormFields.php:443
417
+ #: app/core/src/Forms/SettingsForm.php:123 app/features/events.php:2729
418
+ #: app/features/events.php:2817 app/features/mec/booking.php:800
419
  #: app/features/mec/booking.php:897 app/features/mec/single.php:310
420
+ #: app/libraries/main.php:4253
421
  msgid "Radio Buttons"
422
  msgstr "Přepínače"
423
 
424
  #: app/core/src/Forms/FormFields.php:489
425
+ #: app/core/src/Forms/SettingsForm.php:128 app/features/events.php:2730
426
+ #: app/features/events.php:2818 app/features/mec/booking.php:125
427
  #: app/features/mec/booking.php:801 app/features/mec/booking.php:898
428
  #: app/features/mec/meta_boxes/search_form.php:67
429
  #: app/features/mec/meta_boxes/search_form.php:75
506
  #: app/features/mec/meta_boxes/search_form.php:1094
507
  #: app/features/mec/meta_boxes/search_form.php:1116
508
  #: app/features/mec/single.php:311 app/features/popup/settings.php:348
509
+ #: app/libraries/main.php:4301
510
  msgid "Dropdown"
511
  msgstr "Rozbalovací"
512
 
515
  msgstr ""
516
 
517
  #: app/core/src/Forms/FormFields.php:545
518
+ #: app/core/src/Forms/SettingsForm.php:133 app/features/events.php:2731
519
+ #: app/features/events.php:2819 app/features/mec/booking.php:802
520
+ #: app/features/mec/booking.php:899 app/libraries/main.php:4359
521
  msgid "Agreement"
522
  msgstr "Smlouva"
523
 
524
+ #: app/core/src/Forms/FormFields.php:557 app/libraries/main.php:4372
525
  #, php-format
526
  msgid "Instead of %s, the page title with a link will be show."
527
  msgstr "Místo%s se zobrazí název stránky s odkazem."
528
 
529
  #: app/core/src/Forms/FormFields.php:559 app/features/mec/settings.php:1145
530
+ #: app/libraries/main.php:4374
531
  msgid "Agreement Page"
532
  msgstr "Stránka smlouvy"
533
 
534
  #: app/core/src/Forms/FormFields.php:570 app/features/profile/profile.php:62
535
+ #: app/libraries/main.php:4383
536
  msgid "Status"
537
  msgstr "Stav"
538
 
539
+ #: app/core/src/Forms/FormFields.php:572 app/libraries/main.php:4385
540
  msgid "Checked by default"
541
  msgstr "Ve výchozím nastavení zaškrtnuto"
542
 
543
+ #: app/core/src/Forms/FormFields.php:573 app/libraries/main.php:4386
544
  msgid "Unchecked by default"
545
  msgstr "Ve výchozím nastavení není zaškrtnuto"
546
 
547
+ #: app/core/src/Forms/FormFields.php:598 app/libraries/main.php:4410
548
  msgid "Insert a label for this option"
549
  msgstr "Vložte štítek pro tuto možnost"
550
 
551
+ #: app/core/src/Forms/FormFields.php:606 app/libraries/main.php:8984
552
  msgid "Mapping with Profile Fields"
553
  msgstr ""
554
 
696
  #: app/features/events.php:1404 app/features/events.php:1541
697
  #: app/features/events.php:1666 app/features/events.php:1836
698
  #: app/features/events.php:1849 app/features/events.php:2020
699
+ #: app/features/events.php:2035 app/features/events.php:2277
700
+ #: app/features/events.php:2289 app/features/events.php:2482
701
+ #: app/features/events.php:2519 app/features/fes/form.php:458
702
  #: app/features/fes/form.php:766 app/features/fes/form.php:901
703
+ #: app/features/gateways.php:1433 app/features/gateways.php:3355
704
+ #: app/features/gateways.php:3368 app/features/gateways.php:3655
705
+ #: app/features/gateways.php:4021 app/features/gateways.php:4074
706
+ #: app/features/gateways.php:4092 app/features/gateways.php:4821
707
+ #: app/features/gateways.php:5959 app/features/gateways.php:5979
708
+ #: app/features/gateways.php:6317 app/features/locations.php:341
709
+ #: app/features/mec/booking.php:109 app/features/mec/booking.php:185
710
+ #: app/features/mec/booking.php:198 app/features/mec/booking.php:234
711
+ #: app/features/mec/booking.php:299 app/features/mec/booking.php:332
712
+ #: app/features/mec/booking.php:345 app/features/mec/booking.php:411
713
+ #: app/features/mec/booking.php:462 app/features/mec/booking.php:598
714
+ #: app/features/mec/booking.php:628 app/features/mec/booking.php:694
715
+ #: app/features/mec/booking.php:704 app/features/mec/booking.php:726
716
+ #: app/features/mec/booking.php:736 app/features/mec/booking.php:1006
717
+ #: app/features/mec/booking.php:1034 app/features/mec/integrations.php:57
718
  #: app/features/mec/integrations.php:70 app/features/mec/integrations.php:86
719
  #: app/features/mec/meta_boxes/display_options.php:98
720
  #: app/features/mec/meta_boxes/display_options.php:111
786
  #: app/features/popup/settings.php:78 app/features/popup/settings.php:161
787
  #: app/features/popup/settings.php:182 app/features/popup/settings.php:300
788
  #: app/libraries/ticketVariations.php:50 app/libraries/ticketVariations.php:65
789
+ #: app/skins/single.php:1213 app/skins/single.php:1329
790
  #: app/skins/single/default.php:25 app/skins/single/m1.php:16
791
  #: app/skins/single/m2.php:16 app/skins/single/modern.php:26
792
  msgid "Read More"
906
  msgstr ""
907
 
908
  #: app/core/src/SingleBuilder/Widgets/EventCategories/EventCategories.php:47
909
+ #: app/features/events.php:218 app/features/events.php:3858
910
  #: app/features/mec/meta_boxes/display_options.php:1657
911
  #: app/features/mec/meta_boxes/search_form.php:64
912
  #: app/features/mec/meta_boxes/search_form.php:152
923
  #: app/features/mec/settings.php:1165 app/features/mec/settings.php:1228
924
  #: app/features/mec/single.php:460 app/features/mec/single.php:513
925
  #: app/features/popup/settings.php:220 app/features/popup/settings.php:259
926
+ #: app/features/search.php:91 app/libraries/main.php:7411
927
+ #: app/libraries/main.php:7472 app/libraries/search.php:256
928
  #: app/libraries/skins.php:1090 app/skins/single.php:1090
929
  #: app/skins/single/default.php:299 app/skins/single/default.php:549
930
  #: app/skins/single/m1.php:231 app/skins/single/m2.php:151
947
  #: app/core/src/SingleBuilder/Widgets/EventCost/EventCost.php:47
948
  #: app/features/events.php:432 app/features/events.php:1283
949
  #: app/features/fes/form.php:868 app/features/mec/settings.php:1162
950
+ #: app/features/occurrences.php:511 app/libraries/main.php:7457
951
+ #: app/libraries/main.php:7504 app/libraries/skins.php:1405
952
+ #: app/skins/single.php:1121 app/skins/single/default.php:215
953
  #: app/skins/single/default.php:467 app/skins/single/m1.php:80
954
  #: app/skins/single/modern.php:293
955
  msgid "Cost"
1026
  msgstr ""
1027
 
1028
  #: app/core/src/SingleBuilder/Widgets/EventLabels/EventLabels.php:48
1029
+ #: app/features/events.php:4180 app/features/fes/form.php:998
1030
  #: app/features/labels.php:61 app/features/labels.php:227
1031
+ #: app/features/mec.php:515 app/features/mec/meta_boxes/filter.php:72
1032
+ #: app/features/mec/meta_boxes/filter.php:135 app/libraries/main.php:7412
1033
+ #: app/libraries/main.php:7473 app/skins/single.php:1248
1034
  #: app/skins/single/default.php:247 app/skins/single/default.php:496
1035
  #: app/skins/single/m1.php:95 app/skins/single/modern.php:308
1036
  msgid "Labels"
1062
  msgstr "Skrýt místo"
1063
 
1064
  #: app/core/src/SingleBuilder/Widgets/EventLocations/EventLocations.php:54
1065
+ #: app/features/events.php:3859 app/features/events.php:4173
1066
  #: app/features/locations.php:58 app/features/locations.php:267
1067
  #: app/features/locations.php:329 app/features/locations.php:331
1068
  #: app/features/locations.php:340
1085
  #: app/features/popup/event.php:118 app/features/popup/event.php:127
1086
  #: app/features/popup/settings.php:228 app/features/popup/settings.php:267
1087
  #: app/features/search.php:97 app/libraries/main.php:2961
1088
+ #: app/libraries/main.php:3238 app/libraries/main.php:7415
1089
+ #: app/libraries/main.php:7476 app/libraries/search.php:294
1090
  #: app/libraries/skins.php:1145 app/skins/single.php:1017
1091
+ #: app/skins/single.php:1520 app/skins/single/default.php:268
1092
  #: app/skins/single/default.php:519 app/skins/single/m1.php:201
1093
  #: app/skins/single/m2.php:121 app/skins/single/modern.php:153
1094
  msgid "Location"
1097
  #: app/core/src/SingleBuilder/Widgets/EventLocations/EventLocations.php:63
1098
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:77
1099
  #: app/features/speakers.php:136 app/features/speakers.php:209
1100
+ #: app/skins/single.php:1401 app/skins/single.php:1468
1101
  #: app/skins/single/default.php:276 app/skins/single/default.php:354
1102
  #: app/skins/single/default.php:526 app/skins/single/default.php:603
1103
  #: app/skins/single/m1.php:148 app/skins/single/m1.php:209
1120
  #: app/core/src/SingleBuilder/Widgets/EventMoreInfo/EventMoreInfo.php:48
1121
  #: app/features/events.php:1525 app/features/events.php:1538
1122
  #: app/features/fes/form.php:836 app/features/occurrences.php:525
1123
+ #: app/libraries/main.php:7455 app/libraries/main.php:7502
1124
+ #: app/skins/single.php:1218 app/skins/single/default.php:232
1125
  #: app/skins/single/default.php:481 app/skins/single/m1.php:257
1126
  #: app/skins/single/m2.php:178 app/skins/single/modern.php:211
1127
  #: app/widgets/single.php:105
1169
  msgstr "Skrýt organizátora"
1170
 
1171
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:53
1172
+ #: app/features/events.php:431 app/features/events.php:3860
1173
+ #: app/features/events.php:4175 app/features/events.php:4176
1174
+ #: app/features/events.php:4177
1175
  #: app/features/mec/meta_boxes/display_options.php:1660
1176
  #: app/features/mec/meta_boxes/search_form.php:80
1177
  #: app/features/mec/meta_boxes/search_form.php:168
1193
  #: app/features/organizers.php:288 app/features/popup/event.php:165
1194
  #: app/features/popup/event.php:174 app/features/popup/settings.php:224
1195
  #: app/features/popup/settings.php:263 app/features/search.php:103
1196
+ #: app/libraries/main.php:7417 app/libraries/main.php:7478
1197
  #: app/libraries/search.php:314 app/libraries/skins.php:1174
1198
+ #: app/skins/single.php:1376 app/skins/single/default.php:329
1199
  #: app/skins/single/default.php:578 app/skins/single/m1.php:123
1200
  #: app/skins/single/m2.php:43 app/skins/single/modern.php:76
1201
  msgid "Organizer"
1202
  msgstr "Organizátor"
1203
 
1204
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:63
1205
+ #: app/skins/single.php:1387 app/skins/single.php:1454
1206
  #: app/skins/single/default.php:340 app/skins/single/default.php:589
1207
  #: app/skins/single/m1.php:134 app/skins/single/m2.php:54
1208
  #: app/skins/single/modern.php:87
1234
  msgstr "Registrační tlačítko"
1235
 
1236
  #: app/core/src/SingleBuilder/Widgets/EventRegisterButton/EventRegisterButton.php:48
1237
+ #: app/libraries/main.php:7451 app/libraries/main.php:7498
1238
  #: app/skins/available_spot/tpl.php:204 app/skins/carousel/render.php:105
1239
  #: app/skins/carousel/render.php:145 app/skins/grid/render.php:94
1240
  #: app/skins/grid/render.php:153 app/skins/grid/render.php:214
1241
  #: app/skins/grid/render.php:237 app/skins/list/render.php:90
1242
  #: app/skins/list/render.php:210 app/skins/masonry/render.php:151
1243
+ #: app/skins/single.php:548 app/skins/single.php:1324 app/skins/single.php:1335
1244
  #: app/skins/single/default.php:374 app/skins/single/default.php:376
1245
  #: app/skins/single/default.php:621 app/skins/single/default.php:623
1246
  #: app/skins/single/m1.php:166 app/skins/single/m1.php:168
1305
  #: app/core/src/SingleBuilder/Widgets/EventTime/EventTime.php:43
1306
  #: app/features/emails/details.php:24 app/features/emails/details.php:27
1307
  #: app/libraries/skins.php:1362 app/modules/next-event/details.php:151
1308
+ #: app/skins/single.php:1292 app/skins/single/default.php:190
1309
  #: app/skins/single/default.php:442 app/skins/single/m1.php:59
1310
  #: app/skins/single/modern.php:272
1311
  msgid "Time"
1313
 
1314
  #: app/core/src/SingleBuilder/Widgets/EventTime/EventTime.php:49
1315
  #: app/features/booking/calendar_novel.php:140
1316
+ #: app/features/search_bar/search_result.php:12 app/libraries/main.php:7460
1317
+ #: app/libraries/main.php:7507 app/libraries/notifications.php:1632
1318
  #: app/libraries/render.php:554 app/libraries/render.php:758
1319
  #: app/libraries/render.php:816 app/libraries/render.php:977
1320
  #: app/modules/local-time/details.php:52 app/modules/local-time/type1.php:47
1321
  #: app/modules/local-time/type2.php:83 app/modules/local-time/type3.php:47
1322
  #: app/modules/next-event/details.php:157
1323
+ #: app/modules/next-event/multiple.php:72 app/skins/single.php:1298
1324
  #: app/skins/single/default.php:196 app/skins/single/default.php:448
1325
  #: app/skins/single/m1.php:65 app/skins/single/modern.php:278
1326
  #, fuzzy
1361
  msgid "%s notification(s) sent."
1362
  msgstr "Upozornění"
1363
 
1364
+ #: app/features/autoemails.php:61 app/features/mec.php:532
1365
  #, fuzzy
1366
  #| msgid "Email"
1367
  msgid "Emails"
1421
  msgid "Coupon was not valid or applicable."
1422
  msgstr ""
1423
 
1424
+ #: app/features/cart.php:174 app/features/gateways.php:105
1425
+ #: app/features/gateways.php:594 app/features/gateways.php:1876
1426
+ #: app/features/gateways.php:2452 app/features/gateways.php:3778
1427
+ #: app/features/gateways.php:3956 app/features/gateways.php:5027
1428
+ #: app/features/gateways.php:5354 app/features/gateways.php:5605
1429
+ #: app/features/gateways.php:6441 app/features/gateways.php:6619
1430
  #, fuzzy
1431
  #| msgid "Request is not valid."
1432
  msgid "Request is invalid!"
1436
  msgid "Your cart is not free!"
1437
  msgstr ""
1438
 
1439
+ #: app/features/cart.php:191 app/features/gateways.php:112
1440
  #, fuzzy
1441
  #| msgid "Thanks for your booking."
1442
  msgid "Thanks for your booking."
1454
  msgid "Go to events page"
1455
  msgstr "Zobrazit Mapy Google na stránce události"
1456
 
1457
+ #: app/features/cart/cart.php:43 app/features/events.php:4719
1458
  #: app/features/fes.php:280 app/features/mec/booking.php:351
1459
  #: app/features/wc.php:81 app/libraries/main.php:3013
1460
  #: app/libraries/main.php:3127 app/libraries/main.php:3230
1475
 
1476
  #: app/features/cart/cart.php:45 app/features/events.php:1564
1477
  #: app/features/events.php:1930 app/libraries/book.php:172
1478
+ #: app/libraries/main.php:7445 app/modules/booking/steps/tickets.php:168
1479
  #: app/modules/booking/steps/tickets.php:174
1480
  msgid "Tickets"
1481
  msgstr "Vstupenky"
1520
  msgstr "Zdarma"
1521
 
1522
  #: app/features/cart/checkout.php:96 app/features/contextual.php:308
1523
+ #: app/features/events.php:397 app/features/gateways.php:3425
1524
+ #: app/features/mec/booking.php:88 app/features/mec/notifications.php:45
1525
+ #: app/features/mec/support-page.php:110 app/features/mec/support-page.php:114
1526
+ #: app/libraries/main.php:647 app/libraries/main.php:648
1527
+ #: app/libraries/main.php:652 app/libraries/main.php:677
1528
+ #: app/libraries/main.php:795 app/libraries/main.php:3022
1529
+ #: app/libraries/main.php:7435 app/libraries/main.php:7437
1530
+ #: app/modules/booking/steps/checkout.php:146
1531
  msgid "Booking"
1532
  msgstr "Rezervace"
1533
 
1548
  msgid "Recent Colors"
1549
  msgstr "Barva události"
1550
 
1551
+ #: app/features/contextual.php:55 app/features/mec.php:536
1552
+ #: app/features/mec/dashboard.php:126 app/features/mec/support.php:20
1553
  #: app/features/mec/wizard.php:521 app/features/popup/event.php:61
1554
  #: app/features/popup/settings.php:30 app/features/popup/shortcode.php:39
1555
  #: app/libraries/main.php:703
1557
  msgstr "Nastavení"
1558
 
1559
  #: app/features/contextual.php:62 app/features/events.php:1571
1560
+ #: app/features/events.php:2661 app/features/mec/booking.php:756
1561
+ #: app/features/mec/booking.php:1032 app/features/mec/settings.php:1018
1562
  #: app/features/mec/support.php:29
1563
  msgid "Booking Form"
1564
  msgstr "Rezervační formulář"
1739
  msgstr "Výjimečné dny"
1740
 
1741
  #: app/features/contextual.php:318 app/features/mec/booking.php:553
1742
+ #: app/features/mec/booking.php:989 app/libraries/main.php:649
1743
  msgid "Coupons"
1744
  msgstr "Kupóny"
1745
 
1762
  msgid "Downloadable File"
1763
  msgstr "Stáhnout ICS soubor"
1764
 
1765
+ #: app/features/dlfile.php:142 app/features/dlfile.php:291
1766
  msgid "pdf,zip,png,jpg and gif files are allowed."
1767
  msgstr ""
1768
 
1769
+ #: app/features/dlfile.php:144 app/features/dlfile.php:293
1770
  #, fuzzy
1771
  #| msgid "Remove image"
1772
  msgid "Remove File"
1773
  msgstr "Odebrat obrázek"
1774
 
1775
+ #: app/features/dlfile.php:162 app/features/dlfile.php:319
1776
  #, fuzzy
1777
  #| msgid "Please upload the feed file."
1778
  msgid "Please upload a file."
1779
  msgstr "Nahrajte prosím zdrojový soubor."
1780
 
1781
+ #: app/features/dlfile.php:170 app/features/dlfile.php:327
1782
  #, php-format
1783
  msgid "File extension is invalid. You can upload %s files."
1784
  msgstr ""
1785
 
1786
+ #: app/features/dlfile.php:176 app/features/dlfile.php:333
1787
  #, php-format
1788
  msgid "File is too big. Maximum size is %s KB."
1789
  msgstr ""
1790
 
1791
+ #: app/features/dlfile.php:206 app/features/dlfile.php:363
1792
  #, fuzzy
1793
  #| msgid "The image is uploaded!"
1794
  msgid "File uploaded!"
1795
  msgstr "Obrázek je nahraný!"
1796
 
1797
+ #: app/features/dlfile.php:287
1798
  msgid "Public File to Download"
1799
  msgstr ""
1800
 
1801
+ #: app/features/dlfile.php:297 app/features/events.php:3857
1802
+ #: app/features/events.php:4166 app/features/events.php:4713
1803
+ #: app/features/fes/form.php:260 app/features/gateways.php:1414
1804
+ #: app/features/gateways.php:3343 app/features/gateways.php:3636
1805
+ #: app/features/gateways.php:4055 app/features/gateways.php:4802
1806
+ #: app/features/gateways.php:5940 app/features/gateways.php:6298
1807
+ #: app/features/mec/booking.php:686 app/features/mec/booking.php:718
1808
+ #: app/features/mec/styling.php:134 app/libraries/hourlyschedule.php:49
1809
+ #: app/libraries/hourlyschedule.php:65 app/libraries/hourlyschedule.php:93
1810
+ #: app/libraries/hourlyschedule.php:125 app/libraries/hourlyschedule.php:145
1811
+ #: app/libraries/ticketVariations.php:39
1812
+ msgid "Title"
1813
+ msgstr "Název"
1814
+
1815
+ #: app/features/dlfile.php:301 app/features/events.php:1994
1816
+ #: app/features/events.php:2254 app/features/events.php:4167
1817
+ #: app/libraries/hourlyschedule.php:72 app/libraries/hourlyschedule.php:100
1818
+ #: app/libraries/hourlyschedule.php:152
1819
+ msgid "Description"
1820
+ msgstr "Popis"
1821
+
1822
  #: app/features/emails/details.php:26
1823
  #, fuzzy
1824
  #| msgid "Organizer Email"
1871
  msgstr "Další výskyt"
1872
 
1873
  #: app/features/emails/details.php:40 app/features/events.php:192
1874
+ #: app/features/ix/export.php:37 app/features/mec/dashboard.php:217
1875
+ #: app/libraries/main.php:6430 app/libraries/main.php:6450
1876
  #: app/skins/daily_view/tpl.php:84 app/skins/monthly_view/calendar_clean.php:46
1877
  #: app/skins/monthly_view/tpl.php:76 app/skins/tile/tpl.php:85
1878
  #: app/skins/yearly_view/tpl.php:73
1887
  msgid "Placeholders"
1888
  msgstr ""
1889
 
1890
+ #: app/features/events.php:194 app/features/mec.php:512
1891
  #: app/features/mec/wizard.php:511
1892
  msgid "Add Event"
1893
  msgstr "Přidat událost"
1894
 
1895
+ #: app/features/events.php:195 app/features/mec/dashboard.php:125
1896
  msgid "Add New Event"
1897
  msgstr "Přidat novou událost"
1898
 
1915
  msgid "No events found in Trash!"
1916
  msgstr "V koši nebyly nalezeny žádné události!"
1917
 
1918
+ #: app/features/events.php:219 app/features/events.php:3814
1919
+ #: app/features/events.php:4181 app/features/fes/form.php:972
1920
+ #: app/features/mec.php:514 app/features/mec/meta_boxes/filter.php:69
1921
+ #: app/features/mec/meta_boxes/filter.php:81 app/libraries/main.php:7410
1922
+ #: app/libraries/main.php:7471
1923
  msgid "Categories"
1924
  msgstr "Kategorie"
1925
 
2038
  msgstr "Zobrazit událost"
2039
 
2040
  #: app/features/events.php:428 app/features/mec/settings.php:943
2041
+ #: app/libraries/hourlyschedule.php:36 app/skins/single.php:1560
2042
  msgid "Hourly Schedule"
2043
  msgstr "Hodinový rozvrh"
2044
 
2072
  msgid "Guest Data"
2073
  msgstr "Údaje hosta"
2074
 
2075
+ #: app/features/events.php:605 app/features/events.php:2647
2076
+ #: app/features/events.php:4423 app/features/fes.php:280
2077
+ #: app/features/fes/form.php:814 app/features/gateways.php:1282
2078
+ #: app/features/gateways.php:1372 app/features/gateways.php:1525
2079
+ #: app/features/gateways.php:1743 app/features/gateways.php:3193
2080
+ #: app/features/gateways.php:3295 app/features/labels.php:184
2081
  #: app/features/mec/booking.php:45 app/features/organizers.php:296
2082
+ #: app/features/popup/event.php:184 app/features/profile/profile.php:203
2083
  #: app/libraries/notifications.php:2090 app/modules/booking/steps/form.php:60
2084
  msgid "Name"
2085
  msgstr "Jméno"
2095
  msgstr "Datum a čas"
2096
 
2097
  #: app/features/events.php:622 app/features/events.php:626
2098
+ #: app/features/events.php:3861 app/features/events.php:4168
2099
  #: app/features/fes/form.php:286 app/features/fes/form.php:290
2100
+ #: app/features/ix/import_g_calendar.php:38 app/features/mec.php:1545
2101
  #: app/features/mec/meta_boxes/display_options.php:57
2102
  #: app/features/mec/meta_boxes/display_options.php:312
2103
  #: app/features/mec/meta_boxes/display_options.php:578
2119
  msgstr "Počátečná den"
2120
 
2121
  #: app/features/events.php:642 app/features/events.php:646
2122
+ #: app/features/events.php:3862 app/features/events.php:4170
2123
  #: app/features/fes/form.php:306 app/features/fes/form.php:310
2124
+ #: app/features/ix/import_g_calendar.php:44 app/features/mec.php:1546
2125
  #: app/features/mec/meta_boxes/display_options.php:73
2126
  #: app/features/mec/meta_boxes/display_options.php:328
2127
  #: app/features/mec/meta_boxes/display_options.php:594
2176
  #: app/features/events.php:716 app/features/events.php:729
2177
  #: app/features/events.php:1768 app/features/events.php:1778
2178
  #: app/features/events.php:1799 app/features/events.php:1819
2179
+ #: app/features/events.php:1874 app/features/events.php:2444
2180
+ #: app/features/events.php:2567 app/features/events.php:2678
2181
  #: app/features/fes/form.php:347 app/features/fes/form.php:360
2182
  msgid "Inherit from global options"
2183
  msgstr "Zdědí z globálních možností"
2239
  msgstr "Opakování"
2240
 
2241
  #: app/features/events.php:770 app/features/fes/form.php:390
2242
+ #: app/features/mec.php:1548 app/skins/default_full_calendar/tpl.php:79
2243
  #: app/skins/full_calendar/tpl.php:140
2244
  msgid "Daily"
2245
  msgstr "Děnně"
2263
  msgstr "Týdně"
2264
 
2265
  #: app/features/events.php:805 app/features/fes/form.php:395
2266
+ #: app/features/mec.php:1549 app/skins/default_full_calendar/tpl.php:77
2267
  #: app/skins/full_calendar/tpl.php:138
2268
  msgid "Monthly"
2269
  msgstr "Měsíčně"
2270
 
2271
  #: app/features/events.php:812 app/features/fes/form.php:396
2272
+ #: app/features/mec.php:1550 app/skins/default_full_calendar/tpl.php:76
2273
  #: app/skins/full_calendar/tpl.php:137
2274
  msgid "Yearly"
2275
  msgstr "Ročně"
2303
  msgstr "Pro verze doplňku Modern Events Calendar"
2304
 
2305
  #: app/features/events.php:860 app/features/events.php:2107
2306
+ #: app/features/events.php:2135 app/features/events.php:2349
2307
  #: app/features/fes/form.php:420 app/features/ix/import_f_calendar.php:42
2308
  #: app/features/ix/import_g_calendar.php:51
2309
  #: app/features/ix/import_meetup.php:40 app/features/ix/thirdparty.php:35
2313
 
2314
  #: app/features/events.php:874 app/features/events.php:1398
2315
  #: app/features/events.php:2091 app/features/events.php:2173
2316
+ #: app/features/events.php:2338 app/features/events.php:2382
2317
+ #: app/features/events.php:2455 app/features/events.php:2572
2318
  #: app/features/fes/form.php:451 app/features/fes/form.php:1070
2319
  #: app/features/occurrences.php:113 app/features/organizers.php:340
2320
  #: app/libraries/hourlyschedule.php:57 app/libraries/hourlyschedule.php:134
2341
  "datum zahájení a ukončení musí odpovídat počátečnímu datu."
2342
 
2343
  #: app/features/events.php:891 app/features/events.php:2111
2344
+ #: app/features/events.php:2139 app/features/events.php:2353
2345
  #: app/features/fes/form.php:436 app/libraries/skins.php:1356
2346
  msgid "End"
2347
  msgstr "Konec"
2402
  msgid "Show only one occurrence of this event"
2403
  msgstr "Další výskyt dalších událostí"
2404
 
2405
+ #: app/features/events.php:1277 app/features/events.php:4178
2406
  #: app/features/fes/form.php:865
2407
  #: app/features/mec/meta_boxes/search_form.php:116
2408
  #: app/features/mec/meta_boxes/search_form.php:204
2428
  #: app/features/mec/notifications.php:1628
2429
  #: app/features/mec/notifications.php:1778 app/features/mec/settings.php:860
2430
  #: app/features/notifications.php:160 app/features/occurrences.php:508
2431
+ #: app/libraries/main.php:7456 app/libraries/main.php:7503
2432
  #: app/widgets/single.php:101
2433
  msgid "Event Cost"
2434
  msgstr "Cena události"
2529
 
2530
  #: app/features/events.php:1507 app/features/events.php:1515
2531
  #: app/features/fes/form.php:831 app/features/mec/settings.php:1163
2532
+ #: app/features/occurrences.php:520 app/libraries/main.php:7454
2533
+ #: app/libraries/main.php:7501
2534
  msgid "Event Link"
2535
  msgstr "Odkaz na událost"
2536
 
2565
  msgstr "Více informací"
2566
 
2567
  #: app/features/events.php:1533 app/features/fes/form.php:840
2568
+ #: app/features/mec.php:1104 app/features/occurrences.php:529
2569
  #: app/features/popup/shortcode.php:481
2570
  msgid "Current Window"
2571
  msgstr "Aktuální okno"
2572
 
2573
  #: app/features/events.php:1534 app/features/fes/form.php:841
2574
+ #: app/features/mec.php:1105 app/features/occurrences.php:530
2575
  #: app/features/popup/shortcode.php:485
2576
  msgid "New Window"
2577
  msgstr "Nové okno"
2595
  msgid "Total User Booking Limits"
2596
  msgstr "Celkové limity rezervace uživatelů"
2597
 
2598
+ #: app/features/events.php:1566 app/features/events.php:2432
2599
  msgid "Fees"
2600
  msgstr "Poplatky"
2601
 
2602
+ #: app/features/events.php:1569 app/features/events.php:2562
2603
  #: app/features/mec/settings.php:1030
2604
  msgid "Ticket Variations / Options"
2605
  msgstr "Varianty vstupenky / možnosti"
2606
 
2607
+ #: app/features/events.php:1573 app/features/mec/booking.php:1063
2608
  #: app/features/mec/support-page.php:118
2609
  msgid "Organizer Payment"
2610
  msgstr "Platba organizátora"
2611
 
2612
  #: app/features/events.php:1581 app/features/ix/export.php:58
2613
+ #: app/libraries/main.php:7438
2614
  msgid "Bookings"
2615
  msgstr "Rezervace"
2616
 
2621
  msgstr "Celkové limity rezervace"
2622
 
2623
  #: app/features/events.php:1659 app/features/events.php:2057
2624
+ #: app/features/events.php:2304 app/modules/booking/default.php:116
2625
  #: app/modules/booking/default.php:221
2626
  #: app/modules/booking/steps/tickets.php:168
2627
  #: app/modules/booking/steps/tickets.php:174
2723
  msgstr "Ověřovací email"
2724
 
2725
  #: app/features/events.php:1769 app/features/events.php:1779
2726
+ #: app/features/gateways.php:5972 app/features/mec/booking.php:210
2727
+ #: app/features/mec/booking.php:277 app/features/mec/booking.php:292
2728
+ #: app/features/mec/booking.php:374 app/features/mec/booking.php:1000
2729
+ #: app/features/mec/booking.php:1027
2730
  #: app/features/mec/meta_boxes/search_form.php:66
2731
  #: app/features/mec/meta_boxes/search_form.php:74
2732
  #: app/features/mec/meta_boxes/search_form.php:82
2863
  msgstr "Zakázaný"
2864
 
2865
  #: app/features/events.php:1770 app/features/events.php:1780
2866
+ #: app/features/gateways.php:5971 app/features/mec/booking.php:209
2867
+ #: app/features/mec/booking.php:276 app/features/mec/booking.php:293
2868
+ #: app/features/mec/booking.php:999 app/features/mec/booking.php:1028
2869
+ #: app/features/mec/modules.php:155 app/features/mec/settings.php:99
2870
+ #: app/features/popup/settings.php:357
2871
  msgid "Enabled"
2872
  msgstr "Povoleno"
2873
 
2963
  msgstr "Vstupenka"
2964
 
2965
  #: app/features/events.php:1950 app/features/events.php:2217
2966
+ #: app/features/events.php:4165 app/features/fes.php:280
2967
  #: app/features/labels.php:183 app/features/locations.php:266
2968
  #: app/features/organizers.php:207 app/features/speakers.php:285
2969
  msgid "ID"
2974
  msgstr "Název vstupenky"
2975
 
2976
  #: app/features/events.php:1962 app/features/events.php:2225
2977
+ #: app/features/events.php:4169 app/libraries/skins.php:1370
2978
  msgid "Start Time"
2979
  msgstr "Začátek"
2980
 
2981
  #: app/features/events.php:1976 app/features/events.php:2239
2982
+ #: app/features/events.php:4171 app/libraries/skins.php:1371
2983
  msgid "End Time"
2984
  msgstr "Konec"
2985
 
 
 
 
 
 
 
2986
  #: app/features/events.php:2000 app/features/events.php:2003
2987
  #: app/features/events.php:2259 app/features/events.php:2262
2988
  #: app/features/mec/settings.php:1012
3000
 
3001
  #: app/features/events.php:2013 app/features/events.php:2017
3002
  #: app/features/events.php:2115 app/features/events.php:2142
3003
+ #: app/features/events.php:2271 app/features/events.php:2274
3004
+ #: app/features/events.php:2355 app/features/events.php:4722
3005
  #: app/features/mec/booking.php:690 app/features/mec/booking.php:693
3006
  #: app/features/mec/booking.php:722 app/features/mec/booking.php:725
3007
  #: app/libraries/ticketVariations.php:43 app/libraries/ticketVariations.php:46
3009
  msgid "Price"
3010
  msgstr "Cena"
3011
 
3012
+ #: app/features/events.php:2018 app/features/events.php:2275
3013
  #, fuzzy
3014
  #| msgid "Insert 0 for free ticket. Only numbers please."
3015
  msgid ""
3018
  msgstr "Vložte 0 pro vstupenku zdarma. Prosím pouze čísla."
3019
 
3020
  #: app/features/events.php:2027 app/features/events.php:2032
3021
+ #: app/features/events.php:2283 app/features/events.php:2286
3022
  msgid "Price Label"
3023
  msgstr "Cenový štítek"
3024
 
3025
+ #: app/features/events.php:2033 app/features/events.php:2287
3026
  msgid "For showing on website. e.g. $15"
3027
  msgstr "Pro zobrazení na webu. např. 15 $"
3028
 
3029
+ #: app/features/events.php:2044 app/features/events.php:2298
3030
  msgid "Available Tickets"
3031
  msgstr "Dostupné vstupenky"
3032
 
3033
+ #: app/features/events.php:2063 app/features/events.php:2310
3034
  #, fuzzy
3035
  #| msgid "Maximum Per Ticket"
3036
  msgid "Minimum Ticket e.g. 3"
3037
  msgstr "Maximum na jednu vstupenku"
3038
 
3039
+ #: app/features/events.php:2066 app/features/events.php:2313
3040
  #, fuzzy
3041
  #| msgid "Maximum Per Ticket"
3042
  msgid "MinimumTicket"
3043
  msgstr "Maximum na jednu vstupenku"
3044
 
3045
+ #: app/features/events.php:2068 app/features/events.php:2315
3046
  msgid "Set a number for the minimum ticket reservation possible"
3047
  msgstr ""
3048
 
3049
+ #: app/features/events.php:2077 app/features/events.php:2324
3050
  msgid "e.g. 0"
3051
  msgstr ""
3052
 
3053
+ #: app/features/events.php:2079 app/features/events.php:2326
3054
  #, fuzzy
3055
  #| msgid "Days"
3056
  msgid "Day"
3057
  msgstr "Dny"
3058
 
3059
+ #: app/features/events.php:2080 app/features/events.php:2327
3060
  #: app/features/mec/notifications.php:1734
3061
  msgid "Hour"
3062
  msgstr ""
3063
 
3064
+ #: app/features/events.php:2082 app/features/events.php:2329
3065
  #, php-format
3066
  msgid "Stop selling ticket %s before event start."
3067
  msgstr ""
3068
 
3069
+ #: app/features/events.php:2089 app/features/events.php:2336
3070
  msgid "Price per Date"
3071
  msgstr "Cena za datum"
3072
 
3073
  #: app/features/events.php:2119 app/features/events.php:2145
3074
+ #: app/features/events.php:2357 app/features/labels.php:60
3075
  #: app/features/mec/meta_boxes/display_options.php:1658
3076
  #: app/features/mec/meta_boxes/search_form.php:101
3077
  #: app/features/mec/meta_boxes/search_form.php:189
3093
  msgid "Label"
3094
  msgstr "Štítek"
3095
 
3096
+ #: app/features/events.php:2163 app/features/events.php:2372
3097
  #, fuzzy
3098
  #| msgid "Maximum Per Ticket"
3099
  msgid "Variations Per Ticket"
3100
  msgstr "Maximum na jednu vstupenku"
3101
 
3102
+ #: app/features/events.php:2168 app/features/events.php:2377
3103
  #, fuzzy
3104
  #| msgid "Inherit from global options"
3105
  msgid "Inherit from event options"
3106
  msgstr "Zdědí z globálních možností"
3107
 
3108
+ #: app/features/events.php:2469 app/features/events.php:2508
3109
  #: app/features/mec/booking.php:590 app/features/mec/booking.php:620
3110
  msgid "Fee Title"
3111
  msgstr "Název poplatku"
3112
 
3113
+ #: app/features/events.php:2475 app/features/events.php:2479
3114
+ #: app/features/events.php:2513 app/features/events.php:2516
3115
+ #: app/features/gateways.php:3419 app/features/mec/booking.php:594
3116
+ #: app/features/mec/booking.php:597 app/features/mec/booking.php:624
3117
+ #: app/features/mec/booking.php:627
3118
  msgid "Amount"
3119
  msgstr "Množství"
3120
 
3121
+ #: app/features/events.php:2480 app/features/events.php:2517
3122
  #: app/features/mec/booking.php:598 app/features/mec/booking.php:628
3123
  msgid ""
3124
  "Fee amount, considered as fixed amount if you set the type to amount "
3127
  "Výše poplatku, je považovaná za pevnou částku, pokud nastavíte typ na částku "
3128
  "odpovídající procentuální hodnotě"
3129
 
3130
+ #: app/features/events.php:2489 app/features/events.php:2526
3131
+ #: app/features/gateways.php:3420 app/features/mec/booking.php:605
3132
+ #: app/features/mec/booking.php:635
3133
  msgid "Percent"
3134
  msgstr "Procent"
3135
 
3136
+ #: app/features/events.php:2490 app/features/events.php:2527
3137
  #: app/features/mec/booking.php:606 app/features/mec/booking.php:636
3138
  msgid "Amount (Per Ticket)"
3139
  msgstr "Částka (za vstupenku)"
3140
 
3141
+ #: app/features/events.php:2491 app/features/events.php:2528
3142
  #: app/features/mec/booking.php:607 app/features/mec/booking.php:637
3143
  #, fuzzy
3144
  #| msgid "Amount (Per Ticket)"
3145
  msgid "Amount (Per Date)"
3146
  msgstr "Částka (za vstupenku)"
3147
 
3148
+ #: app/features/events.php:2492 app/features/events.php:2529
3149
  #: app/features/mec/booking.php:608 app/features/mec/booking.php:638
3150
  msgid "Amount (Per Booking)"
3151
  msgstr "Částka (za rezervaci)"
3152
 
3153
+ #: app/features/events.php:2664
3154
  #, fuzzy
3155
  #| msgid ""
3156
  #| "You're translating an event so MEC will use the original event for "
3166
  "vstupenek a rezervace. Můžete přeložit pouze název a popis vstupenky. Prosím "
3167
  "definujte určité vstupenky, které jste definovali v původní události."
3168
 
3169
+ #: app/features/events.php:2690 app/features/mec/booking.php:758
3170
  #, fuzzy
3171
  #| msgid "Attendees Limit"
3172
  msgid "Per Attendee Fields"
3173
  msgstr "Limit účastníků"
3174
 
3175
+ #: app/features/events.php:2781 app/features/mec/booking.php:856
3176
  #, fuzzy
3177
  #| msgid "Required Field"
3178
  msgid "Fixed Fields"
3179
  msgstr "Požadovaná pole"
3180
 
3181
+ #: app/features/events.php:2893 app/features/events.php:4716
3182
  #: app/features/mec/settings.php:1036 app/features/profile/profile.php:65
3183
  #: app/libraries/main.php:3048 app/libraries/main.php:3293
3184
  msgid "Attendees"
3185
  msgstr "Účastníci"
3186
 
3187
+ #: app/features/events.php:2896 app/features/occurrences.php:104
3188
  #, fuzzy
3189
  #| msgid "Next Occurrence"
3190
  msgid "Occurrence"
3191
  msgstr "Další výskyt"
3192
 
3193
+ #: app/features/events.php:2897 app/features/mec.php:1764
3194
  #: app/features/occurrences.php:105
3195
  #, fuzzy
3196
  #| msgid "Next Occurrence"
3197
  msgid "Previous Occurrences"
3198
  msgstr "Další výskyt"
3199
 
3200
+ #: app/features/events.php:2902 app/features/mec.php:1774
3201
+ #: app/features/occurrences.php:110 app/modules/next-event/multiple.php:55
3202
  #, fuzzy
3203
  #| msgid "Next Occurrence"
3204
  msgid "Next Occurrences"
3205
  msgstr "Další výskyt"
3206
 
3207
+ #: app/features/events.php:3739 app/features/mec/meta_boxes/filter.php:199
3208
  #: app/features/mec/settings.php:517
3209
  msgid "Expired Events"
3210
  msgstr "Události vypršely"
3211
 
3212
+ #: app/features/events.php:3740 app/features/mec.php:1355
3213
+ #: app/features/mec/dashboard.php:249 app/features/mec/settings.php:516
3214
  msgid "Upcoming Events"
3215
  msgstr "Nadcházející události"
3216
 
3217
+ #: app/features/events.php:3760 app/features/events.php:3778
3218
+ #: app/features/events.php:3796 app/features/events.php:3814
3219
  #, php-format
3220
  msgid "Show all %s"
3221
  msgstr "Ukázat všechny %s"
3222
 
3223
+ #: app/features/events.php:3760
3224
  msgid "labels"
3225
  msgstr "štítky"
3226
 
3227
+ #: app/features/events.php:3778
3228
  msgid "locations"
3229
  msgstr "umístění"
3230
 
3231
+ #: app/features/events.php:3796
3232
  msgid "organizers"
3233
  msgstr "organizátoři"
3234
 
3235
+ #: app/features/events.php:3830
3236
  #, fuzzy
3237
  #| msgid "Attendees Limit"
3238
  msgid "Attendees List"
3239
  msgstr "Limit účastníků"
3240
 
3241
+ #: app/features/events.php:3865
 
 
 
 
 
 
 
 
 
 
3242
  #, fuzzy
3243
  #| msgid "Tickets"
3244
  msgid "Sold Tickets"
3245
  msgstr "Vstupenky"
3246
 
3247
+ #: app/features/events.php:3867
3248
  msgid "Repeat"
3249
  msgstr "Opakovat"
3250
 
3251
+ #: app/features/events.php:4036 app/features/events.php:4037
3252
  #, fuzzy
3253
  #| msgid "iCal Export"
3254
  msgid "iCal / Outlook Export"
3255
  msgstr "iCal Export"
3256
 
3257
+ #: app/features/events.php:4039 app/features/events.php:4040
3258
  msgid "CSV Export"
3259
  msgstr "CSV Export"
3260
 
3261
+ #: app/features/events.php:4042 app/features/events.php:4043
3262
  msgid "MS Excel Export"
3263
  msgstr "MS Excel Export"
3264
 
3265
+ #: app/features/events.php:4045 app/features/events.php:4046
3266
  msgid "XML Export"
3267
  msgstr "XML Export"
3268
 
3269
+ #: app/features/events.php:4048 app/features/events.php:4049
3270
  msgid "JSON Export"
3271
  msgstr "JSON Export"
3272
 
3273
+ #: app/features/events.php:4051 app/features/events.php:4052
3274
+ #: app/features/events.php:4278
3275
  msgid "Duplicate"
3276
  msgstr "Duplikát"
3277
 
3278
+ #: app/features/events.php:4172
3279
  msgid "Link"
3280
  msgstr "Odkaz"
3281
 
3282
+ #: app/features/events.php:4174 app/features/locations.php:111
3283
  #: app/features/locations.php:181 app/features/locations.php:268
3284
  #: app/features/mec/meta_boxes/search_form.php:108
3285
  #: app/features/mec/meta_boxes/search_form.php:196
3297
  msgid "Address"
3298
  msgstr "Adresa"
3299
 
3300
+ #: app/features/events.php:4176
3301
  #, php-format
3302
  msgid "%s Tel"
3303
  msgstr "%s Tel"
3304
 
3305
+ #: app/features/events.php:4177
3306
  #, php-format
3307
  msgid "%s Email"
3308
  msgstr "%s Email"
3309
 
3310
  # v kontextu
3311
+ #: app/features/events.php:4179 app/features/fes/form.php:951
3312
  #: app/features/mec/settings.php:866
3313
  msgid "Featured Image"
3314
  msgstr "Hlavní obrázek"
3315
 
3316
+ #: app/features/events.php:4182 app/features/fes/form.php:1044
3317
+ #: app/features/mec.php:513 app/features/mec/meta_boxes/filter.php:73
3318
  #: app/features/mec/meta_boxes/filter.php:153 app/features/tag.php:59
3319
  msgid "Tags"
3320
  msgstr "Tagy"
3321
 
3322
+ #: app/features/events.php:4186 app/features/fes/form.php:1066
3323
+ #: app/features/mec.php:522 app/features/mec/modules.php:34
3324
  #: app/features/mec/modules.php:43 app/features/mec/settings.php:937
3325
  #: app/features/popup/settings.php:299 app/features/speakers.php:61
3326
  #: app/libraries/hourlyschedule.php:77 app/libraries/hourlyschedule.php:105
3327
  #: app/libraries/hourlyschedule.php:157 app/libraries/main.php:659
3328
+ #: app/libraries/main.php:7418 app/libraries/main.php:7479
3329
  #: app/modules/speakers/details.php:18
3330
  msgid "Speakers"
3331
  msgstr "Řečníci"
3332
 
3333
+ #: app/features/events.php:4429 app/features/fes.php:280
3334
+ #: app/features/gateways.php:3426 app/features/profile/profile.php:209
3335
+ #: app/libraries/cart.php:64 app/libraries/main.php:3064
3336
+ #: app/libraries/main.php:3310 app/libraries/main.php:7444
3337
  msgid "Ticket"
3338
  msgstr "Vstupenka"
3339
 
3340
+ #: app/features/events.php:4432 app/features/profile/profile.php:212
3341
  msgid "Variations"
3342
  msgstr "Variace"
3343
 
3344
+ #: app/features/events.php:4447 app/features/fes.php:356
3345
  msgid "Unknown"
3346
  msgstr "Neznámý"
3347
 
3348
+ #: app/features/events.php:4475
3349
  msgid ""
3350
  "If you want to send an email, first select your attendees and then click in "
3351
  "the button below, please."
3352
  msgstr ""
3353
 
3354
+ #: app/features/events.php:4475 app/features/mec/report.php:57
3355
  #, fuzzy
3356
  #| msgid "Organizer Email"
3357
  msgid "Send Email"
3358
  msgstr "Organizátor Email"
3359
 
3360
+ #: app/features/events.php:4479
3361
  #, fuzzy
3362
  #| msgid "Attendees Form"
3363
  msgid "No Attendees Found!"
3364
  msgstr "Formulář účastníků"
3365
 
3366
+ #: app/features/events.php:4777
3367
  #, fuzzy
3368
  #| msgid "No bookings found!"
3369
  msgid "No Bookings Found!"
3427
  msgid "Total Price"
3428
  msgstr "Celková cena"
3429
 
3430
+ #: app/features/fes.php:280 app/features/gateways.php:189
3431
+ #: app/libraries/main.php:3122 app/libraries/main.php:3369
3432
  #, fuzzy
3433
  #| msgid "Payment Gateways"
3434
  msgid "Gateway"
3502
  msgid "Please select at-least one label!"
3503
  msgstr "Vyberte události, které chcete importovat!"
3504
 
3505
+ #: app/features/fes.php:1376
3506
  #, fuzzy
3507
  #| msgid "The event submitted. It will publish as soon as possible."
3508
  msgid "Event submitted. It will publish as soon as possible."
3509
  msgstr "Událost byla odeslána. Zveřejní se co nejdříve."
3510
 
3511
+ #: app/features/fes.php:1377
3512
  msgid "The event published."
3513
  msgstr "Událost byla publikována."
3514
 
3682
  msgid "No events found! %s"
3683
  msgstr "Nebyly nalezeny žádné události! %s"
3684
 
3685
+ #: app/features/gateways.php:348
3686
+ #, fuzzy, php-format
3687
+ #| msgid ""
3688
+ #| "The %s ticket is sold out. You can try another ticket or another date."
3689
+ msgid ""
3690
+ "%s ticket is sold out! Please go back and select another ticket if available."
3691
+ msgstr ""
3692
+ "Vstupenka %s je vyprodána. Můžete vyzkoušet jinou vstupenku nebo jiné datum."
3693
+
3694
+ #: app/features/gateways.php:349 app/features/wc.php:212
3695
+ #: app/features/wc.php:238
3696
+ #, php-format
3697
+ msgid "Only %s slots remained for %s ticket so you cannot book %s ones."
3698
+ msgstr ""
3699
+
3700
+ #: app/features/gateways.php:370
3701
+ #, fuzzy, php-format
3702
+ #| msgid "Transaction ID"
3703
+ msgid "MEC Transaction ID: %s, Event Title: %s"
3704
+ msgstr "ID transakce"
3705
+
3706
+ #: app/features/gateways.php:417
3707
+ #, fuzzy, php-format
3708
+ #| msgid ""
3709
+ #| "The %s ticket is sold out. You can try another ticket or another date."
3710
+ msgid ""
3711
+ "%s Transaction: %s ticket is sold out! Please remove it and book another "
3712
+ "ticket if available."
3713
+ msgstr ""
3714
+ "Vstupenka %s je vyprodána. Můžete vyzkoušet jinou vstupenku nebo jiné datum."
3715
+
3716
+ #: app/features/gateways.php:418
3717
+ #, php-format
3718
+ msgid ""
3719
+ "%s Transaction: Only %s slots remained for %s ticket so you cannot book %s "
3720
+ "ones."
3721
+ msgstr ""
3722
+
3723
+ #: app/features/gateways.php:514
3724
+ #, fuzzy
3725
+ #| msgid ""
3726
+ #| "Thanks for your booking. Your tickets booked, booking verification might "
3727
+ #| "be needed, please check your email."
3728
+ msgid ""
3729
+ "Thank you for your booking. Your bookings are made, booking verification "
3730
+ "might be needed, please check your email."
3731
+ msgstr ""
3732
+ "Děkujeme za vaši rezervaci. Vaše vstupenky jsou rezervovány, může být nutné "
3733
+ "ověřit rezervaci. Zkontrolujte prosím svůj e-mail."
3734
+
3735
+ #: app/features/gateways.php:515 app/features/gateways.php:1149
3736
+ #: app/features/gateways.php:1218 app/features/gateways.php:2025
3737
+ #: app/features/gateways.php:3061 app/features/gateways.php:3130
3738
+ #: app/features/gateways.php:3720 app/features/gateways.php:4216
3739
+ #: app/features/gateways.php:4912 app/features/gateways.php:5453
3740
+ #: app/features/gateways.php:5856 app/features/gateways.php:6218
3741
+ #: app/features/gateways.php:6382 app/libraries/book.php:1104
3742
+ #: app/modules/booking/default.php:665 app/modules/booking/default.php:778
3743
+ msgid "Download Invoice"
3744
+ msgstr "Stáhnout fakturu"
3745
+
3746
+ #: app/features/gateways.php:569 app/features/gateways.php:1404
3747
+ msgid "Stripe"
3748
+ msgstr ""
3749
+
3750
+ #: app/features/gateways.php:615 app/features/gateways.php:2473
3751
+ #: app/features/gateways.php:3799 app/features/gateways.php:4303
3752
+ #: app/features/gateways.php:5048 app/features/gateways.php:5697
3753
+ #: app/features/gateways.php:6143 app/features/gateways.php:6462
3754
+ #, fuzzy
3755
+ #| msgid "There is no skins"
3756
+ msgid "There is no attendee for booking!"
3757
+ msgstr "Neexistuje žádný vzhled"
3758
+
3759
+ #: app/features/gateways.php:764 app/features/gateways.php:2024
3760
+ #: app/features/gateways.php:2621 app/features/gateways.php:3874
3761
+ #: app/features/gateways.php:4428 app/features/gateways.php:4679
3762
+ #: app/features/gateways.php:5138 app/features/gateways.php:5452
3763
+ #: app/features/gateways.php:5788 app/features/gateways.php:6013
3764
+ #: app/features/gateways.php:6217 app/features/gateways.php:6537
3765
+ #: app/libraries/main.php:7439
3766
+ #, fuzzy
3767
+ #| msgid ""
3768
+ #| "Thanks for your booking. Your tickets booked, booking verification might "
3769
+ #| "be needed, please check your email."
3770
+ msgid ""
3771
+ "Thank you for booking. Your tickets are booked, booking verification might "
3772
+ "be needed, please check your email."
3773
+ msgstr ""
3774
+ "Děkujeme za vaši rezervaci. Vaše vstupenky jsou rezervovány, může být nutné "
3775
+ "ověřit rezervaci. Zkontrolujte prosím svůj e-mail."
3776
+
3777
+ #: app/features/gateways.php:793 app/features/gateways.php:1824
3778
+ #: app/features/gateways.php:2655
3779
+ msgid "Your payment needs to be confirmed!"
3780
+ msgstr ""
3781
+
3782
+ #: app/features/gateways.php:794 app/features/gateways.php:831
3783
+ #: app/features/gateways.php:1825 app/features/gateways.php:1863
3784
+ #: app/features/gateways.php:2656 app/features/gateways.php:2708
3785
+ #, fuzzy
3786
+ #| msgid "Unknown"
3787
+ msgid "Unknown Error!"
3788
+ msgstr "Neznámý"
3789
+
3790
+ #: app/features/gateways.php:1155 app/features/gateways.php:1224
3791
+ #: app/features/gateways.php:3067 app/features/gateways.php:3136
3792
+ #: app/features/gateways.php:3726 app/features/gateways.php:4222
3793
+ #: app/features/gateways.php:4918 app/features/gateways.php:5862
3794
+ #: app/features/gateways.php:6219 app/features/gateways.php:6388
3795
+ #, fuzzy
3796
+ #| msgid "Download ICS file"
3797
+ msgid "Download File"
3798
+ msgstr "Stáhnout ICS soubor"
3799
+
3800
+ #: app/features/gateways.php:1294 app/features/gateways.php:1537
3801
+ #: app/features/gateways.php:3205
3802
+ msgid "Credit or debit card"
3803
+ msgstr ""
3804
+
3805
+ #: app/features/gateways.php:1306 app/features/gateways.php:1385
3806
+ #: app/features/gateways.php:1549 app/features/gateways.php:1756
3807
+ #: app/features/gateways.php:3217 app/features/gateways.php:3307
3808
+ #: app/features/gateways.php:4275 app/features/gateways.php:4569
3809
+ #: app/features/gateways.php:5011 app/features/gateways.php:5298
3810
+ #, fuzzy
3811
+ #| msgid "day"
3812
+ msgid "Pay"
3813
+ msgstr "den"
3814
+
3815
+ #: app/features/gateways.php:1369 app/features/gateways.php:1740
3816
+ #: app/features/gateways.php:3292
3817
+ msgid "You should complete the payment by returning back to the website."
3818
+ msgstr ""
3819
+
3820
+ #: app/features/gateways.php:1378 app/features/gateways.php:1749
3821
+ #: app/features/gateways.php:3301
3822
+ msgid "iDEAL Bank"
3823
+ msgstr ""
3824
+
3825
+ #: app/features/gateways.php:1424 app/features/gateways.php:1430
3826
+ #: app/features/gateways.php:3349 app/features/gateways.php:3354
3827
+ #: app/features/gateways.php:3367 app/features/gateways.php:3646
3828
+ #: app/features/gateways.php:3652 app/features/gateways.php:4065
3829
+ #: app/features/gateways.php:4071 app/features/gateways.php:4812
3830
+ #: app/features/gateways.php:4818 app/features/gateways.php:5950
3831
+ #: app/features/gateways.php:5956 app/features/gateways.php:6308
3832
+ #: app/features/gateways.php:6314
3833
+ #, fuzzy
3834
+ #| msgid "Time Comment"
3835
+ msgid "Comment"
3836
+ msgstr "Časový komentář"
3837
+
3838
+ #: app/features/gateways.php:1427 app/features/gateways.php:3351
3839
+ #, fuzzy
3840
+ #| msgid "Description"
3841
+ msgid "Stripe Gateway Description"
3842
+ msgstr "Popis"
3843
+
3844
+ #: app/features/gateways.php:1431 app/features/gateways.php:3355
3845
+ #: app/features/gateways.php:3368 app/features/gateways.php:3653
3846
+ #: app/features/gateways.php:4072 app/features/gateways.php:4819
3847
+ #: app/features/gateways.php:5957 app/features/gateways.php:6315
3848
+ msgid "HTML allowed."
3849
+ msgstr ""
3850
+
3851
+ #: app/features/gateways.php:1440 app/features/gateways.php:3384
3852
+ #, fuzzy
3853
+ #| msgid "Date Method"
3854
+ msgid "Payment Method"
3855
+ msgstr "Metoda data"
3856
+
3857
+ #: app/features/gateways.php:1443 app/features/gateways.php:3387
3858
+ msgid "Credit Card"
3859
+ msgstr ""
3860
+
3861
+ #: app/features/gateways.php:1444 app/features/gateways.php:3388
3862
+ msgid "iDEAL"
3863
+ msgstr ""
3864
+
3865
+ #: app/features/gateways.php:1450 app/features/gateways.php:1490
3866
+ #: app/features/gateways.php:3399 app/features/mec/settings.php:685
3867
+ msgid "Secret Key"
3868
+ msgstr "Tajný klíč"
3869
+
3870
+ #: app/features/gateways.php:1459 app/features/gateways.php:1496
3871
+ #: app/features/gateways.php:3405
3872
+ msgid "Publishable Key"
3873
+ msgstr ""
3874
+
3875
+ #: app/features/gateways.php:1467 app/features/gateways.php:1472
3876
+ #: app/features/gateways.php:3452 app/features/gateways.php:3457
3877
+ #: app/features/gateways.php:3662 app/features/gateways.php:3667
3878
+ #: app/features/gateways.php:4110 app/features/gateways.php:4115
3879
+ #: app/features/gateways.php:4866 app/features/gateways.php:4871
3880
+ #: app/features/gateways.php:5986 app/features/gateways.php:5991
3881
+ #: app/features/gateways.php:6324 app/features/gateways.php:6329
3882
+ #, fuzzy
3883
+ #| msgid "Currency Position"
3884
+ msgid "Position"
3885
+ msgstr "Pozice měny"
3886
+
3887
+ #: app/features/gateways.php:1840
3888
+ #, fuzzy, php-format
3889
+ #| msgid "Transaction ID"
3890
+ msgid "Transaction IDs: %s"
3891
+ msgstr "ID transakce"
3892
+
3893
+ #: app/features/gateways.php:2225 app/features/gateways.php:3328
3894
+ #, fuzzy
3895
+ #| msgid "Set Up WooCommerce Gateway"
3896
+ msgid "Stripe Connect"
3897
+ msgstr "Nastavit bránu WooCommerce"
3898
+
3899
+ #: app/features/gateways.php:3337
3900
+ msgid ""
3901
+ "Using this gateway, booking fee goes to the organizer account directly but "
3902
+ "you can get your fee in your Stripe account."
3903
+ msgstr ""
3904
+
3905
+ #: app/features/gateways.php:3338
3906
+ msgid ""
3907
+ "If organizer connects their account, then it will be the only enabled "
3908
+ "gateway for organizer events even if other gateways are enabled. Organizer "
3909
+ "Payment Module must be enabled to use this!"
3910
+ msgstr ""
3911
+
3912
+ #: app/features/gateways.php:3339
3913
+ #, fuzzy, php-format
3914
+ #| msgid "You should set %s as redirect page in Google App Console."
3915
+ msgid "You should set %s as Redirect URL in your Stripe dashboard."
3916
+ msgstr ""
3917
+ "V aplikaci Google App Console byste měli nastavit % s jako stránku "
3918
+ "přesměrování."
3919
+
3920
+ #: app/features/gateways.php:3362
3921
+ #, fuzzy
3922
+ #| msgid "Event Organizer"
3923
+ msgid "Comment for Organizer"
3924
+ msgstr "Organizátor události"
3925
+
3926
+ #: app/features/gateways.php:3375
3927
+ #, fuzzy
3928
+ #| msgid "Countdown View"
3929
+ msgid "Connection Method"
3930
+ msgstr "Zobrazení odpočítávání"
3931
+
3932
+ #: app/features/gateways.php:3378
3933
+ #: app/features/mec/meta_boxes/display_options.php:51
3934
+ #: app/features/mec/settings.php:404 app/features/mec/settings.php:481
3935
+ #: app/features/popup/settings.php:131 app/features/popup/shortcode.php:85
3936
+ msgid "Standard"
3937
+ msgstr "Standardní"
3938
+
3939
+ #: app/features/gateways.php:3379
3940
+ msgid "Express"
3941
+ msgstr ""
3942
+
3943
+ #: app/features/gateways.php:3393
3944
+ #, fuzzy
3945
+ #| msgid "App Client ID"
3946
+ msgid "Client ID"
3947
+ msgstr "ID klienta aplikace"
3948
+
3949
+ #: app/features/gateways.php:3411
3950
+ msgid "Your Fee"
3951
+ msgstr ""
3952
+
3953
+ #: app/features/gateways.php:3418
3954
+ #, fuzzy
3955
+ #| msgid "Select Type"
3956
+ msgid "Fee Type"
3957
+ msgstr "Vyberte typ"
3958
+
3959
+ #: app/features/gateways.php:3424
3960
+ #, fuzzy
3961
+ #| msgid "Percent"
3962
+ msgid "Per"
3963
+ msgstr "Procent"
3964
+
3965
+ #: app/features/gateways.php:3434 app/features/gateways.php:3444
3966
+ #, fuzzy
3967
+ #| msgid "Get Directions"
3968
+ msgid "Redirection Page"
3969
+ msgstr "Získat směr"
3970
+
3971
+ #: app/features/gateways.php:3445
3972
+ msgid ""
3973
+ "Users will redirect to this page after connecting to your Stripe account. "
3974
+ "You can create a page to thank them. If you leave it empty then users will "
3975
+ "redirect to home page!"
3976
+ msgstr ""
3977
+
3978
+ #: app/features/gateways.php:3506 app/features/gateways.php:3513
3979
+ msgid "Connect New Account"
3980
+ msgstr ""
3981
+
3982
+ #: app/features/gateways.php:3506
3983
+ msgid "Connect"
3984
+ msgstr ""
3985
+
3986
+ #: app/features/gateways.php:3509 app/features/gateways.php:3516
3987
+ msgid ""
3988
+ "You're connected to our account successfully and you will receive payments "
3989
+ "in your stripe account directly after deducting the fees."
3990
+ msgstr ""
3991
+
3992
+ #: app/features/gateways.php:3510
3993
+ #, fuzzy
3994
+ #| msgid "Login to Dashboard"
3995
+ msgid "Visit your dashboard"
3996
+ msgstr "Přihlásit se do řídícímu panelu"
3997
+
3998
+ #: app/features/gateways.php:3513
3999
+ msgid "Connect Your Account"
4000
+ msgstr ""
4001
+
4002
+ #: app/features/gateways.php:3560 app/features/gateways.php:4422
4003
+ #: app/features/gateways.php:4673 app/features/gateways.php:6008
4004
+ msgid "Waiting for a response from gateway."
4005
+ msgstr ""
4006
+
4007
+ #: app/features/gateways.php:3568
4008
+ #, fuzzy
4009
+ #| msgid "The events are imported successfully!"
4010
+ msgid "User connected successfully!"
4011
+ msgstr "Události byly úspěšně importovány!"
4012
+
4013
+ #: app/features/gateways.php:3604 app/features/gateways.php:3625
4014
+ msgid "Pay Locally"
4015
+ msgstr ""
4016
+
4017
+ #: app/features/gateways.php:3649
4018
+ #, fuzzy
4019
+ #| msgid "Geo latitude (Optional)"
4020
+ msgid "Pay Locally Description"
4021
+ msgstr "Zeměpisná šířka (volitelné)"
4022
+
4023
+ #: app/features/gateways.php:3674 app/features/gateways.php:6336
4024
+ #, fuzzy
4025
+ #| msgid "Confirmation"
4026
+ msgid "Disable Auto Confirmation"
4027
+ msgstr "Potvrzení"
4028
+
4029
+ #: app/features/gateways.php:3762 app/features/gateways.php:3895
4030
+ #: app/features/gateways.php:6425 app/features/gateways.php:6558
4031
+ #: app/modules/booking/steps/form.php:385
4032
+ msgid "Submit"
4033
+ msgstr "Potvrdit"
4034
+
4035
+ #: app/features/gateways.php:3996 app/features/gateways.php:4044
4036
+ msgid "PayPal Express"
4037
+ msgstr ""
4038
+
4039
+ #: app/features/gateways.php:4015 app/features/gateways.php:4020
4040
+ #: app/features/gateways.php:4082 app/features/gateways.php:4089
4041
+ msgid "Business Account"
4042
+ msgstr ""
4043
+
4044
+ #: app/features/gateways.php:4021 app/features/gateways.php:4090
4045
+ msgid "Normally PayPal Email."
4046
+ msgstr ""
4047
+
4048
+ #: app/features/gateways.php:4068
4049
+ #, fuzzy
4050
+ #| msgid "Description"
4051
+ msgid "Paypal Express Description"
4052
+ msgstr "Popis"
4053
+
4054
+ #: app/features/gateways.php:4100 app/features/gateways.php:4856
4055
+ #, fuzzy
4056
+ #| msgid "Modern"
4057
+ msgid "Mode"
4058
+ msgstr "Moderní"
4059
+
4060
+ #: app/features/gateways.php:4104 app/features/gateways.php:4860
4061
+ msgid "Live"
4062
+ msgstr ""
4063
+
4064
+ #: app/features/gateways.php:4105 app/features/gateways.php:4861
4065
+ msgid "Sandbox"
4066
+ msgstr ""
4067
+
4068
+ #: app/features/gateways.php:4287 app/features/gateways.php:4642
4069
+ #, fuzzy
4070
+ #| msgid "Get Directions"
4071
+ msgid "Ready to checkout."
4072
+ msgstr "Získat směr"
4073
+
4074
+ #: app/features/gateways.php:4445 app/features/gateways.php:4684
4075
+ #: app/features/gateways.php:6021
4076
+ #, fuzzy
4077
+ #| msgid "Invoice is invalid."
4078
+ msgid "Payment invalid! Booking failed."
4079
+ msgstr "Faktura je neplatná."
4080
+
4081
+ #: app/features/gateways.php:4717 app/features/gateways.php:4786
4082
+ msgid "PayPal Credit Card"
4083
+ msgstr ""
4084
+
4085
+ #: app/features/gateways.php:4751 app/features/gateways.php:4829
4086
+ msgid "API Username"
4087
+ msgstr ""
4088
+
4089
+ #: app/features/gateways.php:4757 app/features/gateways.php:4838
4090
+ msgid "API Password"
4091
+ msgstr ""
4092
+
4093
+ #: app/features/gateways.php:4763 app/features/gateways.php:4847
4094
+ msgid "API Signature"
4095
+ msgstr ""
4096
+
4097
+ #: app/features/gateways.php:4796
4098
+ msgid ""
4099
+ "Below error is the latest error received from Paypal during the payment in "
4100
+ "frontend so it's not related to the configuration form. It might help you to "
4101
+ "find some misconfiguration on your Paypal account or inserted credentials."
4102
+ msgstr ""
4103
+
4104
+ #: app/features/gateways.php:4815
4105
+ #, fuzzy
4106
+ #| msgid "Description"
4107
+ msgid "Paypal Credit Card Description"
4108
+ msgstr "Popis"
4109
+
4110
+ #: app/features/gateways.php:4965 app/features/gateways.php:5252
4111
+ #, fuzzy
4112
+ #| msgid "Ticket name"
4113
+ msgid "First name"
4114
+ msgstr "Název vstupenky"
4115
+
4116
+ #: app/features/gateways.php:4969 app/features/gateways.php:5256
4117
+ #, fuzzy
4118
+ #| msgid "Last Year"
4119
+ msgid "Last name"
4120
+ msgstr "Minulý rok"
4121
+
4122
+ #: app/features/gateways.php:4973 app/features/gateways.php:5260
4123
+ #, fuzzy
4124
+ #| msgid "Modern Type"
4125
+ msgid "Card Type"
4126
+ msgstr "Moderní typ"
4127
+
4128
+ #: app/features/gateways.php:4975 app/features/gateways.php:5262
4129
+ msgid "Visa"
4130
+ msgstr ""
4131
+
4132
+ #: app/features/gateways.php:4976 app/features/gateways.php:5263
4133
+ msgid "MasterCard"
4134
+ msgstr ""
4135
+
4136
+ #: app/features/gateways.php:4977 app/features/gateways.php:5264
4137
+ #, fuzzy
4138
+ #| msgid "Discount"
4139
+ msgid "Discover"
4140
+ msgstr "Sleva"
4141
+
4142
+ #: app/features/gateways.php:4978 app/features/gateways.php:5265
4143
+ #, fuzzy
4144
+ #| msgid "Event Speakers"
4145
+ msgid "American Express"
4146
+ msgstr "Řečník události"
4147
+
4148
+ #: app/features/gateways.php:4982 app/features/gateways.php:5269
4149
+ msgid "CC Number"
4150
+ msgstr ""
4151
+
4152
+ #: app/features/gateways.php:4986 app/features/gateways.php:5273
4153
+ #, fuzzy
4154
+ #| msgid "Exceptional Days"
4155
+ msgid "Expiration Date"
4156
+ msgstr "Výjimečné dny"
4157
+
4158
+ #: app/features/gateways.php:5003 app/features/gateways.php:5290
4159
+ msgid "CVV2"
4160
+ msgstr ""
4161
+
4162
+ #: app/features/gateways.php:5063 app/features/gateways.php:5371
4163
+ #, fuzzy
4164
+ #| msgid "Invoice is invalid."
4165
+ msgid "Payment is invalid."
4166
+ msgstr "Faktura je neplatná."
4167
+
4168
+ #: app/features/gateways.php:5508
4169
+ #, fuzzy, php-format
4170
+ #| msgid "Transaction ID"
4171
+ msgid "Transactions: %s"
4172
+ msgstr "ID transakce"
4173
+
4174
+ #: app/features/gateways.php:5582 app/features/gateways.php:5925
4175
+ #, fuzzy
4176
+ #| msgid "Set Up WooCommerce Gateway"
4177
+ msgid "Pay by WooCommerce"
4178
+ msgstr "Nastavit bránu WooCommerce"
4179
+
4180
+ #: app/features/gateways.php:5664
4181
+ #, fuzzy, php-format
4182
+ #| msgid "Booking Form"
4183
+ msgid "Booking fee for %s"
4184
+ msgstr "Rezervační formulář"
4185
+
4186
+ #: app/features/gateways.php:5677
4187
+ msgid "Order created. Please proceed with checkout."
4188
+ msgstr ""
4189
+
4190
+ #: app/features/gateways.php:5903 app/features/gateways.php:5907
4191
+ #: app/libraries/cart.php:71 app/libraries/wc.php:109
4192
+ #: app/modules/booking/steps/checkout.php:55
4193
+ msgid "Checkout"
4194
+ msgstr "Překontrolovat"
4195
+
4196
+ #: app/features/gateways.php:5936
4197
+ #, fuzzy
4198
+ #| msgid "Third Party plugin is not installed and activated!"
4199
+ msgid "WooCommerce must be installed and activated first."
4200
+ msgstr "Plugin třetích stran není nainstalován a aktivován!"
4201
+
4202
+ #: app/features/gateways.php:5953
4203
+ #, fuzzy
4204
+ #| msgid "Set Up WooCommerce Gateway"
4205
+ msgid "WooCommerce Gateway Description"
4206
+ msgstr "Nastavit bránu WooCommerce"
4207
+
4208
+ #: app/features/gateways.php:5967
4209
+ msgid "Automatically complete WC orders"
4210
+ msgstr ""
4211
+
4212
+ #: app/features/gateways.php:5976
4213
+ #, fuzzy
4214
+ #| msgid "WooCommerce gateways"
4215
+ msgid "Auto WC orders"
4216
+ msgstr "Brána WooCommerce"
4217
+
4218
+ #: app/features/gateways.php:5977 app/features/mec/booking.php:1005
4219
+ msgid "It applies only to the orders that are related to MEC."
4220
+ msgstr ""
4221
+
4222
+ #: app/features/gateways.php:6108 app/libraries/main.php:4424
4223
+ msgid "Free"
4224
+ msgstr "Zdarma"
4225
+
4226
+ #: app/features/gateways.php:6129
4227
+ #, fuzzy
4228
+ #| msgid "Your booking is confirmed."
4229
+ msgid "This booking is not free!"
4230
+ msgstr "Vaše rezervace je potvrzena."
4231
+
4232
+ #: app/features/gateways.php:6266 app/features/gateways.php:6287
4233
+ msgid "Bank Transfer"
4234
+ msgstr ""
4235
+
4236
+ #: app/features/gateways.php:6311
4237
+ #, fuzzy
4238
+ #| msgid "Description"
4239
+ msgid "Bank Transfer Description"
4240
+ msgstr "Popis"
4241
+
4242
  #: app/features/ix.php:108
4243
  msgid "MEC - Import / Export"
4244
  msgstr "MEC Import / Export"
4592
  msgid "Add to Google Calendar"
4593
  msgstr "Přidat do Google kalendáře"
4594
 
4595
+ #: app/features/ix/export_g_calendar.php:100 app/features/mec/booking.php:1253
4596
  #: app/features/mec/integrations.php:451 app/features/mec/modules.php:408
4597
  #: app/features/mec/notifications.php:1924 app/features/mec/settings.php:1601
4598
  #: app/features/mec/single.php:597
4711
  msgid "Import all of your Facebook events into MEC."
4712
  msgstr "Importujte všechny své události na Facebooku do MEC."
4713
 
4714
+ #: app/features/ix/import_f_calendar.php:27 app/features/mec/dashboard.php:127
4715
  #: app/features/mec/support-page.php:11 app/features/mec/support.php:100
4716
  msgid "Documentation"
4717
  msgstr "Dokumentace"
5104
  msgid "Event %s"
5105
  msgstr "Událost %s"
5106
 
5107
+ #: app/features/locations.php:59 app/features/mec.php:516
5108
+ #: app/features/mec/dashboard.php:231 app/features/mec/meta_boxes/filter.php:70
5109
+ #: app/features/mec/meta_boxes/filter.php:99 app/libraries/main.php:7414
5110
+ #: app/libraries/main.php:7475
5111
  msgid "Locations"
5112
  msgstr "Umístění"
5113
 
5224
  msgid "Don't show map in single event page"
5225
  msgstr "Nezobrazovat mapu na jednostránkové události"
5226
 
5227
+ #: app/features/locations.php:409 app/libraries/main.php:7459
5228
+ #: app/libraries/main.php:7506
5229
  msgid "Other Locations"
5230
  msgstr "Další místa"
5231
 
5254
  msgid "Forgot Password?"
5255
  msgstr ""
5256
 
5257
+ #: app/features/mec.php:217
5258
  #, fuzzy
5259
  #| msgid ""
5260
  #| "Activation faild. Please check your purchase code or license type."
5267
  "<br> <b> Poznámka: Váš nákupní kód by se měl shodovat s vaším typem licence. "
5268
  "</b>"
5269
 
5270
+ #: app/features/mec.php:217 app/features/mec/support-page.php:136
5271
  msgid "Troubleshooting"
5272
  msgstr "Odstraňování problémů"
5273
 
5274
+ #: app/features/mec.php:332
5275
  #, fuzzy
5276
  #| msgid "Select Type"
5277
  msgid "Select Date"
5278
  msgstr "Vyberte typ"
5279
 
5280
+ #: app/features/mec.php:336 app/skins/masonry.php:265
5281
  msgid "All"
5282
  msgstr "Vše"
5283
 
5284
+ #: app/features/mec.php:378
5285
  #, fuzzy
5286
  #| msgid ""
5287
  #| "Your options is not in JSON format. Please insert correct options in this "
5293
  "Vaše možnosti nejsou ve formátu JSON. Do tohoto pole vložte správné možnosti "
5294
  "a zkuste to znovu."
5295
 
5296
+ #: app/features/mec.php:385
5297
  msgid "Your options field can not be empty!"
5298
  msgstr "Pole možností nemůže být prázdné!"
5299
 
5300
+ #: app/features/mec.php:391
5301
  msgid "Your options imported successfuly."
5302
  msgstr "Vaše možnosti byly úspěšně importovány."
5303
 
5304
+ #: app/features/mec.php:496
5305
  msgid "MEC - Support"
5306
  msgstr "MEC - podpora"
5307
 
5308
+ #: app/features/mec.php:496 app/features/mec/support-page.php:9
5309
  #: app/features/mec/support.php:80 app/features/mec/support.php:93
5310
  msgid "Support"
5311
  msgstr "Podpora"
5312
 
5313
+ #: app/features/mec.php:517 app/features/mec/dashboard.php:238
5314
  #: app/features/mec/meta_boxes/filter.php:71
5315
  #: app/features/mec/meta_boxes/filter.php:117 app/features/organizers.php:59
5316
+ #: app/libraries/main.php:7416 app/libraries/main.php:7477
5317
  msgid "Organizers"
5318
  msgstr "Organizátoři"
5319
 
5320
+ #: app/features/mec.php:526 app/features/mec.php:587
5321
+ #: app/features/mec/dashboard.php:224
5322
  msgid "Shortcodes"
5323
  msgstr "Zkrácené kódy"
5324
 
5325
+ #: app/features/mec.php:536
5326
  msgid "MEC - Settings"
5327
  msgstr "MEC - Nastavení"
5328
 
5329
+ #: app/features/mec.php:538
5330
  msgid "MEC - Addons"
5331
  msgstr "MEC - doplňky"
5332
 
5333
+ #: app/features/mec.php:538 app/features/mec/addons.php:11
5334
  msgid "Addons"
5335
  msgstr "Doplňky"
5336
 
5337
+ #: app/features/mec.php:539
5338
  msgid "MEC - Wizard"
5339
  msgstr ""
5340
 
5341
+ #: app/features/mec.php:539 app/features/mec/wizard.php:512
5342
  #: app/features/mec/wizard.php:517 app/features/mec/wizard.php:522
5343
  msgid "Wizard"
5344
  msgstr ""
5345
 
5346
+ #: app/features/mec.php:543
5347
  #, fuzzy
5348
  #| msgid "MEC - Support"
5349
  msgid "MEC - Report"
5350
  msgstr "MEC - podpora"
5351
 
5352
+ #: app/features/mec.php:543
5353
  #, fuzzy
5354
  #| msgid "Export"
5355
  msgid "Report"
5356
  msgstr "Export"
5357
 
5358
+ #: app/features/mec.php:546
5359
  #, fuzzy
5360
  #| msgid "MEC - Support"
5361
  msgid "MEC - Go Pro"
5362
  msgstr "MEC - podpora"
5363
 
5364
+ #: app/features/mec.php:546 app/features/mec.php:1426
5365
  #: app/features/mec/go-pro.php:9
5366
  msgid "Go Pro"
5367
  msgstr ""
5368
 
5369
+ #: app/features/mec.php:589 app/features/mec/wizard.php:516
5370
  msgid "Add Shortcode"
5371
  msgstr "Přidat zkrácený kód"
5372
 
5373
+ #: app/features/mec.php:590
5374
  msgid "Add New Shortcode"
5375
  msgstr "Přidat nový zkrácený kód"
5376
 
5377
+ #: app/features/mec.php:591
5378
  msgid "No shortcodes found!"
5379
  msgstr "Nebyly nalezeny žádné zkrácené kódy!"
5380
 
5381
+ #: app/features/mec.php:592
5382
  msgid "All Shortcodes"
5383
  msgstr "Všechny zkrácené kódy"
5384
 
5385
+ #: app/features/mec.php:593
5386
  msgid "Edit shortcodes"
5387
  msgstr "Editace zkrácených kódů"
5388
 
5389
+ #: app/features/mec.php:594
5390
  msgid "No shortcodes found in Trash!"
5391
  msgstr "V koši nebyly nalezeny žádné zkrácené kódy!"
5392
 
5393
+ #: app/features/mec.php:647
5394
  msgid "Display Options"
5395
  msgstr "Zobrazit možnosti"
5396
 
5397
+ #: app/features/mec.php:648
5398
  msgid "Filter Options"
5399
  msgstr "Filtrovat možnosti"
5400
 
5401
+ #: app/features/mec.php:650
5402
  msgid "Search Form"
5403
  msgstr "Vyhledávací formulář"
5404
 
5405
+ #: app/features/mec.php:1085
5406
  msgid "Display content's images as Popup"
5407
  msgstr "Zobrazit obrázky obsahu jako vyskakovací okno"
5408
 
5409
+ #: app/features/mec.php:1099 app/features/popup/shortcode.php:477
5410
  msgid "Single Event Display Method"
5411
  msgstr "Metoda zobrazení jedné události"
5412
 
5413
+ #: app/features/mec.php:1106 app/features/popup/shortcode.php:489
5414
  #, fuzzy
5415
  #| msgid "Modal 1"
5416
  msgid "Modal Popup"
5417
  msgstr "Modal 1"
5418
 
5419
+ #: app/features/mec.php:1107
5420
  #, fuzzy
5421
  #| msgid "Disabled"
5422
  msgid "Disable Link"
5423
  msgstr "Zakázaný"
5424
 
5425
+ #: app/features/mec.php:1117
5426
  msgid "Descending Order"
5427
  msgstr ""
5428
 
5429
+ #: app/features/mec.php:1133
5430
  #, fuzzy
5431
  #| msgid "Booking Options"
5432
  msgid "Booking Button / Icon"
5433
  msgstr "Možnosti rezervace"
5434
 
5435
+ #: app/features/mec.php:1146
5436
  #, fuzzy
5437
  #| msgid "Organizers"
5438
  msgid "Display Organizers"
5439
  msgstr "Organizátoři"
5440
 
5441
+ #: app/features/mec.php:1159
5442
  #, fuzzy
5443
  #| msgid "Custom Styles"
5444
  msgid "Display Custom Fields"
5445
  msgstr "Vlastní styly"
5446
 
5447
+ #: app/features/mec.php:1172
5448
  #, fuzzy
5449
  #| msgid "Date and Time"
5450
  msgid "Detailed Time"
5451
  msgstr "Datum a čas"
5452
 
5453
+ #: app/features/mec.php:1173
5454
  #, fuzzy
5455
  #| msgid "Multiple Day Events"
5456
  msgid "For Multiple Day Events"
5457
  msgstr "Vícedenní událost"
5458
 
5459
+ #: app/features/mec.php:1330 app/features/mec.php:1506
5460
  msgid "Total Bookings"
5461
  msgstr "Celkový počet rezervací"
5462
 
5463
+ #: app/features/mec.php:1346 app/features/mec/dashboard.php:57
5464
  msgid "Modern Events Calendar (Lite)"
5465
  msgstr "Modern Events Calendar (Lite)"
5466
 
5467
+ #: app/features/mec.php:1412
5468
  #, fuzzy
5469
  #| msgid "Update %s"
5470
  msgid "News & Updates"
5471
  msgstr "Aktualizovat %s"
5472
 
5473
+ #: app/features/mec.php:1425
5474
  msgid "Blog"
5475
  msgstr ""
5476
 
5477
+ #: app/features/mec.php:1425
5478
  msgid "Help"
5479
  msgstr ""
5480
 
5481
+ #: app/features/mec.php:1480
5482
  #, fuzzy, php-format
5483
  #| msgid "Total Sells (%s)"
5484
  msgid "Total Sales (%s)"
5485
  msgstr "Celkový prodej %s"
5486
 
5487
+ #: app/features/mec.php:1515
5488
  msgid "This Month"
5489
  msgstr "Tento měsíc"
5490
 
5491
+ #: app/features/mec.php:1521
5492
  msgid "Last Month"
5493
  msgstr "Minulý měsíc"
5494
 
5495
+ #: app/features/mec.php:1527
5496
  msgid "This Year"
5497
  msgstr "Tento rok"
5498
 
5499
+ #: app/features/mec.php:1533
5500
  msgid "Last Year"
5501
  msgstr "Minulý rok"
5502
 
5503
+ #: app/features/mec.php:1553
5504
  msgid "Bar"
5505
  msgstr "Pruh"
5506
 
5507
+ #: app/features/mec.php:1554
5508
  msgid "Line"
5509
  msgstr "Čára"
5510
 
5511
+ #: app/features/mec.php:1556 app/skins/general_calendar/tpl.php:145
5512
  msgid "Filter"
5513
  msgstr "Filtr"
5514
 
5515
+ #: app/features/mec.php:1580
5516
  #, fuzzy
5517
  #| msgid "Modern Events Calendar"
5518
  msgid "Print Calendar"
5519
  msgstr "Moderní kalendář událostí"
5520
 
5521
+ #: app/features/mec.php:1595
5522
  #, fuzzy
5523
  #| msgid "Display Event Price"
5524
  msgid "Display Events"
5525
  msgstr "Zobrazit cenu události"
5526
 
5527
+ #: app/features/mec.php:1642
5528
  #, fuzzy
5529
  #| msgid "Include Expired Events"
5530
  msgid "Include MEC Assets"
5531
  msgstr "Zahrnout uplynulé události"
5532
 
5533
+ #: app/features/mec.php:1653
5534
  msgid "Include Modern Events Calendar Assets (CSS, JavaScript, etc files.)"
5535
  msgstr ""
5536
 
5537
  #: app/features/mec/addons.php:16 app/features/mec/addons.php:62
5538
+ #: app/features/mec/dashboard.php:67 app/features/mec/go-pro.php:14
5539
  #: app/features/mec/report.php:21 app/features/mec/support-page.php:21
5540
  msgid "Version"
5541
  msgstr "Verze"
5562
  msgstr "Vyhledávání ..."
5563
 
5564
  #: app/features/mec/booking.php:72 app/features/mec/booking.php:906
5565
+ #: app/features/mec/booking.php:1103 app/features/mec/booking.php:1178
5566
+ #: app/features/mec/booking.php:1188 app/features/mec/booking.php:1270
5567
+ #: app/features/mec/booking.php:1284 app/features/mec/integrations.php:24
5568
  #: app/features/mec/integrations.php:400 app/features/mec/integrations.php:410
5569
  #: app/features/mec/integrations.php:468 app/features/mec/integrations.php:482
5570
  #: app/features/mec/messages.php:20 app/features/mec/messages.php:60
6023
  "Po povolení a uložení nastavení byste měli stránku znovu načíst a zobrazit "
6024
  "novou nabídku na řídícím panelu > Rezervace"
6025
 
6026
+ #: app/features/mec/booking.php:571 app/features/mec/booking.php:991
6027
  #: app/libraries/main.php:650
6028
  msgid "Taxes / Fees"
6029
  msgstr "Daně / poplatky"
6116
  "fields etc, you need to configure WooCommerce on your website."
6117
  msgstr ""
6118
 
6119
+ #: app/features/mec/booking.php:982
6120
+ msgid ""
6121
+ "Please disable MEC Cart first otherwise you're not able to use WooCommerce "
6122
+ "feature."
6123
+ msgstr ""
6124
+
6125
+ #: app/features/mec/booking.php:985
6126
  msgid ""
6127
  "You cannot use following MEC features so you should use WooCommerc and its "
6128
  "addons if you need them."
6129
  msgstr ""
6130
 
6131
+ #: app/features/mec/booking.php:987
6132
  #, fuzzy
6133
  #| msgid "Payment Gateways"
6134
  msgid "Payment gateways"
6135
  msgstr "Platební brány"
6136
 
6137
+ #: app/features/mec/booking.php:988
6138
  #, fuzzy
6139
  #| msgid "Price per Date"
6140
  msgid "Price per dates of tickets"
6141
  msgstr "Cena za datum"
6142
 
6143
+ #: app/features/mec/booking.php:990
6144
  #, fuzzy
6145
  #| msgid "Ticket Variations / Options"
6146
  msgid "Ticket variations"
6147
  msgstr "Varianty vstupenky / možnosti"
6148
 
6149
+ #: app/features/mec/booking.php:992
6150
  #, fuzzy
6151
  #| msgid "Discount"
6152
  msgid "Discount Per Roles"
6153
  msgstr "Sleva"
6154
 
6155
+ #: app/features/mec/booking.php:996
6156
  msgid "Automatically complete WooCommerce orders"
6157
  msgstr ""
6158
 
6159
+ #: app/features/mec/booking.php:1004
6160
  #, fuzzy
6161
  #| msgid "WooCommerce gateways"
6162
  msgid "Auto WooCommerce orders"
6163
  msgstr "Brána WooCommerce"
6164
 
6165
+ #: app/features/mec/booking.php:1013 app/features/mec/booking.php:1151
 
 
 
 
6166
  msgid "After Add to Cart"
6167
  msgstr ""
6168
 
6169
+ #: app/features/mec/booking.php:1016 app/features/mec/booking.php:1154
6170
  #, fuzzy
6171
  #| msgid "Get Directions"
6172
  msgid "Redirect to Cart"
6173
  msgstr "Získat směr"
6174
 
6175
+ #: app/features/mec/booking.php:1017 app/features/mec/booking.php:1155
6176
  #, fuzzy
6177
  #| msgid "Get Directions"
6178
  msgid "Redirect to Checkout"
6179
  msgstr "Získat směr"
6180
 
6181
+ #: app/features/mec/booking.php:1018 app/features/mec/booking.php:1156
6182
  #, fuzzy
6183
  #| msgid "View Detail Button"
6184
  msgid "Optional View Cart Button"
6185
  msgstr "Tlačítko Zobrazit detail"
6186
 
6187
+ #: app/features/mec/booking.php:1019 app/features/mec/booking.php:1157
6188
  msgid "Optional Checkout Button"
6189
  msgstr ""
6190
 
6191
+ #: app/features/mec/booking.php:1024
6192
  #, fuzzy
6193
  #| msgid "Booking Form"
6194
  msgid "MEC Booking Form"
6195
  msgstr "Rezervační formulář"
6196
 
6197
+ #: app/features/mec/booking.php:1033
6198
  msgid ""
6199
  "If enabled then users should fill the booking form in MEC and then they will "
6200
  "be redirected to checkout."
6201
  msgstr ""
6202
 
6203
+ #: app/features/mec/booking.php:1059
6204
  msgid "Enable Organizer Payment Module"
6205
  msgstr "Povolit platební modul organizátora"
6206
 
6207
+ #: app/features/mec/booking.php:1064
6208
  msgid ""
6209
  "By enabling this module, organizers are able to insert their own payment "
6210
  "credentials for enabled gateways per event and receive the payments directly!"
6212
  "Po aktivaci tohoto modulu mohou organizátoři vkládat své vlastní platební "
6213
  "údaje pro povolené brány pro události a přijímat platby přímo!"
6214
 
6215
+ #: app/features/mec/booking.php:1074
6216
  msgid "Disable / Enable payment gateways per event"
6217
  msgstr ""
6218
 
6219
+ #: app/features/mec/booking.php:1078
6220
  #, fuzzy
6221
  #| msgid "Payment Gateways"
6222
  msgid "Payment Gateways Per Event"
6223
  msgstr "Platební brány"
6224
 
6225
+ #: app/features/mec/booking.php:1079
6226
  #, fuzzy
6227
  #| msgid ""
6228
  #| "By enabling this module, organizers are able to insert their own payment "
6235
  "Po aktivaci tohoto modulu mohou organizátoři vkládat své vlastní platební "
6236
  "údaje pro povolené brány pro události a přijímat platby přímo!"
6237
 
6238
+ #: app/features/mec/booking.php:1089
6239
  msgid "Automatically refund the payment"
6240
  msgstr ""
6241
 
6242
+ #: app/features/mec/booking.php:1093
6243
  msgid "Auto Refund"
6244
  msgstr ""
6245
 
6246
+ #: app/features/mec/booking.php:1094
6247
  msgid ""
6248
  "Automatically refund the payment when a booking paid by applicable gateways "
6249
  "(Stripe) got canceled."
6250
  msgstr ""
6251
 
6252
+ #: app/features/mec/booking.php:1113
6253
  msgid "Use MEC Cart System"
6254
  msgstr ""
6255
 
6256
+ #: app/features/mec/booking.php:1115
6257
  msgid ""
6258
  "If you don't want to use WooCommerce for any reason you can use MEC Cart for "
6259
  "adding a simple cart and checkout system to your website."
6260
  msgstr ""
6261
 
6262
+ #: app/features/mec/booking.php:1117
6263
  msgid "You cannot use following MEC features while using MEC Cart."
6264
  msgstr ""
6265
 
6266
+ #: app/features/mec/booking.php:1119
6267
  #, fuzzy
6268
  #| msgid "Set Up a Payment Gateway"
6269
  msgid "WooCommerce as Payment Gateway"
6270
  msgstr "Nastavení platební brány"
6271
 
6272
+ #: app/features/mec/booking.php:1120
6273
  #, fuzzy
6274
  #| msgid "Next Occurrence of Other Events"
6275
  msgid "Currency Per Event"
6276
  msgstr "Další výskyt dalších událostí"
6277
 
6278
+ #: app/features/mec/booking.php:1121
6279
  #, fuzzy
6280
  #| msgid "Payment Gateways"
6281
  msgid "Disable Gateways Per Event"
6282
  msgstr "Platební brány"
6283
 
6284
+ #: app/features/mec/booking.php:1122
6285
  #, fuzzy
6286
  #| msgid "Set Up WooCommerce Gateway"
6287
  msgid "Stripe Connect Gateway"
6288
  msgstr "Nastavit bránu WooCommerce"
6289
 
6290
+ #: app/features/mec/booking.php:1123
6291
  #, fuzzy
6292
  #| msgid "Set Up WooCommerce Gateway"
6293
  msgid "Pay By WooCommerce Gateway"
6294
  msgstr "Nastavit bránu WooCommerce"
6295
 
6296
+ #: app/features/mec/booking.php:1127
6297
  #, fuzzy
6298
  #| msgid "Start Date"
6299
  msgid "Cart Page"
6300
  msgstr "Počátečná den"
6301
 
6302
+ #: app/features/mec/booking.php:1135 app/features/mec/booking.php:1147
6303
  #: app/features/mec/settings.php:722 app/features/mec/settings.php:734
6304
  #, php-format
6305
  msgid "Put %s shortcode into the page."
6306
  msgstr "Vložte %s na stránku zkrácené kódy."
6307
 
6308
+ #: app/features/mec/booking.php:1139
6309
  #, fuzzy
6310
  #| msgid "Checkout"
6311
  msgid "Checkout Page"
6312
  msgstr "Překontrolovat"
6313
 
6314
+ #: app/features/mec/booking.php:1165
6315
  #, fuzzy
6316
  #| msgid "Enable Invoice"
6317
  msgid "Enable Cart Invoice"
6318
  msgstr "Povolit fakturu"
6319
 
6320
+ #: app/features/mec/booking.php:1248 app/features/mec/integrations.php:446
6321
  #: app/features/mec/messages.php:90 app/features/mec/modules.php:403
6322
  #: app/features/mec/notifications.php:1919 app/features/mec/settings.php:1596
6323
  #: app/features/mec/single.php:592 app/features/mec/styles.php:62
6325
  msgid "Saved"
6326
  msgstr "Uloženo"
6327
 
6328
+ #: app/features/mec/booking.php:1249 app/features/mec/integrations.php:447
6329
  #: app/features/mec/messages.php:91 app/features/mec/modules.php:404
6330
  #: app/features/mec/notifications.php:1920 app/features/mec/settings.php:1597
6331
  #: app/features/mec/single.php:593 app/features/mec/styles.php:63
6333
  msgid "Settings Saved!"
6334
  msgstr "Nastavení uložena!"
6335
 
6336
+ #: app/features/mec/booking.php:1275 app/features/mec/integrations.php:473
6337
  #: app/features/mec/modules.php:430 app/features/mec/notifications.php:1947
6338
  #: app/features/mec/settings.php:1623 app/features/mec/single.php:619
6339
  msgid "Please Refresh Page"
6340
  msgstr "Prosím obnovte stránku"
6341
 
6342
+ #: app/features/mec/dashboard.php:54
6343
  #, php-format
6344
  msgid "Welcome %s"
6345
  msgstr "Vítejte %s"
6346
 
6347
+ #: app/features/mec/dashboard.php:57
6348
  #, php-format
6349
  msgid "%s - Most Powerful & Easy to Use Events Management System"
6350
  msgstr "%s - Nejvýkonnější a snadno použitelný systém pro správu událostí"
6351
 
6352
+ #: app/features/mec/dashboard.php:59 app/libraries/factory.php:217
6353
  msgctxt "plugin rate"
6354
  msgid "Rate the plugin ★★★★★"
6355
  msgstr "Ohodnoťe doplněk ★★★★★"
6356
 
6357
+ #: app/features/mec/dashboard.php:82 app/features/mec/go-pro.php:66
 
 
 
 
6358
  #, php-format
6359
  msgid ""
6360
  "You're using %s version of Modern Events Calendar. To use advanced booking "
6365
  "pokročilý rezervační systém, moderní vzhledy jako Agenda, Rozvrh, Roční "
6366
  "pohled, Dostupná místa atd., Měli byste upgradovat na verzi Pro."
6367
 
6368
+ #: app/features/mec/dashboard.php:82 app/features/mec/go-pro.php:66
6369
  msgid "lite"
6370
  msgstr " omezenou"
6371
 
6372
+ #: app/features/mec/dashboard.php:85 app/features/mec/go-pro.php:69
6373
  #: app/features/mec/support.php:126
6374
  msgid "GO PREMIUM"
6375
  msgstr "PŘEJÍT NA PREMIUM"
6376
 
6377
+ #: app/features/mec/dashboard.php:88 app/features/mec/go-pro.php:72
6378
  #, php-format
6379
  msgid ""
6380
  "Easily get a discount coupon by rating us on %s or following and reposting "
6383
  "Jednoduše získejte slevový kupón tím, že nás ohodnocíte na% s nebo poté a "
6384
  "uložíte nás na sociální média. Stačí poslat screenshot do % s a obdržíte % s"
6385
 
6386
+ #: app/features/mec/dashboard.php:88 app/features/mec/go-pro.php:72
6387
  msgid "WordPress"
6388
  msgstr "WordPress"
6389
 
6390
+ #: app/features/mec/dashboard.php:88 app/features/mec/go-pro.php:72
6391
  msgid "Copouns!"
6392
  msgstr "Kupóny!"
6393
 
6394
+ #: app/features/mec/dashboard.php:118
6395
  msgid "Getting started with Modern Events Calendar"
6396
  msgstr "Začínáme s Modern Events Calendar"
6397
 
6398
+ #: app/features/mec/dashboard.php:119
6399
  msgid ""
6400
  "In this short video, you can learn how to make an event and put a calendar "
6401
  "on your website. Please watch this 2 minutes video to the end."
6403
  "V tomto krátkém videu se dozvíte, jak vytvořit událost a umístit kalendář na "
6404
  "svoje stránky. Sledujte prosím toto 2minutové video až do konce."
6405
 
6406
+ #: app/features/mec/dashboard.php:135 app/features/mec/dashboard.php:159
6407
  #, fuzzy
6408
  #| msgid "MEC Activation"
6409
  msgid "License Activation"
6410
  msgstr "Aktivace MEC"
6411
 
6412
+ #: app/features/mec/dashboard.php:141 app/features/mec/dashboard.php:196
6413
  msgid "Activate Addons"
6414
  msgstr "Aktivovat doplňky"
6415
 
6416
+ #: app/features/mec/dashboard.php:149 app/features/mec/dashboard.php:205
6417
  msgid "You cannot access this section."
6418
  msgstr "Nemáte přístup do této části."
6419
 
6420
+ #: app/features/mec/dashboard.php:165
6421
  msgid ""
6422
  "In order to use all plugin features and options, please enter your purchase "
6423
  "code."
6425
  "Chcete-li využívat všechny funkce a možnosti doplňku, zadejte prosím "
6426
  "zakoupený kód."
6427
 
6428
+ #: app/features/mec/dashboard.php:273
6429
  msgid "Popular Gateways"
6430
  msgstr "Oblíbené platební brány"
6431
 
6432
+ #: app/features/mec/dashboard.php:331
6433
  msgid "Change Log"
6434
  msgstr "Změna logu"
6435
 
6803
  msgid "Modern"
6804
  msgstr "Moderní"
6805
 
 
 
 
 
 
 
6806
  #: app/features/mec/meta_boxes/display_options.php:52
6807
  #: app/features/mec/settings.php:405 app/features/mec/settings.php:482
6808
  #: app/features/popup/settings.php:132 app/features/popup/shortcode.php:90
7975
  #: app/features/mec/single.php:526 app/features/popup/settings.php:233
7976
  #: app/features/popup/settings.php:272 app/features/search.php:109
7977
  #: app/features/speakers.php:60 app/features/speakers.php:286
7978
+ #: app/libraries/main.php:7419 app/libraries/main.php:7480
7979
  #: app/libraries/search.php:334 app/libraries/skins.php:1203
7980
  #: app/modules/speakers/details.php:18
7981
  msgid "Speaker"
9305
  msgid "only once per hour"
9306
  msgstr "pouze jednou denně"
9307
 
9308
+ #: app/features/mec/notifications.php:1314 app/libraries/main.php:8664
9309
+ #: app/libraries/main.php:8684
9310
  #, fuzzy
9311
  #| msgid "hours"
9312
  msgid "Hours"
9643
  msgstr "Můžete povolit nebo zakázat skripty schématu"
9644
 
9645
  #: app/features/mec/settings.php:137 app/features/mec/settings.php:148
9646
+ #: app/features/popup/settings.php:41 app/libraries/main.php:7423
9647
+ #: app/libraries/main.php:7484
9648
  msgid "Weekdays"
9649
  msgstr "Pracovní dny"
9650
 
10073
  msgid "Site Key"
10074
  msgstr "Klíč webu"
10075
 
 
 
 
 
10076
  #: app/features/mec/settings.php:697 app/features/mec/settings.php:705
10077
  msgid "Time Format"
10078
  msgstr "Formát času"
10312
  msgid "Required Fields"
10313
  msgstr "Požadovaná pole"
10314
 
10315
+ #: app/features/mec/settings.php:1164 app/libraries/main.php:7455
10316
+ #: app/libraries/main.php:7502
10317
  msgid "More Info Link"
10318
  msgstr "Odkaz na více informací"
10319
 
11683
  msgid "eg. https://webnus.net"
11684
  msgstr "např. https://webnus.net"
11685
 
11686
+ #: app/features/organizers.php:329 app/libraries/main.php:7458
11687
+ #: app/libraries/main.php:7505 app/skins/single.php:1434
11688
  msgid "Other Organizers"
11689
  msgstr "Další organizátoři"
11690
 
11914
  msgid "MEC Pro"
11915
  msgstr "MEC - podpora"
11916
 
11917
+ #: app/features/profile/profile.php:53 app/features/profile/profile.php:200
11918
  msgid "#"
11919
  msgstr "#"
11920
 
11926
  msgid "Cancel"
11927
  msgstr "Zrušit"
11928
 
11929
+ #: app/features/profile/profile.php:125
11930
  msgid "N/A"
11931
  msgstr ""
11932
 
11933
+ #: app/features/profile/profile.php:161
11934
  #, php-format
11935
  msgid "<i class=\"mec-sl-eye\"></i> %s"
11936
  msgstr "<i class=\"mec-sl-eye\"></i> %s"
11937
 
11938
+ #: app/features/profile/profile.php:261
11939
  msgid "No bookings found!"
11940
  msgstr "Nebyly nalezeny žádné rezervace!"
11941
 
12069
  msgid "%s ticket is sold out!"
12070
  msgstr ""
12071
 
12072
+ #: app/features/wc.php:246 app/libraries/main.php:7442
 
 
 
 
 
12073
  #, php-format
12074
  msgid "Maximum allowed number of tickets that you can book is %s."
12075
  msgstr ""
12087
  msgid "Discount"
12088
  msgstr "Sleva"
12089
 
 
 
 
 
 
12090
  #: app/libraries/cart.php:69 app/libraries/wc.php:107
12091
  #, fuzzy
12092
  #| msgid "View Event"
12102
  msgstr[1] ""
12103
  msgstr[2] ""
12104
 
12105
+ #: app/libraries/factory.php:177
 
 
 
 
 
12106
  msgid "M.E. Calendar"
12107
  msgstr "M.E. Kalendář"
12108
 
12109
+ #: app/libraries/factory.php:216
12110
  msgctxt "plugin link"
12111
  msgid "Upgrade to Pro Version"
12112
  msgstr "Upgrade na verzi PRO"
12113
 
12114
+ #: app/libraries/factory.php:234
12115
  msgctxt "plugin link"
12116
  msgid "Settings"
12117
  msgstr "Nastavení"
12118
 
12119
+ #: app/libraries/factory.php:239
12120
  msgctxt "plugin link"
12121
  msgid "Upgrade"
12122
  msgstr "Upgrade"
12123
 
12124
+ #: app/libraries/factory.php:387
12125
  msgid "day"
12126
  msgstr "den"
12127
 
12128
+ #: app/libraries/factory.php:388 app/modules/countdown/details.php:190
12129
  #: app/skins/available_spot/tpl.php:143 app/skins/countdown/tpl.php:125
12130
  #: app/skins/countdown/tpl.php:171 app/skins/countdown/tpl.php:222
12131
  msgid "days"
12132
  msgstr "dny"
12133
 
12134
+ #: app/libraries/factory.php:389
12135
  msgid "hour"
12136
  msgstr "hodina"
12137
 
12138
+ #: app/libraries/factory.php:390 app/modules/countdown/details.php:197
12139
  #: app/skins/available_spot/tpl.php:147 app/skins/countdown/tpl.php:131
12140
  #: app/skins/countdown/tpl.php:177 app/skins/countdown/tpl.php:228
12141
  msgid "hours"
12142
  msgstr "hodiny"
12143
 
12144
+ #: app/libraries/factory.php:391
12145
  msgid "minute"
12146
  msgstr "minuta"
12147
 
12148
+ #: app/libraries/factory.php:392 app/modules/countdown/details.php:204
12149
  #: app/skins/available_spot/tpl.php:151 app/skins/countdown/tpl.php:137
12150
  #: app/skins/countdown/tpl.php:183 app/skins/countdown/tpl.php:234
12151
  msgid "minutes"
12152
  msgstr "minuty"
12153
 
12154
+ #: app/libraries/factory.php:393
12155
  msgid "second"
12156
  msgstr "vteřina"
12157
 
12158
+ #: app/libraries/factory.php:394 app/modules/countdown/details.php:211
12159
  #: app/skins/available_spot/tpl.php:155 app/skins/countdown/tpl.php:143
12160
  #: app/skins/countdown/tpl.php:189 app/skins/countdown/tpl.php:240
12161
  msgid "seconds"
12162
  msgstr "vteřiny"
12163
 
12164
+ #: app/libraries/factory.php:470
12165
  msgid "MEC Single Sidebar"
12166
  msgstr "MEC Postranní panel"
12167
 
12168
+ #: app/libraries/factory.php:471
12169
  msgid "Custom sidebar for single and modal page of MEC."
12170
  msgstr "Vlastní postranní panel pro jednu a modální stránku MEC."
12171
 
12172
+ #: app/libraries/factory.php:1186
12173
  msgid "Notice:"
12174
  msgstr ""
12175
 
12176
+ #: app/libraries/factory.php:1187
12177
  msgid "This update includes only bug fixes."
12178
  msgstr ""
12179
 
12280
  msgid "General Calendar"
12281
  msgstr "Kalendář Google"
12282
 
12283
+ #: app/libraries/main.php:439 app/libraries/main.php:7425
12284
+ #: app/libraries/main.php:7486
12285
  msgid "SU"
12286
  msgstr "NE"
12287
 
12288
+ #: app/libraries/main.php:440 app/libraries/main.php:7426
12289
+ #: app/libraries/main.php:7487
12290
  msgid "MO"
12291
  msgstr "PO"
12292
 
12293
+ #: app/libraries/main.php:441 app/libraries/main.php:7427
12294
+ #: app/libraries/main.php:7488
12295
  msgid "TU"
12296
  msgstr "ÚT"
12297
 
12298
+ #: app/libraries/main.php:442 app/libraries/main.php:7428
12299
+ #: app/libraries/main.php:7489
12300
  msgid "WE"
12301
  msgstr "ST"
12302
 
12303
+ #: app/libraries/main.php:443 app/libraries/main.php:7429
12304
+ #: app/libraries/main.php:7490
12305
  msgid "TH"
12306
  msgstr "ČT"
12307
 
12308
+ #: app/libraries/main.php:444 app/libraries/main.php:7430
12309
+ #: app/libraries/main.php:7491
12310
  msgid "FR"
12311
  msgstr "PÁ"
12312
 
12313
+ #: app/libraries/main.php:445 app/libraries/main.php:7431
12314
+ #: app/libraries/main.php:7492
12315
  msgid "SA"
12316
  msgstr "SO"
12317
 
12648
  msgid "iCal export stopped!"
12649
  msgstr "iCal export byl zastaven!"
12650
 
12651
+ #: app/libraries/main.php:4157
12652
  #, fuzzy
12653
  #| msgid "Block Editor"
12654
  msgid "HTML Editor"
12655
  msgstr "Editor bloků"
12656
 
12657
+ #: app/libraries/main.php:4315
12658
  msgid "Consider the first item as a placeholder"
12659
  msgstr ""
12660
 
12661
+ #: app/libraries/main.php:5204 app/libraries/main.php:7823
 
 
 
 
12662
  msgid "M.E. Calender"
12663
  msgstr "M.E. Kalendář"
12664
 
12665
+ #: app/libraries/main.php:5383
12666
  #, php-format
12667
  msgid "Copy of %s"
12668
  msgstr "Kopie %s"
12669
 
12670
+ #: app/libraries/main.php:6354
12671
  msgid "Booked an event."
12672
  msgstr "Událost byla rezervována."
12673
 
12674
+ #: app/libraries/main.php:6395
12675
  #, php-format
12676
  msgid "%s booked %s event."
12677
  msgstr "%s zarezervoval %s událost."
12678
 
12679
+ #: app/libraries/main.php:7408 app/libraries/main.php:7469
12680
  msgid "Taxonomies"
12681
  msgstr "Taxonomie"
12682
 
12683
  # Mrknout na kontext
12684
+ #: app/libraries/main.php:7410 app/libraries/main.php:7471
12685
  msgid "Category Plural Label"
12686
  msgstr "Štítek množné kategorie"
12687
 
12688
  # Mrknout na kontext
12689
+ #: app/libraries/main.php:7411 app/libraries/main.php:7472
12690
  msgid "Category Singular Label"
12691
  msgstr "Štítek jednotné kategorie"
12692
 
12693
+ #: app/libraries/main.php:7412 app/libraries/main.php:7473
12694
  msgid "Label Plural Label"
12695
  msgstr "Štítek množného štítku"
12696
 
12697
+ #: app/libraries/main.php:7413 app/libraries/main.php:7474
12698
  msgid "Label Singular Label"
12699
  msgstr "Štítek jednotného štítku"
12700
 
12701
+ #: app/libraries/main.php:7413 app/libraries/main.php:7474
12702
  msgid "label"
12703
  msgstr "štítek"
12704
 
12705
+ #: app/libraries/main.php:7414 app/libraries/main.php:7475
12706
  msgid "Location Plural Label"
12707
  msgstr "Štítek množného umístění"
12708
 
12709
+ #: app/libraries/main.php:7415 app/libraries/main.php:7476
12710
  msgid "Location Singular Label"
12711
  msgstr "Štítek jednotného umístění"
12712
 
12713
+ #: app/libraries/main.php:7416 app/libraries/main.php:7477
12714
  msgid "Organizer Plural Label"
12715
  msgstr "Štítek množného organizátora"
12716
 
12717
+ #: app/libraries/main.php:7417 app/libraries/main.php:7478
12718
  msgid "Organizer Singular Label"
12719
  msgstr "Štítek jednotného organizátora"
12720
 
12721
+ #: app/libraries/main.php:7418 app/libraries/main.php:7479
12722
  msgid "Speaker Plural Label"
12723
  msgstr "Štítek množného řečníka"
12724
 
12725
+ #: app/libraries/main.php:7419 app/libraries/main.php:7480
12726
  msgid "Speaker Singular Label"
12727
  msgstr "Štítek jednotného řečníka"
12728
 
12729
+ #: app/libraries/main.php:7425 app/libraries/main.php:7486
12730
  msgid "Sunday abbreviation"
12731
  msgstr "Neděle zkratka"
12732
 
12733
+ #: app/libraries/main.php:7426 app/libraries/main.php:7487
12734
  msgid "Monday abbreviation"
12735
  msgstr "Pondělí zkratka"
12736
 
12737
+ #: app/libraries/main.php:7427 app/libraries/main.php:7488
12738
  msgid "Tuesday abbreviation"
12739
  msgstr "Úterý zkratka"
12740
 
12741
+ #: app/libraries/main.php:7428 app/libraries/main.php:7489
12742
  msgid "Wednesday abbreviation"
12743
  msgstr "Středa zkratka"
12744
 
12745
+ #: app/libraries/main.php:7429 app/libraries/main.php:7490
12746
  msgid "Thursday abbreviation"
12747
  msgstr "Čtvrtek zkratka"
12748
 
12749
+ #: app/libraries/main.php:7430 app/libraries/main.php:7491
12750
  msgid "Friday abbreviation"
12751
  msgstr "Pátek zkratka"
12752
 
12753
+ #: app/libraries/main.php:7431 app/libraries/main.php:7492
12754
  msgid "Saturday abbreviation"
12755
  msgstr "Sobota zkratka"
12756
 
12757
+ #: app/libraries/main.php:7437
12758
  #, fuzzy
12759
  #| msgid "Ticket (Singular)"
12760
  msgid "Booking (Singular)"
12761
  msgstr "Vstupenka (Jednotné)"
12762
 
12763
+ #: app/libraries/main.php:7438
12764
  #, fuzzy
12765
  #| msgid "Tickets (Plural)"
12766
  msgid "Bookings (Plural)"
12767
  msgstr "Vstupenky (Množné)"
12768
 
12769
+ #: app/libraries/main.php:7439
12770
  msgid "Booking Success Message"
12771
  msgstr "Zpráva o úspěchu rezervace"
12772
 
12773
+ #: app/libraries/main.php:7440
 
 
 
 
 
 
 
 
 
 
 
 
12774
  #, fuzzy
12775
  #| msgid "Booking Success Message"
12776
  msgid "Booking Restriction Message 1"
12777
  msgstr "Zpráva o úspěchu rezervace"
12778
 
12779
+ #: app/libraries/main.php:7440
12780
  #, php-format
12781
  msgid ""
12782
  "You selected %s tickets to book but maximum number of tikets per user is %s "
12783
  "tickets."
12784
  msgstr ""
12785
 
12786
+ #: app/libraries/main.php:7441
12787
  #, fuzzy
12788
  #| msgid "Booking Success Message"
12789
  msgid "Booking Restriction Message 2"
12790
  msgstr "Zpráva o úspěchu rezervace"
12791
 
12792
+ #: app/libraries/main.php:7441
12793
  #, php-format
12794
  msgid ""
12795
  "You booked %s tickets till now but maximum number of tickets per user is %s "
12796
  "tickets."
12797
  msgstr ""
12798
 
12799
+ #: app/libraries/main.php:7442
12800
  #, fuzzy
12801
  #| msgid "Booking Success Message"
12802
  msgid "Booking IP Restriction Message"
12803
  msgstr "Zpráva o úspěchu rezervace"
12804
 
12805
+ #: app/libraries/main.php:7443
12806
  #, fuzzy
12807
  #| msgid "Booking Options"
12808
  msgid "Booking Button"
12809
  msgstr "Možnosti rezervace"
12810
 
12811
+ #: app/libraries/main.php:7443
12812
  #, fuzzy
12813
  #| msgid "Booking Form"
12814
  msgid "Book Now"
12815
  msgstr "Rezervační formulář"
12816
 
12817
+ #: app/libraries/main.php:7444
12818
  msgid "Ticket (Singular)"
12819
  msgstr "Vstupenka (Jednotné)"
12820
 
12821
+ #: app/libraries/main.php:7445
12822
  msgid "Tickets (Plural)"
12823
  msgstr "Vstupenky (Množné)"
12824
 
12825
+ #: app/libraries/main.php:7449 app/libraries/main.php:7496
12826
  msgid "Others"
12827
  msgstr "Další"
12828
 
12829
+ #: app/libraries/main.php:7451 app/libraries/main.php:7498
12830
  #: app/widgets/single.php:129
12831
  msgid "Register Button"
12832
  msgstr "Registrační tlačítko"
12833
 
12834
+ #: app/libraries/main.php:7452 app/libraries/main.php:7499
12835
  msgid "View Detail Button"
12836
  msgstr "Tlačítko Zobrazit detail"
12837
 
12838
+ #: app/libraries/main.php:7452 app/libraries/main.php:7499
12839
  #: app/skins/carousel/render.php:105 app/skins/carousel/render.php:145
12840
  #: app/skins/grid/render.php:94 app/skins/grid/render.php:153
12841
  #: app/skins/grid/render.php:214 app/skins/grid/render.php:237
12847
  msgid "View Detail"
12848
  msgstr "Zobrazit detail"
12849
 
12850
+ #: app/libraries/main.php:7453 app/libraries/main.php:7500
12851
  msgid "Event Detail Button"
12852
  msgstr "Tlačítko Detail události"
12853
 
12854
+ #: app/libraries/main.php:7453 app/libraries/main.php:7500
12855
  msgid "Event Detail"
12856
  msgstr "Zobrazit událost"
12857
 
12858
+ #: app/libraries/main.php:7615
12859
  msgid "EventON"
12860
  msgstr "EventON"
12861
 
12862
+ #: app/libraries/main.php:7616
12863
  msgid "The Events Calendar"
12864
  msgstr "The Events Calendar"
12865
 
12866
+ #: app/libraries/main.php:7617
12867
  msgid "Events Schedule WP Plugin"
12868
  msgstr "Events Schedule WP Plugin"
12869
 
12870
+ #: app/libraries/main.php:7618
12871
  msgid "Calendarize It"
12872
  msgstr "Calendarize It"
12873
 
12874
+ #: app/libraries/main.php:7619
12875
  #, fuzzy
12876
  #| msgid "Event Speakers"
12877
  msgid "Event Espresso"
12878
  msgstr "Řečník události"
12879
 
12880
+ #: app/libraries/main.php:7620
12881
  #, fuzzy
12882
  #| msgid "Event Repeating (Recurring events)"
12883
  msgid "Events Manager (Recurring)"
12884
  msgstr "Opakování události (opakující se události)"
12885
 
12886
+ #: app/libraries/main.php:7621
12887
  #, fuzzy
12888
  #| msgid "Modern Events Calendar (Lite)"
12889
  msgid "Events Manager (Single)"
12890
  msgstr "Modern Events Calendar (Lite)"
12891
 
12892
+ #: app/libraries/main.php:7622
12893
  #, fuzzy
12894
  #| msgid "Modern Events Calendar (Lite)"
12895
  msgid "WP Event Manager"
12896
  msgstr "Modern Events Calendar (Lite)"
12897
 
12898
+ #: app/libraries/main.php:7853
12899
  #, fuzzy
12900
  #| msgid "Sunday"
12901
  msgid "Sun"
12902
  msgstr "Neděle"
12903
 
12904
+ #: app/libraries/main.php:7853
12905
  #, fuzzy
12906
  #| msgid "Monday"
12907
  msgid "Mon"
12908
  msgstr "Pondělí"
12909
 
12910
+ #: app/libraries/main.php:7853
12911
  #, fuzzy
12912
  #| msgid "Tel"
12913
  msgid "Tue"
12914
  msgstr "Tel"
12915
 
12916
+ #: app/libraries/main.php:7853
12917
  msgid "Wed"
12918
  msgstr ""
12919
 
12920
+ #: app/libraries/main.php:7853
12921
  msgid "Thu"
12922
  msgstr ""
12923
 
12924
+ #: app/libraries/main.php:7853
12925
  #, fuzzy
12926
  #| msgid "Friday"
12927
  msgid "Fri"
12928
  msgstr "Pátek"
12929
 
12930
+ #: app/libraries/main.php:7853
12931
  #, fuzzy
12932
  #| msgid "Start"
12933
  msgid "Sat"
12934
  msgstr "Začátek"
12935
 
12936
+ #: app/libraries/main.php:8059 app/libraries/render.php:82
12937
  #: app/libraries/render.php:467
12938
  msgid "Skin controller does not exist."
12939
  msgstr "Ovladač vzhledu neexistuje."
12940
 
12941
+ #: app/libraries/main.php:8299
12942
  msgid "Sold Out"
12943
  msgstr "Vyprodáno"
12944
 
12945
+ #: app/libraries/main.php:8330
12946
  #, fuzzy
12947
  #| msgid "Ticket"
12948
  msgid "Last Few Tickets"
12949
  msgstr "Vstupenka"
12950
 
12951
+ #: app/libraries/main.php:8602
12952
  #, fuzzy
12953
  #| msgid "Upcoming Events"
12954
  msgid "Ongoing"
12955
  msgstr "Nadcházející události"
12956
 
12957
+ #: app/libraries/main.php:8604
12958
  #, fuzzy
12959
  #| msgid "Expired Events"
12960
  msgid "Expired"
12961
  msgstr "Události vypršely"
12962
 
12963
+ #: app/libraries/main.php:8670 app/libraries/main.php:8690
12964
  #, fuzzy
12965
  #| msgid "minutes"
12966
  msgid "Minutes"
12967
  msgstr "minuty"
12968
 
12969
+ #: app/libraries/main.php:8695
12970
  msgid "AM / PM"
12971
  msgstr ""
12972
 
12973
+ #: app/libraries/main.php:8696
12974
  msgid "AM"
12975
  msgstr "dop."
12976
 
12977
+ #: app/libraries/main.php:8697
12978
  msgid "PM"
12979
  msgstr "odp."
12980
 
12981
+ #: app/libraries/main.php:8705
12982
  msgid "Ongoing..."
12983
  msgstr ""
12984
 
12985
+ #: app/libraries/main.php:8706 app/skins/single.php:229
12986
  #, fuzzy
12987
  #| msgid "Expired Events"
12988
  msgid "Expired!"
12989
  msgstr "Události vypršely"
12990
 
12991
+ #: app/libraries/main.php:9264
12992
  #, fuzzy
12993
  #| msgid "Categories"
12994
  msgid "Uncategorized"
13195
  msgid "Add to Cart"
13196
  msgstr "Umístění"
13197
 
 
 
 
 
13198
  #: app/modules/booking/steps/tickets.php:148
13199
  msgid ""
13200
  "By booking this event you can attend all occurrences. Some of them are "
13451
  msgid "Home"
13452
  msgstr "Domů"
13453
 
13454
+ #: app/skins/single.php:1574
13455
  msgid "Speakers:"
13456
  msgstr "Řečník:"
13457
 
13458
+ #: app/skins/single.php:1769
13459
  #, fuzzy
13460
  #| msgid "Download Invoice"
13461
  msgid "Download"
13578
  msgid "http://webnus.net"
13579
  msgstr "http://webnus.net"
13580
 
13581
+ #~ msgid "Update"
13582
+ #~ msgstr "Aktualizovat"
13583
+
13584
  #~ msgid "All of the day"
13585
  #~ msgstr "Celý den"
13586
 
13973
  #~ msgid "Insert -1 for unlimited usage"
13974
  #~ msgstr "Vložte URL stránky na Twitteru"
13975
 
 
 
 
 
 
13976
  #, fuzzy
13977
  #~| msgid "Next Event"
13978
  #~ msgid "Target Event"
13999
  #~ msgstr ""
14000
  #~ "Událost se neopakuje. Pro tuto událost neexistují žádná data!álosti)"
14001
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14002
  #, fuzzy
14003
  #~| msgid "Organizer Payment"
14004
  #~ msgid "Organizer Payment Credentials"
languages/modern-events-calendar-lite-de_DE.mo CHANGED
Binary file
languages/modern-events-calendar-lite-de_DE.po CHANGED
@@ -2,8 +2,8 @@ msgid ""
2
  msgstr ""
3
  "Project-Id-Version: ME Calender\n"
4
  "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2022-01-05 14:48+0330\n"
6
- "PO-Revision-Date: 2022-01-05 14:52+0330\n"
7
  "Last-Translator: Jogon <koenig@kafinanz.de>\n"
8
  "Language-Team: German\n"
9
  "Language: de_DE\n"
@@ -19,8 +19,8 @@ msgstr ""
19
 
20
  #: app/addons/KC.php:68 app/addons/VC.php:59 app/features/ix/import.php:24
21
  #: app/features/ix/import.php:48 app/features/ix/import.php:77
22
- #: app/features/ix/thirdparty.php:26 app/features/mec.php:1302
23
- #: app/features/mec.php:1326 app/features/mec/dashboard.php:65
24
  #: app/features/mec/wizard.php:489 app/widgets/MEC.php:33
25
  msgid "Modern Events Calendar"
26
  msgstr "Moderner Event Kalender "
@@ -31,8 +31,8 @@ msgstr "Moderner Event Kalender "
31
  msgid "Content"
32
  msgstr "Inhalt"
33
 
34
- #: app/addons/KC.php:75 app/addons/VC.php:70 app/features/mec.php:568
35
- #: app/features/mec.php:599 app/features/mec.php:629
36
  msgid "Shortcode"
37
  msgstr "Shortcode"
38
 
@@ -106,40 +106,85 @@ msgstr ""
106
  msgid "Select Shortcode"
107
  msgstr "Neuen Shortcode hinzufügen"
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  #: app/core/src/Books/Book.php:106 app/features/ix.php:284
110
- #: app/libraries/main.php:7751 app/libraries/main.php:7778
111
  msgid "Rejected"
112
  msgstr "Abgelehnt"
113
 
114
  #: app/core/src/Books/Book.php:111 app/features/ix.php:283
115
- #: app/libraries/main.php:3232 app/libraries/main.php:7750
116
- #: app/libraries/main.php:7770
117
  msgid "Confirmed"
118
  msgstr "Bestätigt"
119
 
120
  #: app/core/src/Books/Book.php:117 app/features/mec/settings.php:742
121
- #: app/libraries/main.php:7752 app/libraries/main.php:7774
122
  msgid "Pending"
123
  msgstr "Ausstehend"
124
 
125
  #: app/core/src/Books/Book.php:186 app/features/ix.php:289
126
  #: app/features/labels.php:119 app/features/labels.php:145
127
- #: app/libraries/main.php:7799
128
  msgid "Canceled"
129
  msgstr "Abgesagt"
130
 
131
  #: app/core/src/Books/Book.php:191 app/features/ix.php:288
132
- #: app/features/mec/booking.php:1246 app/features/mec/booking.php:1268
133
  #: app/features/mec/integrations.php:449 app/features/mec/integrations.php:471
134
  #: app/features/mec/modules.php:406 app/features/mec/modules.php:428
135
  #: app/features/mec/notifications.php:1922
136
  #: app/features/mec/notifications.php:1945 app/features/mec/settings.php:1599
137
  #: app/features/mec/settings.php:1621 app/features/mec/single.php:595
138
- #: app/features/mec/single.php:617 app/libraries/main.php:7798
139
  msgid "Verified"
140
  msgstr "Verifiziert"
141
 
142
- #: app/core/src/Books/Book.php:197 app/libraries/main.php:7800
143
  msgid "Waiting"
144
  msgstr "in Bearbeitung"
145
 
@@ -166,22 +211,23 @@ msgstr "Vorname"
166
  #: app/core/src/Forms/FormFields.php:188 app/core/src/Forms/SettingsForm.php:93
167
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:70
168
  #: app/features/autoemails.php:60 app/features/events.php:606
169
- #: app/features/events.php:2658 app/features/events.php:2725
170
- #: app/features/events.php:2814 app/features/events.php:4422
171
  #: app/features/fes.php:280 app/features/fes/form.php:810
172
- #: app/features/login/login.php:5 app/features/mec/booking.php:57
173
- #: app/features/mec/booking.php:794 app/features/mec/booking.php:892
174
- #: app/features/mec/settings.php:295 app/features/mec/single.php:303
175
- #: app/features/organizers.php:112 app/features/organizers.php:153
176
- #: app/features/profile/profile.php:195 app/features/speakers.php:128
177
- #: app/features/speakers.php:205 app/libraries/main.php:618
178
- #: app/libraries/main.php:2093 app/libraries/main.php:2162
179
- #: app/libraries/main.php:3987 app/libraries/notifications.php:2091
180
- #: app/modules/booking/steps/form.php:69 app/modules/booking/steps/form.php:218
181
- #: app/skins/single.php:1399 app/skins/single.php:1466
182
- #: app/skins/single/default.php:347 app/skins/single/default.php:596
183
- #: app/skins/single/m1.php:141 app/skins/single/m2.php:61
184
- #: app/skins/single/modern.php:94
 
185
  msgid "Email"
186
  msgstr "E-Mail"
187
 
@@ -199,21 +245,21 @@ msgstr "Geben Sie eine Bezeichnung (Label) für dieses Feld ein."
199
  #: app/core/src/Forms/FormFields.php:396 app/core/src/Forms/FormFields.php:442
200
  #: app/core/src/Forms/FormFields.php:488 app/core/src/Forms/FormFields.php:544
201
  #: app/core/src/Forms/FormFields.php:596 app/features/organizers.php:340
202
- #: app/features/organizers.php:348 app/libraries/main.php:3895
203
- #: app/libraries/main.php:3926 app/libraries/main.php:3956
204
- #: app/libraries/main.php:3986 app/libraries/main.php:4017
205
- #: app/libraries/main.php:4048 app/libraries/main.php:4078
206
- #: app/libraries/main.php:4109 app/libraries/main.php:4140
207
- #: app/libraries/main.php:4178 app/libraries/main.php:4202
208
- #: app/libraries/main.php:4250 app/libraries/main.php:4298
209
- #: app/libraries/main.php:4356 app/libraries/main.php:4406
210
  msgid "Sort"
211
  msgstr "Sortieren"
212
 
213
  #: app/core/src/Forms/FormFields.php:52 app/core/src/Forms/SettingsForm.php:88
214
- #: app/features/events.php:2724 app/features/events.php:2813
215
  #: app/features/mec/booking.php:793 app/features/mec/booking.php:891
216
- #: app/features/mec/single.php:302 app/libraries/main.php:3896
217
  #: app/libraries/skins.php:1377
218
  msgid "Text"
219
  msgstr "Text"
@@ -224,13 +270,13 @@ msgstr "Text"
224
  #: app/core/src/Forms/FormFields.php:286 app/core/src/Forms/FormFields.php:317
225
  #: app/core/src/Forms/FormFields.php:348 app/core/src/Forms/FormFields.php:403
226
  #: app/core/src/Forms/FormFields.php:449 app/core/src/Forms/FormFields.php:495
227
- #: app/core/src/Forms/FormFields.php:551 app/libraries/main.php:3903
228
- #: app/libraries/main.php:3934 app/libraries/main.php:3964
229
- #: app/libraries/main.php:3994 app/libraries/main.php:4025
230
- #: app/libraries/main.php:4056 app/libraries/main.php:4086
231
- #: app/libraries/main.php:4117 app/libraries/main.php:4149
232
- #: app/libraries/main.php:4210 app/libraries/main.php:4258
233
- #: app/libraries/main.php:4306 app/libraries/main.php:4364
234
  msgid "Required Field"
235
  msgstr "Pflichtfeld"
236
 
@@ -242,21 +288,21 @@ msgstr "Pflichtfeld"
242
  #: app/core/src/Forms/FormFields.php:406 app/core/src/Forms/FormFields.php:452
243
  #: app/core/src/Forms/FormFields.php:505 app/core/src/Forms/FormFields.php:554
244
  #: app/core/src/Forms/FormFields.php:597 app/features/events.php:2121
245
- #: app/features/events.php:2147 app/features/events.php:2361
246
- #: app/features/events.php:2498 app/features/events.php:2535
247
  #: app/features/mec/booking.php:611 app/features/mec/booking.php:641
248
  #: app/features/mec/booking.php:709 app/features/mec/booking.php:741
249
  #: app/features/organizers.php:340 app/features/organizers.php:349
250
  #: app/libraries/hourlyschedule.php:53 app/libraries/hourlyschedule.php:74
251
  #: app/libraries/hourlyschedule.php:102 app/libraries/hourlyschedule.php:130
252
- #: app/libraries/hourlyschedule.php:154 app/libraries/main.php:3906
253
- #: app/libraries/main.php:3937 app/libraries/main.php:3967
254
- #: app/libraries/main.php:3997 app/libraries/main.php:4028
255
- #: app/libraries/main.php:4059 app/libraries/main.php:4089
256
- #: app/libraries/main.php:4120 app/libraries/main.php:4158
257
- #: app/libraries/main.php:4180 app/libraries/main.php:4213
258
- #: app/libraries/main.php:4261 app/libraries/main.php:4316
259
- #: app/libraries/main.php:4367 app/libraries/main.php:4407
260
  #: app/libraries/ticketVariations.php:72
261
  msgid "Remove"
262
  msgstr "Entfernen"
@@ -267,13 +313,13 @@ msgstr "Entfernen"
267
  #: app/core/src/Forms/FormFields.php:292 app/core/src/Forms/FormFields.php:323
268
  #: app/core/src/Forms/FormFields.php:354 app/core/src/Forms/FormFields.php:409
269
  #: app/core/src/Forms/FormFields.php:455 app/core/src/Forms/FormFields.php:508
270
- #: app/core/src/Forms/FormFields.php:557 app/libraries/main.php:3909
271
- #: app/libraries/main.php:3940 app/libraries/main.php:3970
272
- #: app/libraries/main.php:4000 app/libraries/main.php:4031
273
- #: app/libraries/main.php:4062 app/libraries/main.php:4092
274
- #: app/libraries/main.php:4123 app/libraries/main.php:4161
275
- #: app/libraries/main.php:4216 app/libraries/main.php:4264
276
- #: app/libraries/main.php:4319 app/libraries/main.php:4370
277
  msgid "Insert a label for this field"
278
  msgstr "Geben Sie eine Bezeichnung (Label) für dieses Feld ein."
279
 
@@ -289,97 +335,97 @@ msgstr "Vorname"
289
  msgid "MEC Last Name"
290
  msgstr "MEC Name"
291
 
292
- #: app/core/src/Forms/FormFields.php:93 app/features/events.php:2722
293
- #: app/features/mec/booking.php:791 app/libraries/main.php:3927
294
  msgid "MEC Name"
295
  msgstr "MEC Name"
296
 
297
  #: app/core/src/Forms/FormFields.php:158 app/core/src/Forms/SettingsForm.php:83
298
- #: app/features/events.php:2723 app/features/mec/booking.php:792
299
- #: app/libraries/main.php:3957
300
  msgid "MEC Email"
301
  msgstr "MEC Email"
302
 
303
  #: app/core/src/Forms/FormFields.php:219 app/features/mec/single.php:304
304
- #: app/libraries/main.php:4018
305
  msgid "URL"
306
  msgstr ""
307
 
308
  #: app/core/src/Forms/FormFields.php:250
309
- #: app/core/src/Forms/SettingsForm.php:108 app/features/events.php:2728
310
- #: app/features/mec/booking.php:797 app/libraries/main.php:4049
311
  msgid "File"
312
  msgstr "Datei"
313
 
314
  #: app/core/src/Forms/FormFields.php:280 app/core/src/Forms/SettingsForm.php:98
315
  #: app/core/src/SingleBuilder/Widgets/EventDate/EventDate.php:47
316
- #: app/features/events.php:1396 app/features/events.php:2726
317
- #: app/features/events.php:2815 app/features/fes.php:280
318
  #: app/features/mec/booking.php:795 app/features/mec/booking.php:893
319
  #: app/features/mec/single.php:305 app/features/profile/profile.php:59
320
- #: app/features/wc.php:79 app/libraries/main.php:4079
321
  #: app/libraries/skins.php:1289 app/modules/booking/steps/tickets.php:136
322
- #: app/modules/next-event/details.php:145 app/skins/single.php:1191
323
  #: app/skins/single/default.php:171 app/skins/single/default.php:423
324
  #: app/skins/single/m1.php:40 app/skins/single/modern.php:253
325
  msgid "Date"
326
  msgstr "Datum"
327
 
328
  #: app/core/src/Forms/FormFields.php:311
329
- #: app/core/src/Forms/SettingsForm.php:103 app/features/events.php:2727
330
- #: app/features/events.php:2816 app/features/mec/booking.php:796
331
  #: app/features/mec/booking.php:894 app/features/mec/single.php:306
332
  #: app/features/organizers.php:104 app/features/organizers.php:149
333
  #: app/features/speakers.php:120 app/features/speakers.php:201
334
- #: app/features/speakers.php:288 app/libraries/main.php:4110
335
  msgid "Tel"
336
  msgstr "Tel"
337
 
338
  #: app/core/src/Forms/FormFields.php:342
339
- #: app/core/src/Forms/SettingsForm.php:113 app/features/events.php:2729
340
- #: app/features/events.php:2817 app/features/mec/booking.php:798
341
  #: app/features/mec/booking.php:895 app/features/mec/single.php:307
342
- #: app/libraries/main.php:4141
343
  msgid "Textarea"
344
  msgstr "Textbereich"
345
 
346
  #: app/core/src/Forms/FormFields.php:373
347
- #: app/core/src/Forms/SettingsForm.php:138 app/features/events.php:2734
348
- #: app/features/events.php:2822 app/features/mec/booking.php:803
349
  #: app/features/mec/booking.php:900 app/features/mec/settings.php:351
350
- #: app/features/mec/single.php:308 app/libraries/main.php:4179
351
  msgid "Paragraph"
352
  msgstr "Absatz"
353
 
354
- #: app/core/src/Forms/FormFields.php:378 app/libraries/main.php:4185
355
  msgid "HTML and shortcode are allowed."
356
  msgstr "HTML und shortcodes sind erlaubt."
357
 
358
  #: app/core/src/Forms/FormFields.php:397
359
- #: app/core/src/Forms/SettingsForm.php:118 app/features/events.php:2730
360
- #: app/features/events.php:2818 app/features/mec/booking.php:127
361
  #: app/features/mec/booking.php:799 app/features/mec/booking.php:896
362
- #: app/features/mec/single.php:309 app/libraries/main.php:4203
363
  msgid "Checkboxes"
364
  msgstr "Checkboxes"
365
 
366
  #: app/core/src/Forms/FormFields.php:421 app/core/src/Forms/FormFields.php:467
367
- #: app/core/src/Forms/FormFields.php:520 app/libraries/main.php:4230
368
- #: app/libraries/main.php:4278 app/libraries/main.php:4333
369
  msgid "Option"
370
  msgstr "Option"
371
 
372
  #: app/core/src/Forms/FormFields.php:443
373
- #: app/core/src/Forms/SettingsForm.php:123 app/features/events.php:2731
374
- #: app/features/events.php:2819 app/features/mec/booking.php:800
375
  #: app/features/mec/booking.php:897 app/features/mec/single.php:310
376
- #: app/libraries/main.php:4251
377
  msgid "Radio Buttons"
378
  msgstr "Radio Buttons"
379
 
380
  #: app/core/src/Forms/FormFields.php:489
381
- #: app/core/src/Forms/SettingsForm.php:128 app/features/events.php:2732
382
- #: app/features/events.php:2820 app/features/mec/booking.php:125
383
  #: app/features/mec/booking.php:801 app/features/mec/booking.php:898
384
  #: app/features/mec/meta_boxes/search_form.php:67
385
  #: app/features/mec/meta_boxes/search_form.php:75
@@ -462,7 +508,7 @@ msgstr "Radio Buttons"
462
  #: app/features/mec/meta_boxes/search_form.php:1094
463
  #: app/features/mec/meta_boxes/search_form.php:1116
464
  #: app/features/mec/single.php:311 app/features/popup/settings.php:348
465
- #: app/libraries/main.php:4299
466
  msgid "Dropdown"
467
  msgstr "Dropdown"
468
 
@@ -471,40 +517,40 @@ msgid "Consider first item as placeholder"
471
  msgstr ""
472
 
473
  #: app/core/src/Forms/FormFields.php:545
474
- #: app/core/src/Forms/SettingsForm.php:133 app/features/events.php:2733
475
- #: app/features/events.php:2821 app/features/mec/booking.php:802
476
- #: app/features/mec/booking.php:899 app/libraries/main.php:4357
477
  msgid "Agreement"
478
  msgstr "Zustimmung"
479
 
480
- #: app/core/src/Forms/FormFields.php:557 app/libraries/main.php:4370
481
  #, php-format
482
  msgid "Instead of %s, the page title with a link will be show."
483
  msgstr "Anstelle von %s, wird der Seitentitel mit einem Link gezeigt"
484
 
485
  #: app/core/src/Forms/FormFields.php:559 app/features/mec/settings.php:1145
486
- #: app/libraries/main.php:4372
487
  msgid "Agreement Page"
488
  msgstr "Zustimmungsseite"
489
 
490
  #: app/core/src/Forms/FormFields.php:570 app/features/profile/profile.php:62
491
- #: app/libraries/main.php:4381
492
  msgid "Status"
493
  msgstr ""
494
 
495
- #: app/core/src/Forms/FormFields.php:572 app/libraries/main.php:4383
496
  msgid "Checked by default"
497
  msgstr ""
498
 
499
- #: app/core/src/Forms/FormFields.php:573 app/libraries/main.php:4384
500
  msgid "Unchecked by default"
501
  msgstr ""
502
 
503
- #: app/core/src/Forms/FormFields.php:598 app/libraries/main.php:4408
504
  msgid "Insert a label for this option"
505
  msgstr "Ein neues Label für diese Option einfügen"
506
 
507
- #: app/core/src/Forms/FormFields.php:606 app/libraries/main.php:8974
508
  msgid "Mapping with Profile Fields"
509
  msgstr ""
510
 
@@ -652,20 +698,25 @@ msgstr "Geben Sie mit Komma getrennte email-Adressen ein für mehrere Empfänger
652
  #: app/features/events.php:1404 app/features/events.php:1541
653
  #: app/features/events.php:1666 app/features/events.php:1836
654
  #: app/features/events.php:1849 app/features/events.php:2020
655
- #: app/features/events.php:2035 app/features/events.php:2278
656
- #: app/features/events.php:2291 app/features/events.php:2484
657
- #: app/features/events.php:2521 app/features/fes/form.php:458
658
  #: app/features/fes/form.php:766 app/features/fes/form.php:901
659
- #: app/features/locations.php:341 app/features/mec/booking.php:109
660
- #: app/features/mec/booking.php:185 app/features/mec/booking.php:198
661
- #: app/features/mec/booking.php:234 app/features/mec/booking.php:299
662
- #: app/features/mec/booking.php:332 app/features/mec/booking.php:345
663
- #: app/features/mec/booking.php:411 app/features/mec/booking.php:462
664
- #: app/features/mec/booking.php:598 app/features/mec/booking.php:628
665
- #: app/features/mec/booking.php:694 app/features/mec/booking.php:704
666
- #: app/features/mec/booking.php:726 app/features/mec/booking.php:736
667
- #: app/features/mec/booking.php:1001 app/features/mec/booking.php:1029
668
- #: app/features/mec/dashboard.php:73 app/features/mec/integrations.php:57
 
 
 
 
 
669
  #: app/features/mec/integrations.php:70 app/features/mec/integrations.php:86
670
  #: app/features/mec/meta_boxes/display_options.php:98
671
  #: app/features/mec/meta_boxes/display_options.php:111
@@ -737,7 +788,7 @@ msgstr "Geben Sie mit Komma getrennte email-Adressen ein für mehrere Empfänger
737
  #: app/features/popup/settings.php:78 app/features/popup/settings.php:161
738
  #: app/features/popup/settings.php:182 app/features/popup/settings.php:300
739
  #: app/libraries/ticketVariations.php:50 app/libraries/ticketVariations.php:65
740
- #: app/skins/single.php:1218 app/skins/single.php:1334
741
  #: app/skins/single/default.php:25 app/skins/single/m1.php:16
742
  #: app/skins/single/m2.php:16 app/skins/single/modern.php:26
743
  msgid "Read More"
@@ -857,7 +908,7 @@ msgid "How to set category"
857
  msgstr ""
858
 
859
  #: app/core/src/SingleBuilder/Widgets/EventCategories/EventCategories.php:47
860
- #: app/features/events.php:218 app/features/events.php:3854
861
  #: app/features/mec/meta_boxes/display_options.php:1657
862
  #: app/features/mec/meta_boxes/search_form.php:64
863
  #: app/features/mec/meta_boxes/search_form.php:152
@@ -874,8 +925,8 @@ msgstr ""
874
  #: app/features/mec/settings.php:1165 app/features/mec/settings.php:1228
875
  #: app/features/mec/single.php:460 app/features/mec/single.php:513
876
  #: app/features/popup/settings.php:220 app/features/popup/settings.php:259
877
- #: app/features/search.php:91 app/libraries/main.php:7401
878
- #: app/libraries/main.php:7462 app/libraries/search.php:256
879
  #: app/libraries/skins.php:1090 app/skins/single.php:1090
880
  #: app/skins/single/default.php:299 app/skins/single/default.php:549
881
  #: app/skins/single/m1.php:231 app/skins/single/m2.php:151
@@ -898,9 +949,9 @@ msgstr ""
898
  #: app/core/src/SingleBuilder/Widgets/EventCost/EventCost.php:47
899
  #: app/features/events.php:432 app/features/events.php:1283
900
  #: app/features/fes/form.php:868 app/features/mec/settings.php:1162
901
- #: app/features/occurrences.php:511 app/libraries/main.php:7447
902
- #: app/libraries/main.php:7494 app/libraries/skins.php:1405
903
- #: app/skins/single.php:1123 app/skins/single/default.php:215
904
  #: app/skins/single/default.php:467 app/skins/single/m1.php:80
905
  #: app/skins/single/modern.php:293
906
  msgid "Cost"
@@ -977,11 +1028,11 @@ msgid "How to set label"
977
  msgstr ""
978
 
979
  #: app/core/src/SingleBuilder/Widgets/EventLabels/EventLabels.php:48
980
- #: app/features/events.php:4176 app/features/fes/form.php:998
981
  #: app/features/labels.php:61 app/features/labels.php:227
982
- #: app/features/mec.php:495 app/features/mec/meta_boxes/filter.php:72
983
- #: app/features/mec/meta_boxes/filter.php:135 app/libraries/main.php:7402
984
- #: app/libraries/main.php:7463 app/skins/single.php:1253
985
  #: app/skins/single/default.php:247 app/skins/single/default.php:496
986
  #: app/skins/single/m1.php:95 app/skins/single/modern.php:308
987
  msgid "Labels"
@@ -1013,7 +1064,7 @@ msgid "How to set location"
1013
  msgstr "Ort verbergen"
1014
 
1015
  #: app/core/src/SingleBuilder/Widgets/EventLocations/EventLocations.php:54
1016
- #: app/features/events.php:3855 app/features/events.php:4169
1017
  #: app/features/locations.php:58 app/features/locations.php:267
1018
  #: app/features/locations.php:329 app/features/locations.php:331
1019
  #: app/features/locations.php:340
@@ -1036,10 +1087,10 @@ msgstr "Ort verbergen"
1036
  #: app/features/popup/event.php:118 app/features/popup/event.php:127
1037
  #: app/features/popup/settings.php:228 app/features/popup/settings.php:267
1038
  #: app/features/search.php:97 app/libraries/main.php:2961
1039
- #: app/libraries/main.php:3238 app/libraries/main.php:7405
1040
- #: app/libraries/main.php:7466 app/libraries/search.php:294
1041
  #: app/libraries/skins.php:1145 app/skins/single.php:1017
1042
- #: app/skins/single.php:1525 app/skins/single/default.php:268
1043
  #: app/skins/single/default.php:519 app/skins/single/m1.php:201
1044
  #: app/skins/single/m2.php:121 app/skins/single/modern.php:153
1045
  msgid "Location"
@@ -1048,7 +1099,7 @@ msgstr "Ort"
1048
  #: app/core/src/SingleBuilder/Widgets/EventLocations/EventLocations.php:63
1049
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:77
1050
  #: app/features/speakers.php:136 app/features/speakers.php:209
1051
- #: app/skins/single.php:1406 app/skins/single.php:1473
1052
  #: app/skins/single/default.php:276 app/skins/single/default.php:354
1053
  #: app/skins/single/default.php:526 app/skins/single/default.php:603
1054
  #: app/skins/single/m1.php:148 app/skins/single/m1.php:209
@@ -1071,8 +1122,8 @@ msgstr ""
1071
  #: app/core/src/SingleBuilder/Widgets/EventMoreInfo/EventMoreInfo.php:48
1072
  #: app/features/events.php:1525 app/features/events.php:1538
1073
  #: app/features/fes/form.php:836 app/features/occurrences.php:525
1074
- #: app/libraries/main.php:7445 app/libraries/main.php:7492
1075
- #: app/skins/single.php:1223 app/skins/single/default.php:232
1076
  #: app/skins/single/default.php:481 app/skins/single/m1.php:257
1077
  #: app/skins/single/m2.php:178 app/skins/single/modern.php:211
1078
  #: app/widgets/single.php:105
@@ -1120,9 +1171,9 @@ msgid "How to set organizer"
1120
  msgstr "Veranstalter verbergen"
1121
 
1122
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:53
1123
- #: app/features/events.php:431 app/features/events.php:3856
1124
- #: app/features/events.php:4171 app/features/events.php:4172
1125
- #: app/features/events.php:4173
1126
  #: app/features/mec/meta_boxes/display_options.php:1660
1127
  #: app/features/mec/meta_boxes/search_form.php:80
1128
  #: app/features/mec/meta_boxes/search_form.php:168
@@ -1144,16 +1195,16 @@ msgstr "Veranstalter verbergen"
1144
  #: app/features/organizers.php:288 app/features/popup/event.php:165
1145
  #: app/features/popup/event.php:174 app/features/popup/settings.php:224
1146
  #: app/features/popup/settings.php:263 app/features/search.php:103
1147
- #: app/libraries/main.php:7407 app/libraries/main.php:7468
1148
  #: app/libraries/search.php:314 app/libraries/skins.php:1174
1149
- #: app/skins/single.php:1381 app/skins/single/default.php:329
1150
  #: app/skins/single/default.php:578 app/skins/single/m1.php:123
1151
  #: app/skins/single/m2.php:43 app/skins/single/modern.php:76
1152
  msgid "Organizer"
1153
  msgstr "Veranstalter"
1154
 
1155
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:63
1156
- #: app/skins/single.php:1392 app/skins/single.php:1459
1157
  #: app/skins/single/default.php:340 app/skins/single/default.php:589
1158
  #: app/skins/single/m1.php:134 app/skins/single/m2.php:54
1159
  #: app/skins/single/modern.php:87
@@ -1187,13 +1238,13 @@ msgid "How to set register button"
1187
  msgstr "Register Button"
1188
 
1189
  #: app/core/src/SingleBuilder/Widgets/EventRegisterButton/EventRegisterButton.php:48
1190
- #: app/libraries/main.php:7441 app/libraries/main.php:7488
1191
  #: app/skins/available_spot/tpl.php:204 app/skins/carousel/render.php:105
1192
  #: app/skins/carousel/render.php:145 app/skins/grid/render.php:94
1193
  #: app/skins/grid/render.php:153 app/skins/grid/render.php:214
1194
  #: app/skins/grid/render.php:237 app/skins/list/render.php:90
1195
  #: app/skins/list/render.php:210 app/skins/masonry/render.php:151
1196
- #: app/skins/single.php:548 app/skins/single.php:1329 app/skins/single.php:1340
1197
  #: app/skins/single/default.php:374 app/skins/single/default.php:376
1198
  #: app/skins/single/default.php:621 app/skins/single/default.php:623
1199
  #: app/skins/single/m1.php:166 app/skins/single/m1.php:168
@@ -1258,7 +1309,7 @@ msgstr "Tags:"
1258
  #: app/core/src/SingleBuilder/Widgets/EventTime/EventTime.php:43
1259
  #: app/features/emails/details.php:24 app/features/emails/details.php:27
1260
  #: app/libraries/skins.php:1362 app/modules/next-event/details.php:151
1261
- #: app/skins/single.php:1297 app/skins/single/default.php:190
1262
  #: app/skins/single/default.php:442 app/skins/single/m1.php:59
1263
  #: app/skins/single/modern.php:272
1264
  msgid "Time"
@@ -1266,14 +1317,14 @@ msgstr "Uhrzeit"
1266
 
1267
  #: app/core/src/SingleBuilder/Widgets/EventTime/EventTime.php:49
1268
  #: app/features/booking/calendar_novel.php:140
1269
- #: app/features/search_bar/search_result.php:12 app/libraries/main.php:7450
1270
- #: app/libraries/main.php:7497 app/libraries/notifications.php:1632
1271
  #: app/libraries/render.php:554 app/libraries/render.php:758
1272
  #: app/libraries/render.php:816 app/libraries/render.php:977
1273
  #: app/modules/local-time/details.php:52 app/modules/local-time/type1.php:47
1274
  #: app/modules/local-time/type2.php:83 app/modules/local-time/type3.php:47
1275
  #: app/modules/next-event/details.php:157
1276
- #: app/modules/next-event/multiple.php:65 app/skins/single.php:1303
1277
  #: app/skins/single/default.php:196 app/skins/single/default.php:448
1278
  #: app/skins/single/m1.php:65 app/skins/single/modern.php:278
1279
  #, fuzzy
@@ -1315,7 +1366,7 @@ msgstr "% s Erinnerungen gesendet."
1315
  msgid "%s notification(s) sent."
1316
  msgstr "Benachrichtigungen"
1317
 
1318
- #: app/features/autoemails.php:61 app/features/mec.php:512
1319
  #, fuzzy
1320
  #| msgid "Email"
1321
  msgid "Emails"
@@ -1375,7 +1426,12 @@ msgstr ""
1375
  msgid "Coupon was not valid or applicable."
1376
  msgstr ""
1377
 
1378
- #: app/features/cart.php:174
 
 
 
 
 
1379
  msgid "Request is invalid!"
1380
  msgstr "Die Anfrage ist ungültig!"
1381
 
@@ -1383,7 +1439,7 @@ msgstr "Die Anfrage ist ungültig!"
1383
  msgid "Your cart is not free!"
1384
  msgstr ""
1385
 
1386
- #: app/features/cart.php:191
1387
  #, fuzzy
1388
  #| msgid "Thanks for your booking."
1389
  msgid "Thanks for your booking."
@@ -1401,7 +1457,7 @@ msgstr "Standart ist leer "
1401
  msgid "Go to events page"
1402
  msgstr "Google Maps auf der Veranstaltungsseite anzeigen"
1403
 
1404
- #: app/features/cart/cart.php:43 app/features/events.php:4715
1405
  #: app/features/fes.php:280 app/features/mec/booking.php:351
1406
  #: app/features/wc.php:81 app/libraries/main.php:3013
1407
  #: app/libraries/main.php:3127 app/libraries/main.php:3230
@@ -1422,7 +1478,7 @@ msgstr "Veranstaltung"
1422
 
1423
  #: app/features/cart/cart.php:45 app/features/events.php:1564
1424
  #: app/features/events.php:1930 app/libraries/book.php:172
1425
- #: app/libraries/main.php:7435 app/modules/booking/steps/tickets.php:168
1426
  #: app/modules/booking/steps/tickets.php:174
1427
  msgid "Tickets"
1428
  msgstr "Tickets"
@@ -1467,13 +1523,14 @@ msgid "Free %s"
1467
  msgstr "kostenfrei"
1468
 
1469
  #: app/features/cart/checkout.php:96 app/features/contextual.php:308
1470
- #: app/features/events.php:397 app/features/mec/booking.php:88
1471
- #: app/features/mec/notifications.php:45 app/features/mec/support-page.php:110
1472
- #: app/features/mec/support-page.php:114 app/libraries/main.php:647
1473
- #: app/libraries/main.php:648 app/libraries/main.php:652
1474
- #: app/libraries/main.php:677 app/libraries/main.php:795
1475
- #: app/libraries/main.php:3022 app/libraries/main.php:7425
1476
- #: app/libraries/main.php:7427 app/modules/booking/steps/checkout.php:146
 
1477
  msgid "Booking"
1478
  msgstr "Buchung / Reservierung"
1479
 
@@ -1494,8 +1551,8 @@ msgstr "Farbe der Veranstaltung"
1494
  msgid "Recent Colors"
1495
  msgstr "Farbe der Veranstaltung"
1496
 
1497
- #: app/features/contextual.php:55 app/features/mec.php:516
1498
- #: app/features/mec/dashboard.php:143 app/features/mec/support.php:20
1499
  #: app/features/mec/wizard.php:521 app/features/popup/event.php:61
1500
  #: app/features/popup/settings.php:30 app/features/popup/shortcode.php:39
1501
  #: app/libraries/main.php:703
@@ -1503,8 +1560,8 @@ msgid "Settings"
1503
  msgstr "Einstellungen"
1504
 
1505
  #: app/features/contextual.php:62 app/features/events.php:1571
1506
- #: app/features/events.php:2663 app/features/mec/booking.php:756
1507
- #: app/features/mec/booking.php:1027 app/features/mec/settings.php:1018
1508
  #: app/features/mec/support.php:29
1509
  msgid "Booking Form"
1510
  msgstr "Buchungsformular"
@@ -1684,7 +1741,7 @@ msgid "Exceptional Days"
1684
  msgstr "Herausgenommene Tage "
1685
 
1686
  #: app/features/contextual.php:318 app/features/mec/booking.php:553
1687
- #: app/features/mec/booking.php:984 app/libraries/main.php:649
1688
  msgid "Coupons"
1689
  msgstr "Gutscheine"
1690
 
@@ -1707,40 +1764,61 @@ msgstr "MEC Aktivierung"
1707
  msgid "Downloadable File"
1708
  msgstr "Download ICS Datei"
1709
 
1710
- #: app/features/dlfile.php:142 app/features/dlfile.php:288
1711
  msgid "pdf,zip,png,jpg and gif files are allowed."
1712
  msgstr ""
1713
 
1714
- #: app/features/dlfile.php:144 app/features/dlfile.php:290
1715
  #, fuzzy
1716
  #| msgid "Remove image"
1717
  msgid "Remove File"
1718
  msgstr "Bild entfernen"
1719
 
1720
- #: app/features/dlfile.php:162 app/features/dlfile.php:308
1721
  msgid "Please upload a file."
1722
  msgstr ""
1723
 
1724
- #: app/features/dlfile.php:170 app/features/dlfile.php:316
1725
  #, php-format
1726
  msgid "File extension is invalid. You can upload %s files."
1727
  msgstr ""
1728
 
1729
- #: app/features/dlfile.php:176 app/features/dlfile.php:322
1730
  #, php-format
1731
  msgid "File is too big. Maximum size is %s KB."
1732
  msgstr ""
1733
 
1734
- #: app/features/dlfile.php:206 app/features/dlfile.php:352
1735
  #, fuzzy
1736
  #| msgid "The image is uploaded!"
1737
  msgid "File uploaded!"
1738
  msgstr "Das Bild ist hochgeladen"
1739
 
1740
- #: app/features/dlfile.php:284
1741
  msgid "Public File to Download"
1742
  msgstr ""
1743
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1744
  #: app/features/emails/details.php:26
1745
  #, fuzzy
1746
  #| msgid "Send Email"
@@ -1793,8 +1871,8 @@ msgid "event occurrence."
1793
  msgstr "Nächstes Event"
1794
 
1795
  #: app/features/emails/details.php:40 app/features/events.php:192
1796
- #: app/features/ix/export.php:37 app/features/mec/dashboard.php:234
1797
- #: app/libraries/main.php:6428 app/libraries/main.php:6448
1798
  #: app/skins/daily_view/tpl.php:84 app/skins/monthly_view/calendar_clean.php:46
1799
  #: app/skins/monthly_view/tpl.php:76 app/skins/tile/tpl.php:85
1800
  #: app/skins/yearly_view/tpl.php:73
@@ -1809,12 +1887,12 @@ msgstr "Alle Veranstaltungen"
1809
  msgid "Placeholders"
1810
  msgstr ""
1811
 
1812
- #: app/features/events.php:194 app/features/mec.php:492
1813
  #: app/features/mec/wizard.php:511
1814
  msgid "Add Event"
1815
  msgstr "Veranstaltung hinzufügen"
1816
 
1817
- #: app/features/events.php:195 app/features/mec/dashboard.php:142
1818
  msgid "Add New Event"
1819
  msgstr "Neue Veranstaltung hinzufügen"
1820
 
@@ -1837,11 +1915,11 @@ msgstr "Veranstaltung ansehen"
1837
  msgid "No events found in Trash!"
1838
  msgstr "Keine Veranstaltungen im Papierkorb gefunden!"
1839
 
1840
- #: app/features/events.php:219 app/features/events.php:3810
1841
- #: app/features/events.php:4177 app/features/fes/form.php:972
1842
- #: app/features/mec.php:494 app/features/mec/meta_boxes/filter.php:69
1843
- #: app/features/mec/meta_boxes/filter.php:81 app/libraries/main.php:7400
1844
- #: app/libraries/main.php:7461
1845
  msgid "Categories"
1846
  msgstr "Kategorien"
1847
 
@@ -1958,7 +2036,7 @@ msgid "Event Data"
1958
  msgstr "Veranstaltungsdetails"
1959
 
1960
  #: app/features/events.php:428 app/features/mec/settings.php:943
1961
- #: app/libraries/hourlyschedule.php:36 app/skins/single.php:1565
1962
  msgid "Hourly Schedule"
1963
  msgstr "Stundenplan"
1964
 
@@ -1990,11 +2068,14 @@ msgstr "Zusätzliche Anmerkungen zum Event "
1990
  msgid "Guest Data"
1991
  msgstr "Gäste Daten"
1992
 
1993
- #: app/features/events.php:605 app/features/events.php:2649
1994
- #: app/features/events.php:4419 app/features/fes.php:280
1995
- #: app/features/fes/form.php:814 app/features/labels.php:184
 
 
 
1996
  #: app/features/mec/booking.php:45 app/features/organizers.php:296
1997
- #: app/features/popup/event.php:184 app/features/profile/profile.php:192
1998
  #: app/libraries/notifications.php:2090 app/modules/booking/steps/form.php:60
1999
  msgid "Name"
2000
  msgstr "Name"
@@ -2010,9 +2091,9 @@ msgid "Date and Time"
2010
  msgstr "Datum und Uhrzeit"
2011
 
2012
  #: app/features/events.php:622 app/features/events.php:626
2013
- #: app/features/events.php:3857 app/features/events.php:4164
2014
  #: app/features/fes/form.php:286 app/features/fes/form.php:290
2015
- #: app/features/ix/import_g_calendar.php:38 app/features/mec.php:1525
2016
  #: app/features/mec/meta_boxes/display_options.php:57
2017
  #: app/features/mec/meta_boxes/display_options.php:312
2018
  #: app/features/mec/meta_boxes/display_options.php:578
@@ -2034,9 +2115,9 @@ msgid "Start Date"
2034
  msgstr "Start Datum"
2035
 
2036
  #: app/features/events.php:642 app/features/events.php:646
2037
- #: app/features/events.php:3858 app/features/events.php:4166
2038
  #: app/features/fes/form.php:306 app/features/fes/form.php:310
2039
- #: app/features/ix/import_g_calendar.php:44 app/features/mec.php:1526
2040
  #: app/features/mec/meta_boxes/display_options.php:73
2041
  #: app/features/mec/meta_boxes/display_options.php:328
2042
  #: app/features/mec/meta_boxes/display_options.php:594
@@ -2091,8 +2172,8 @@ msgstr "Zeitzone: %s"
2091
  #: app/features/events.php:716 app/features/events.php:729
2092
  #: app/features/events.php:1768 app/features/events.php:1778
2093
  #: app/features/events.php:1799 app/features/events.php:1819
2094
- #: app/features/events.php:1874 app/features/events.php:2446
2095
- #: app/features/events.php:2569 app/features/events.php:2680
2096
  #: app/features/fes/form.php:347 app/features/fes/form.php:360
2097
  msgid "Inherit from global options"
2098
  msgstr "Aus den globalen Einstellungen übernehmen"
@@ -2154,7 +2235,7 @@ msgid "Repeats"
2154
  msgstr "Wiederholend"
2155
 
2156
  #: app/features/events.php:770 app/features/fes/form.php:390
2157
- #: app/features/mec.php:1528 app/skins/default_full_calendar/tpl.php:79
2158
  #: app/skins/full_calendar/tpl.php:140
2159
  msgid "Daily"
2160
  msgstr "Täglich"
@@ -2178,13 +2259,13 @@ msgid "Weekly"
2178
  msgstr "Wöchentlich"
2179
 
2180
  #: app/features/events.php:805 app/features/fes/form.php:395
2181
- #: app/features/mec.php:1529 app/skins/default_full_calendar/tpl.php:77
2182
  #: app/skins/full_calendar/tpl.php:138
2183
  msgid "Monthly"
2184
  msgstr "Monatlich"
2185
 
2186
  #: app/features/events.php:812 app/features/fes/form.php:396
2187
- #: app/features/mec.php:1530 app/skins/default_full_calendar/tpl.php:76
2188
  #: app/skins/full_calendar/tpl.php:137
2189
  msgid "Yearly"
2190
  msgstr "Jährlich"
@@ -2218,7 +2299,7 @@ msgid ""
2218
  msgstr "Pro Version vom Modernen Event Calendar"
2219
 
2220
  #: app/features/events.php:860 app/features/events.php:2107
2221
- #: app/features/events.php:2135 app/features/events.php:2351
2222
  #: app/features/fes/form.php:420 app/features/ix/import_f_calendar.php:42
2223
  #: app/features/ix/import_g_calendar.php:51
2224
  #: app/features/ix/import_meetup.php:40 app/features/ix/thirdparty.php:35
@@ -2228,8 +2309,8 @@ msgstr "Start"
2228
 
2229
  #: app/features/events.php:874 app/features/events.php:1398
2230
  #: app/features/events.php:2091 app/features/events.php:2173
2231
- #: app/features/events.php:2340 app/features/events.php:2384
2232
- #: app/features/events.php:2457 app/features/events.php:2574
2233
  #: app/features/fes/form.php:451 app/features/fes/form.php:1070
2234
  #: app/features/occurrences.php:113 app/features/organizers.php:340
2235
  #: app/libraries/hourlyschedule.php:57 app/libraries/hourlyschedule.php:134
@@ -2248,7 +2329,7 @@ msgid ""
2248
  msgstr ""
2249
 
2250
  #: app/features/events.php:891 app/features/events.php:2111
2251
- #: app/features/events.php:2139 app/features/events.php:2355
2252
  #: app/features/fes/form.php:436 app/libraries/skins.php:1356
2253
  msgid "End"
2254
  msgstr "Ende"
@@ -2308,7 +2389,7 @@ msgstr ""
2308
  msgid "Show only one occurrence of this event"
2309
  msgstr "Nächstes Auftreten von anderen Events."
2310
 
2311
- #: app/features/events.php:1277 app/features/events.php:4174
2312
  #: app/features/fes/form.php:865
2313
  #: app/features/mec/meta_boxes/search_form.php:116
2314
  #: app/features/mec/meta_boxes/search_form.php:204
@@ -2334,7 +2415,7 @@ msgstr "Nächstes Auftreten von anderen Events."
2334
  #: app/features/mec/notifications.php:1628
2335
  #: app/features/mec/notifications.php:1778 app/features/mec/settings.php:860
2336
  #: app/features/notifications.php:160 app/features/occurrences.php:508
2337
- #: app/libraries/main.php:7446 app/libraries/main.php:7493
2338
  #: app/widgets/single.php:101
2339
  msgid "Event Cost"
2340
  msgstr ""
@@ -2435,8 +2516,8 @@ msgstr "Veranstaltungslinks"
2435
 
2436
  #: app/features/events.php:1507 app/features/events.php:1515
2437
  #: app/features/fes/form.php:831 app/features/mec/settings.php:1163
2438
- #: app/features/occurrences.php:520 app/libraries/main.php:7444
2439
- #: app/libraries/main.php:7491
2440
  msgid "Event Link"
2441
  msgstr "Veranstaltungslink"
2442
 
@@ -2470,13 +2551,13 @@ msgid "More Information"
2470
  msgstr "z.B. Noch mehr Informationen "
2471
 
2472
  #: app/features/events.php:1533 app/features/fes/form.php:840
2473
- #: app/features/mec.php:1084 app/features/occurrences.php:529
2474
  #: app/features/popup/shortcode.php:481
2475
  msgid "Current Window"
2476
  msgstr "Aktuelles Fenster"
2477
 
2478
  #: app/features/events.php:1534 app/features/fes/form.php:841
2479
- #: app/features/mec.php:1085 app/features/occurrences.php:530
2480
  #: app/features/popup/shortcode.php:485
2481
  msgid "New Window"
2482
  msgstr "Neues Fenster"
@@ -2503,16 +2584,16 @@ msgstr "Buchungsoptionen"
2503
  msgid "Total User Booking Limits"
2504
  msgstr "Gesamt Verfügbare Plätze"
2505
 
2506
- #: app/features/events.php:1566 app/features/events.php:2434
2507
  msgid "Fees"
2508
  msgstr "Gebühren"
2509
 
2510
- #: app/features/events.php:1569 app/features/events.php:2564
2511
  #: app/features/mec/settings.php:1030
2512
  msgid "Ticket Variations / Options"
2513
  msgstr ""
2514
 
2515
- #: app/features/events.php:1573 app/features/mec/booking.php:1058
2516
  #: app/features/mec/support-page.php:118
2517
  #, fuzzy
2518
  #| msgid "Organizer Tel"
@@ -2520,7 +2601,7 @@ msgid "Organizer Payment"
2520
  msgstr "Organisator Telefon"
2521
 
2522
  #: app/features/events.php:1581 app/features/ix/export.php:58
2523
- #: app/libraries/main.php:7428
2524
  msgid "Bookings"
2525
  msgstr "Buchungen / Reservierungen"
2526
 
@@ -2531,7 +2612,7 @@ msgid "Total booking limit"
2531
  msgstr "Gesamt Verfügbare Plätze"
2532
 
2533
  #: app/features/events.php:1659 app/features/events.php:2057
2534
- #: app/features/events.php:2306 app/modules/booking/default.php:116
2535
  #: app/modules/booking/default.php:221
2536
  #: app/modules/booking/steps/tickets.php:168
2537
  #: app/modules/booking/steps/tickets.php:174
@@ -2627,9 +2708,10 @@ msgid "Email Verification"
2627
  msgstr "Email-Verifizierung"
2628
 
2629
  #: app/features/events.php:1769 app/features/events.php:1779
2630
- #: app/features/mec/booking.php:210 app/features/mec/booking.php:277
2631
- #: app/features/mec/booking.php:292 app/features/mec/booking.php:374
2632
- #: app/features/mec/booking.php:995 app/features/mec/booking.php:1022
 
2633
  #: app/features/mec/meta_boxes/search_form.php:66
2634
  #: app/features/mec/meta_boxes/search_form.php:74
2635
  #: app/features/mec/meta_boxes/search_form.php:82
@@ -2766,10 +2848,11 @@ msgid "Disabled"
2766
  msgstr "Deaktiviert"
2767
 
2768
  #: app/features/events.php:1770 app/features/events.php:1780
2769
- #: app/features/mec/booking.php:209 app/features/mec/booking.php:276
2770
- #: app/features/mec/booking.php:293 app/features/mec/booking.php:994
2771
- #: app/features/mec/booking.php:1023 app/features/mec/modules.php:155
2772
- #: app/features/mec/settings.php:99 app/features/popup/settings.php:357
 
2773
  msgid "Enabled"
2774
  msgstr "Aktiviert"
2775
 
@@ -2858,7 +2941,7 @@ msgid "Ticket ID"
2858
  msgstr "Ticket"
2859
 
2860
  #: app/features/events.php:1950 app/features/events.php:2217
2861
- #: app/features/events.php:4161 app/features/fes.php:280
2862
  #: app/features/labels.php:183 app/features/locations.php:266
2863
  #: app/features/organizers.php:207 app/features/speakers.php:285
2864
  msgid "ID"
@@ -2869,21 +2952,15 @@ msgid "Ticket Name"
2869
  msgstr "Ticket Name"
2870
 
2871
  #: app/features/events.php:1962 app/features/events.php:2225
2872
- #: app/features/events.php:4165 app/libraries/skins.php:1370
2873
  msgid "Start Time"
2874
  msgstr "Uhrzeit des Beginns"
2875
 
2876
  #: app/features/events.php:1976 app/features/events.php:2239
2877
- #: app/features/events.php:4167 app/libraries/skins.php:1371
2878
  msgid "End Time"
2879
  msgstr "Uhrzeit Ende"
2880
 
2881
- #: app/features/events.php:1994 app/features/events.php:2254
2882
- #: app/features/events.php:4163 app/libraries/hourlyschedule.php:72
2883
- #: app/libraries/hourlyschedule.php:100 app/libraries/hourlyschedule.php:152
2884
- msgid "Description"
2885
- msgstr "Beschreibung"
2886
-
2887
  #: app/features/events.php:2000 app/features/events.php:2003
2888
  #: app/features/events.php:2259 app/features/events.php:2262
2889
  #: app/features/mec/settings.php:1012
@@ -2901,8 +2978,8 @@ msgstr ""
2901
 
2902
  #: app/features/events.php:2013 app/features/events.php:2017
2903
  #: app/features/events.php:2115 app/features/events.php:2142
2904
- #: app/features/events.php:2272 app/features/events.php:2275
2905
- #: app/features/events.php:2357 app/features/events.php:4718
2906
  #: app/features/mec/booking.php:690 app/features/mec/booking.php:693
2907
  #: app/features/mec/booking.php:722 app/features/mec/booking.php:725
2908
  #: app/libraries/ticketVariations.php:43 app/libraries/ticketVariations.php:46
@@ -2910,7 +2987,7 @@ msgstr ""
2910
  msgid "Price"
2911
  msgstr "Preis"
2912
 
2913
- #: app/features/events.php:2018 app/features/events.php:2276
2914
  #, fuzzy
2915
  #| msgid "Insert 0 for free ticket. Only numbers please."
2916
  msgid ""
@@ -2919,54 +2996,54 @@ msgid ""
2919
  msgstr "Bitte 0 für kostenloses Ticket eingeben. Bitte nur Zahlen eintragen"
2920
 
2921
  #: app/features/events.php:2027 app/features/events.php:2032
2922
- #: app/features/events.php:2285 app/features/events.php:2288
2923
  msgid "Price Label"
2924
  msgstr "Preisschild"
2925
 
2926
- #: app/features/events.php:2033 app/features/events.php:2289
2927
  msgid "For showing on website. e.g. $15"
2928
  msgstr "Um das auf der Webseite anzuzeigen zum Beispiel 15 €"
2929
 
2930
- #: app/features/events.php:2044 app/features/events.php:2300
2931
  msgid "Available Tickets"
2932
  msgstr "Verfügbare Tickets: %s "
2933
 
2934
- #: app/features/events.php:2063 app/features/events.php:2312
2935
  msgid "Minimum Ticket e.g. 3"
2936
  msgstr "Ticket minimum z.B. 3"
2937
 
2938
- #: app/features/events.php:2066 app/features/events.php:2315
2939
  msgid "MinimumTicket"
2940
  msgstr "Ticket minimum"
2941
 
2942
- #: app/features/events.php:2068 app/features/events.php:2317
2943
  msgid "Set a number for the minimum ticket reservation possible"
2944
  msgstr ""
2945
 
2946
- #: app/features/events.php:2077 app/features/events.php:2326
2947
  msgid "e.g. 0"
2948
  msgstr "z.B. 0"
2949
 
2950
- #: app/features/events.php:2079 app/features/events.php:2328
2951
  msgid "Day"
2952
  msgstr "Tag"
2953
 
2954
- #: app/features/events.php:2080 app/features/events.php:2329
2955
  #: app/features/mec/notifications.php:1734
2956
  msgid "Hour"
2957
  msgstr "Stunde"
2958
 
2959
- #: app/features/events.php:2082 app/features/events.php:2331
2960
  #, php-format
2961
  msgid "Stop selling ticket %s before event start."
2962
  msgstr ""
2963
 
2964
- #: app/features/events.php:2089 app/features/events.php:2338
2965
  msgid "Price per Date"
2966
  msgstr "Preis pro Datum"
2967
 
2968
  #: app/features/events.php:2119 app/features/events.php:2145
2969
- #: app/features/events.php:2359 app/features/labels.php:60
2970
  #: app/features/mec/meta_boxes/display_options.php:1658
2971
  #: app/features/mec/meta_boxes/search_form.php:101
2972
  #: app/features/mec/meta_boxes/search_form.php:189
@@ -2988,31 +3065,32 @@ msgstr "Preis pro Datum"
2988
  msgid "Label"
2989
  msgstr "Label"
2990
 
2991
- #: app/features/events.php:2163 app/features/events.php:2374
2992
  #, fuzzy
2993
  #| msgid "Maximum Per Ticket"
2994
  msgid "Variations Per Ticket"
2995
  msgstr "Maximum pro Ticket"
2996
 
2997
- #: app/features/events.php:2168 app/features/events.php:2379
2998
  #, fuzzy
2999
  #| msgid "Inherit from global options"
3000
  msgid "Inherit from event options"
3001
  msgstr "Aus den globalen Einstellungen übernehmen"
3002
 
3003
- #: app/features/events.php:2471 app/features/events.php:2510
3004
  #: app/features/mec/booking.php:590 app/features/mec/booking.php:620
3005
  msgid "Fee Title"
3006
  msgstr "Gebühren Name"
3007
 
3008
- #: app/features/events.php:2477 app/features/events.php:2481
3009
- #: app/features/events.php:2515 app/features/events.php:2518
3010
- #: app/features/mec/booking.php:594 app/features/mec/booking.php:597
3011
- #: app/features/mec/booking.php:624 app/features/mec/booking.php:627
 
3012
  msgid "Amount"
3013
  msgstr "Betrag"
3014
 
3015
- #: app/features/events.php:2482 app/features/events.php:2519
3016
  #: app/features/mec/booking.php:598 app/features/mec/booking.php:628
3017
  msgid ""
3018
  "Fee amount, considered as fixed amount if you set the type to amount "
@@ -3021,157 +3099,148 @@ msgstr ""
3021
  "Gebührenbetrag, gilt als fester Betrag, wenn Sie die Art auf Betrag setzen, "
3022
  "sonst als Prozentsatz"
3023
 
3024
- #: app/features/events.php:2491 app/features/events.php:2528
3025
- #: app/features/mec/booking.php:605 app/features/mec/booking.php:635
 
3026
  msgid "Percent"
3027
  msgstr "Prozent"
3028
 
3029
- #: app/features/events.php:2492 app/features/events.php:2529
3030
  #: app/features/mec/booking.php:606 app/features/mec/booking.php:636
3031
  msgid "Amount (Per Ticket)"
3032
  msgstr "Betrag (pro Ticket)"
3033
 
3034
- #: app/features/events.php:2493 app/features/events.php:2530
3035
  #: app/features/mec/booking.php:607 app/features/mec/booking.php:637
3036
  #, fuzzy
3037
  #| msgid "Amount (Per Ticket)"
3038
  msgid "Amount (Per Date)"
3039
  msgstr "Betrag (pro Ticket)"
3040
 
3041
- #: app/features/events.php:2494 app/features/events.php:2531
3042
  #: app/features/mec/booking.php:608 app/features/mec/booking.php:638
3043
  msgid "Amount (Per Booking)"
3044
  msgstr "Betrag (pro Buchung)"
3045
 
3046
- #: app/features/events.php:2666
3047
  msgid ""
3048
  "You're translating an event so MEC will use the original event for booking "
3049
  "form. You can only translate the field name and options. Please define exact "
3050
  "fields that you defined in the original event here."
3051
  msgstr ""
3052
 
3053
- #: app/features/events.php:2692 app/features/mec/booking.php:758
3054
  #, fuzzy
3055
  #| msgid "Attendees List"
3056
  msgid "Per Attendee Fields"
3057
  msgstr "Teilnehmer Liste"
3058
 
3059
- #: app/features/events.php:2783 app/features/mec/booking.php:856
3060
  #, fuzzy
3061
  #| msgid "Required Field"
3062
  msgid "Fixed Fields"
3063
  msgstr "Pflichtfeld"
3064
 
3065
- #: app/features/events.php:2895 app/features/events.php:4712
3066
  #: app/features/mec/settings.php:1036 app/features/profile/profile.php:65
3067
  #: app/libraries/main.php:3048 app/libraries/main.php:3293
3068
  msgid "Attendees"
3069
  msgstr "Teilnehmer"
3070
 
3071
- #: app/features/events.php:2898 app/features/occurrences.php:104
3072
  #, fuzzy
3073
  #| msgid "Next Occurrence"
3074
  msgid "Occurrence"
3075
  msgstr "Nächstes Event"
3076
 
3077
- #: app/features/events.php:2899 app/features/mec.php:1731
3078
  #: app/features/occurrences.php:105
3079
  #, fuzzy
3080
  #| msgid "Next Occurrence"
3081
  msgid "Previous Occurrences"
3082
  msgstr "Nächstes Event"
3083
 
3084
- #: app/features/events.php:2904 app/features/mec.php:1741
3085
- #: app/features/occurrences.php:110 app/modules/next-event/multiple.php:52
3086
  #, fuzzy
3087
  #| msgid "Next Occurrence"
3088
  msgid "Next Occurrences"
3089
  msgstr "Nächstes Event"
3090
 
3091
- #: app/features/events.php:3735 app/features/mec/meta_boxes/filter.php:199
3092
  #: app/features/mec/settings.php:517
3093
  msgid "Expired Events"
3094
  msgstr "Abgelaufene Events"
3095
 
3096
- #: app/features/events.php:3736 app/features/mec.php:1335
3097
- #: app/features/mec/dashboard.php:266 app/features/mec/settings.php:516
3098
  msgid "Upcoming Events"
3099
  msgstr "Bevorstehende Events"
3100
 
3101
- #: app/features/events.php:3756 app/features/events.php:3774
3102
- #: app/features/events.php:3792 app/features/events.php:3810
3103
  #, php-format
3104
  msgid "Show all %s"
3105
  msgstr "Zeige alle %s"
3106
 
3107
- #: app/features/events.php:3756
3108
  msgid "labels"
3109
  msgstr "Labels + Eventstatus"
3110
 
3111
- #: app/features/events.php:3774
3112
  msgid "locations"
3113
  msgstr "Orte"
3114
 
3115
- #: app/features/events.php:3792
3116
  msgid "organizers"
3117
  msgstr "Veranstalter"
3118
 
3119
- #: app/features/events.php:3826
3120
  msgid "Attendees List"
3121
  msgstr "Teilnehmer Liste"
3122
 
3123
- #: app/features/events.php:3853 app/features/events.php:4162
3124
- #: app/features/events.php:4709 app/features/fes/form.php:260
3125
- #: app/features/mec/booking.php:686 app/features/mec/booking.php:718
3126
- #: app/features/mec/styling.php:134 app/libraries/hourlyschedule.php:49
3127
- #: app/libraries/hourlyschedule.php:65 app/libraries/hourlyschedule.php:93
3128
- #: app/libraries/hourlyschedule.php:125 app/libraries/hourlyschedule.php:145
3129
- #: app/libraries/ticketVariations.php:39
3130
- msgid "Title"
3131
- msgstr "Titel"
3132
-
3133
- #: app/features/events.php:3861
3134
  #, fuzzy
3135
  #| msgid "Tickets"
3136
  msgid "Sold Tickets"
3137
  msgstr "Tickets"
3138
 
3139
- #: app/features/events.php:3863
3140
  msgid "Repeat"
3141
  msgstr "Wiederholen"
3142
 
3143
- #: app/features/events.php:4032 app/features/events.php:4033
3144
  #, fuzzy
3145
  #| msgid "iCal Export"
3146
  msgid "iCal / Outlook Export"
3147
  msgstr "ical Export"
3148
 
3149
- #: app/features/events.php:4035 app/features/events.php:4036
3150
  msgid "CSV Export"
3151
  msgstr "CSV Export"
3152
 
3153
- #: app/features/events.php:4038 app/features/events.php:4039
3154
  msgid "MS Excel Export"
3155
  msgstr "MS Excel Export"
3156
 
3157
- #: app/features/events.php:4041 app/features/events.php:4042
3158
  msgid "XML Export"
3159
  msgstr "XML Export"
3160
 
3161
- #: app/features/events.php:4044 app/features/events.php:4045
3162
  msgid "JSON Export"
3163
  msgstr "JSON Export"
3164
 
3165
- #: app/features/events.php:4047 app/features/events.php:4048
3166
- #: app/features/events.php:4274
3167
  msgid "Duplicate"
3168
  msgstr "Kopie"
3169
 
3170
- #: app/features/events.php:4168
3171
  msgid "Link"
3172
  msgstr "Link"
3173
 
3174
- #: app/features/events.php:4170 app/features/locations.php:111
3175
  #: app/features/locations.php:181 app/features/locations.php:268
3176
  #: app/features/mec/meta_boxes/search_form.php:108
3177
  #: app/features/mec/meta_boxes/search_form.php:196
@@ -3189,68 +3258,68 @@ msgstr "Link"
3189
  msgid "Address"
3190
  msgstr "Adresse"
3191
 
3192
- #: app/features/events.php:4172
3193
  #, php-format
3194
  msgid "%s Tel"
3195
  msgstr "%s Tel"
3196
 
3197
- #: app/features/events.php:4173
3198
  #, php-format
3199
  msgid "%s Email"
3200
  msgstr "%s Email"
3201
 
3202
- #: app/features/events.php:4175 app/features/fes/form.php:951
3203
  #: app/features/mec/settings.php:866
3204
  msgid "Featured Image"
3205
  msgstr "Ausgewähltes Bild"
3206
 
3207
- #: app/features/events.php:4178 app/features/fes/form.php:1044
3208
- #: app/features/mec.php:493 app/features/mec/meta_boxes/filter.php:73
3209
  #: app/features/mec/meta_boxes/filter.php:153 app/features/tag.php:59
3210
  msgid "Tags"
3211
  msgstr "Schlagworte"
3212
 
3213
- #: app/features/events.php:4182 app/features/fes/form.php:1066
3214
- #: app/features/mec.php:502 app/features/mec/modules.php:34
3215
  #: app/features/mec/modules.php:43 app/features/mec/settings.php:937
3216
  #: app/features/popup/settings.php:299 app/features/speakers.php:61
3217
  #: app/libraries/hourlyschedule.php:77 app/libraries/hourlyschedule.php:105
3218
  #: app/libraries/hourlyschedule.php:157 app/libraries/main.php:659
3219
- #: app/libraries/main.php:7408 app/libraries/main.php:7469
3220
  #: app/modules/speakers/details.php:18
3221
  msgid "Speakers"
3222
  msgstr "Sprecher"
3223
 
3224
- #: app/features/events.php:4425 app/features/fes.php:280
3225
- #: app/features/profile/profile.php:198 app/libraries/cart.php:64
3226
- #: app/libraries/main.php:3064 app/libraries/main.php:3310
3227
- #: app/libraries/main.php:7434
3228
  msgid "Ticket"
3229
  msgstr "Ticket"
3230
 
3231
- #: app/features/events.php:4428 app/features/profile/profile.php:201
3232
  msgid "Variations"
3233
  msgstr "Variationen"
3234
 
3235
- #: app/features/events.php:4443 app/features/fes.php:356
3236
  msgid "Unknown"
3237
  msgstr "Unbekannt"
3238
 
3239
- #: app/features/events.php:4471
3240
  msgid ""
3241
  "If you want to send an email, first select your attendees and then click in "
3242
  "the button below, please."
3243
  msgstr ""
3244
 
3245
- #: app/features/events.php:4471 app/features/mec/report.php:57
3246
  msgid "Send Email"
3247
  msgstr "E-Mail senden"
3248
 
3249
- #: app/features/events.php:4475
3250
  msgid "No Attendees Found!"
3251
  msgstr "Keine Teilnehmer gefunden!"
3252
 
3253
- #: app/features/events.php:4773
3254
  #, fuzzy
3255
  #| msgid "No bookings found!"
3256
  msgid "No Bookings Found!"
@@ -3316,8 +3385,8 @@ msgstr "Uhrzeit Bestellung"
3316
  msgid "Total Price"
3317
  msgstr "Gesamt Preis"
3318
 
3319
- #: app/features/fes.php:280 app/libraries/main.php:3122
3320
- #: app/libraries/main.php:3369
3321
  msgid "Gateway"
3322
  msgstr "Gateway"
3323
 
@@ -3385,7 +3454,7 @@ msgstr "Mindestens 3 Zeichen eingeben"
3385
  msgid "Please select at-least one label!"
3386
  msgstr "Bitte Tickets auswählen!"
3387
 
3388
- #: app/features/fes.php:1370
3389
  #, fuzzy
3390
  #| msgid "The event submitted. It will publish as soon as possible."
3391
  msgid "Event submitted. It will publish as soon as possible."
@@ -3393,7 +3462,7 @@ msgstr ""
3393
  "Die Veranstaltung wurde übermittelt. Sie wird sobald wie möglich "
3394
  "veröffentlicht werden."
3395
 
3396
- #: app/features/fes.php:1371
3397
  msgid "The event published."
3398
  msgstr "Die Veranstaltung wurde veröffentlicht."
3399
 
@@ -3569,6 +3638,558 @@ msgstr ""
3569
  msgid "No events found! %s"
3570
  msgstr "Keine Veranstaltungen gefunden! %s"
3571
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3572
  #: app/features/ix.php:108
3573
  msgid "MEC - Import / Export"
3574
  msgstr "MEC - Import / Export"
@@ -3920,7 +4541,7 @@ msgstr "Event Teilnehmer"
3920
  msgid "Add to Google Calendar"
3921
  msgstr "Zum Google Kalender hinzufügen"
3922
 
3923
- #: app/features/ix/export_g_calendar.php:100 app/features/mec/booking.php:1248
3924
  #: app/features/mec/integrations.php:451 app/features/mec/modules.php:408
3925
  #: app/features/mec/notifications.php:1924 app/features/mec/settings.php:1601
3926
  #: app/features/mec/single.php:597
@@ -4036,7 +4657,7 @@ msgstr "Vom Facebook Kalender Importieren"
4036
  msgid "Import all of your Facebook events into MEC."
4037
  msgstr "Importiere alle Deine Facebook Events zum MEC"
4038
 
4039
- #: app/features/ix/import_f_calendar.php:27 app/features/mec/dashboard.php:144
4040
  #: app/features/mec/support-page.php:11 app/features/mec/support.php:100
4041
  msgid "Documentation"
4042
  msgstr "Dokumentation"
@@ -4447,10 +5068,10 @@ msgstr "Slug"
4447
  msgid "Event %s"
4448
  msgstr "Event %s"
4449
 
4450
- #: app/features/locations.php:59 app/features/mec.php:496
4451
- #: app/features/mec/dashboard.php:248 app/features/mec/meta_boxes/filter.php:70
4452
- #: app/features/mec/meta_boxes/filter.php:99 app/libraries/main.php:7404
4453
- #: app/libraries/main.php:7465
4454
  msgid "Locations"
4455
  msgstr "Orte"
4456
 
@@ -4569,8 +5190,8 @@ msgstr "Bild wählen"
4569
  msgid "Don't show map in single event page"
4570
  msgstr "Karte in Einzelansicht nicht anzeigen"
4571
 
4572
- #: app/features/locations.php:409 app/libraries/main.php:7449
4573
- #: app/libraries/main.php:7496
4574
  msgid "Other Locations"
4575
  msgstr "Andere Orte"
4576
 
@@ -4608,275 +5229,275 @@ msgstr "API Passwort"
4608
  msgid "Forgot Password?"
4609
  msgstr "API Passwort"
4610
 
4611
- #: app/features/mec.php:223
4612
  msgid ""
4613
  "Activation failed. Please check your purchase code or license type."
4614
  "<br><b>Note: Your purchase code should match your licesne type.</b>"
4615
  msgstr ""
4616
 
4617
- #: app/features/mec.php:223 app/features/mec/support-page.php:136
4618
  msgid "Troubleshooting"
4619
  msgstr "Problembehebung"
4620
 
4621
- #: app/features/mec.php:312
4622
  #, fuzzy
4623
  #| msgid "Select All"
4624
  msgid "Select Date"
4625
  msgstr "Alles Auswählen"
4626
 
4627
- #: app/features/mec.php:316 app/skins/masonry.php:265
4628
  msgid "All"
4629
  msgstr "Alle"
4630
 
4631
- #: app/features/mec.php:358
4632
  msgid ""
4633
  "Your option is not in JSON format. Please insert correct options in this "
4634
  "field and try again."
4635
  msgstr ""
4636
 
4637
- #: app/features/mec.php:365
4638
  msgid "Your options field can not be empty!"
4639
  msgstr "Ihr Optionen Feld darf nicht leer sein!"
4640
 
4641
- #: app/features/mec.php:371
4642
  msgid "Your options imported successfuly."
4643
  msgstr "Ihre Einstellungen wurden erfolgreich importiert."
4644
 
4645
- #: app/features/mec.php:476
4646
  msgid "MEC - Support"
4647
  msgstr "MEC - Support"
4648
 
4649
- #: app/features/mec.php:476 app/features/mec/support-page.php:9
4650
  #: app/features/mec/support.php:80 app/features/mec/support.php:93
4651
  msgid "Support"
4652
  msgstr "Support"
4653
 
4654
- #: app/features/mec.php:497 app/features/mec/dashboard.php:255
4655
  #: app/features/mec/meta_boxes/filter.php:71
4656
  #: app/features/mec/meta_boxes/filter.php:117 app/features/organizers.php:59
4657
- #: app/libraries/main.php:7406 app/libraries/main.php:7467
4658
  msgid "Organizers"
4659
  msgstr "Veranstalter"
4660
 
4661
- #: app/features/mec.php:506 app/features/mec.php:567
4662
- #: app/features/mec/dashboard.php:241
4663
  msgid "Shortcodes"
4664
  msgstr "Shortcodes"
4665
 
4666
- #: app/features/mec.php:516
4667
  msgid "MEC - Settings"
4668
  msgstr "MEC - Einstellungen"
4669
 
4670
- #: app/features/mec.php:518
4671
  msgid "MEC - Addons"
4672
  msgstr "MEC - Erweiterungen"
4673
 
4674
- #: app/features/mec.php:518 app/features/mec/addons.php:11
4675
  msgid "Addons"
4676
  msgstr "Erweiterungen"
4677
 
4678
- #: app/features/mec.php:519
4679
  msgid "MEC - Wizard"
4680
  msgstr ""
4681
 
4682
- #: app/features/mec.php:519 app/features/mec/wizard.php:512
4683
  #: app/features/mec/wizard.php:517 app/features/mec/wizard.php:522
4684
  msgid "Wizard"
4685
  msgstr ""
4686
 
4687
- #: app/features/mec.php:523
4688
  #, fuzzy
4689
  #| msgid "Support"
4690
  msgid "MEC - Report"
4691
  msgstr "Support"
4692
 
4693
- #: app/features/mec.php:523
4694
  #, fuzzy
4695
  #| msgid "Export"
4696
  msgid "Report"
4697
  msgstr "Export"
4698
 
4699
- #: app/features/mec.php:526
4700
  #, fuzzy
4701
  #| msgid "Support"
4702
  msgid "MEC - Go Pro"
4703
  msgstr "Support"
4704
 
4705
- #: app/features/mec.php:526 app/features/mec.php:1406
4706
  #: app/features/mec/go-pro.php:9
4707
  msgid "Go Pro"
4708
  msgstr ""
4709
 
4710
- #: app/features/mec.php:569 app/features/mec/wizard.php:516
4711
  msgid "Add Shortcode"
4712
  msgstr "Shortcode hinzufügen"
4713
 
4714
- #: app/features/mec.php:570
4715
  msgid "Add New Shortcode"
4716
  msgstr "Neuen Shortcode hinzufügen"
4717
 
4718
- #: app/features/mec.php:571
4719
  msgid "No shortcodes found!"
4720
  msgstr "Keine Shortcodes gefunden!"
4721
 
4722
- #: app/features/mec.php:572
4723
  msgid "All Shortcodes"
4724
  msgstr "Alle Shortcodes"
4725
 
4726
- #: app/features/mec.php:573
4727
  msgid "Edit shortcodes"
4728
  msgstr "Shortcode ändern"
4729
 
4730
- #: app/features/mec.php:574
4731
  msgid "No shortcodes found in Trash!"
4732
  msgstr "Keine Shortcodes im Papierkorb gefunden!"
4733
 
4734
- #: app/features/mec.php:627
4735
  msgid "Display Options"
4736
  msgstr "Darstellungsoptionen"
4737
 
4738
- #: app/features/mec.php:628
4739
  msgid "Filter Options"
4740
  msgstr "Filteroptionen"
4741
 
4742
- #: app/features/mec.php:630
4743
  msgid "Search Form"
4744
  msgstr "Suche Formular"
4745
 
4746
- #: app/features/mec.php:1065
4747
  msgid "Display content's images as Popup"
4748
  msgstr ""
4749
 
4750
- #: app/features/mec.php:1079 app/features/popup/shortcode.php:477
4751
  msgid "Single Event Display Method"
4752
  msgstr "Single Event Anzeigemethode"
4753
 
4754
- #: app/features/mec.php:1086 app/features/popup/shortcode.php:489
4755
  #, fuzzy
4756
  #| msgid "Modal 1"
4757
  msgid "Modal Popup"
4758
  msgstr "Modal 1"
4759
 
4760
- #: app/features/mec.php:1087
4761
  #, fuzzy
4762
  #| msgid "Disabled"
4763
  msgid "Disable Link"
4764
  msgstr "Deaktiviert"
4765
 
4766
- #: app/features/mec.php:1097
4767
  msgid "Descending Order"
4768
  msgstr ""
4769
 
4770
- #: app/features/mec.php:1113
4771
  #, fuzzy
4772
  #| msgid "Booking Options"
4773
  msgid "Booking Button / Icon"
4774
  msgstr "Buchungsoptionen"
4775
 
4776
- #: app/features/mec.php:1126
4777
  #, fuzzy
4778
  #| msgid "Organizers"
4779
  msgid "Display Organizers"
4780
  msgstr "Veranstalter"
4781
 
4782
- #: app/features/mec.php:1139
4783
  #, fuzzy
4784
  #| msgid "Custom Styles"
4785
  msgid "Display Custom Fields"
4786
  msgstr "Benutzerdefinierte Stile"
4787
 
4788
- #: app/features/mec.php:1152
4789
  #, fuzzy
4790
  #| msgid "Date And Time"
4791
  msgid "Detailed Time"
4792
  msgstr "Datum und Uhrzeit"
4793
 
4794
- #: app/features/mec.php:1153
4795
  #, fuzzy
4796
  #| msgid "Multiple Day Events"
4797
  msgid "For Multiple Day Events"
4798
  msgstr "Mehrtagesveranstaltung"
4799
 
4800
- #: app/features/mec.php:1310 app/features/mec.php:1486
4801
  msgid "Total Bookings"
4802
  msgstr "Gesamte Buchungen"
4803
 
4804
- #: app/features/mec.php:1326 app/features/mec/dashboard.php:65
4805
  msgid "Modern Events Calendar (Lite)"
4806
  msgstr "Moderner Event Kalender (Lite)"
4807
 
4808
- #: app/features/mec.php:1392
4809
  #, fuzzy
4810
  #| msgid "Update %s"
4811
  msgid "News & Updates"
4812
  msgstr "Update %s"
4813
 
4814
- #: app/features/mec.php:1405
4815
  msgid "Blog"
4816
  msgstr ""
4817
 
4818
- #: app/features/mec.php:1405
4819
  msgid "Help"
4820
  msgstr ""
4821
 
4822
- #: app/features/mec.php:1460
4823
  #, fuzzy, php-format
4824
  #| msgid "Total Sells (%s)"
4825
  msgid "Total Sales (%s)"
4826
  msgstr "Alle Verkäufe (%s)"
4827
 
4828
- #: app/features/mec.php:1495
4829
  msgid "This Month"
4830
  msgstr "Diesen Monat"
4831
 
4832
- #: app/features/mec.php:1501
4833
  msgid "Last Month"
4834
  msgstr "Letzten Monat"
4835
 
4836
- #: app/features/mec.php:1507
4837
  msgid "This Year"
4838
  msgstr "Diese Jahr"
4839
 
4840
- #: app/features/mec.php:1513
4841
  msgid "Last Year"
4842
  msgstr "Letztes Jahr"
4843
 
4844
- #: app/features/mec.php:1533
4845
  msgid "Bar"
4846
  msgstr "Bar"
4847
 
4848
- #: app/features/mec.php:1534
4849
  msgid "Line"
4850
  msgstr "Linie"
4851
 
4852
- #: app/features/mec.php:1536 app/skins/general_calendar/tpl.php:145
4853
  msgid "Filter"
4854
  msgstr "Filter"
4855
 
4856
- #: app/features/mec.php:1560
4857
  #, fuzzy
4858
  #| msgid "Modern Events Calendar"
4859
  msgid "Print Calendar"
4860
  msgstr "Moderner Event Kalender "
4861
 
4862
- #: app/features/mec.php:1575
4863
  #, fuzzy
4864
  #| msgid "Multiple Day Events"
4865
  msgid "Display Events"
4866
  msgstr "Mehrtagesveranstaltung"
4867
 
4868
- #: app/features/mec.php:1621
4869
  #, fuzzy
4870
  #| msgid "Include Expired Events"
4871
  msgid "Include MEC Assets"
4872
  msgstr "Inklusive abgelaufene Events"
4873
 
4874
- #: app/features/mec.php:1632
4875
  msgid "Include Modern Events Calendar Assets (CSS, JavaScript, etc files.)"
4876
  msgstr ""
4877
 
4878
  #: app/features/mec/addons.php:16 app/features/mec/addons.php:62
4879
- #: app/features/mec/dashboard.php:84 app/features/mec/go-pro.php:14
4880
  #: app/features/mec/report.php:21 app/features/mec/support-page.php:21
4881
  msgid "Version"
4882
  msgstr "Version"
@@ -4900,9 +5521,9 @@ msgid "Search..."
4900
  msgstr "Suche…"
4901
 
4902
  #: app/features/mec/booking.php:72 app/features/mec/booking.php:906
4903
- #: app/features/mec/booking.php:1098 app/features/mec/booking.php:1173
4904
- #: app/features/mec/booking.php:1183 app/features/mec/booking.php:1265
4905
- #: app/features/mec/booking.php:1279 app/features/mec/integrations.php:24
4906
  #: app/features/mec/integrations.php:400 app/features/mec/integrations.php:410
4907
  #: app/features/mec/integrations.php:468 app/features/mec/integrations.php:482
4908
  #: app/features/mec/messages.php:20 app/features/mec/messages.php:60
@@ -5344,7 +5965,7 @@ msgid ""
5344
  "new menu on the Dashboard > Booking"
5345
  msgstr ""
5346
 
5347
- #: app/features/mec/booking.php:571 app/features/mec/booking.php:986
5348
  #: app/libraries/main.php:650
5349
  msgid "Taxes / Fees"
5350
  msgstr "Steuern/Gebühren"
@@ -5441,201 +6062,203 @@ msgid ""
5441
  "fields etc, you need to configure WooCommerce on your website."
5442
  msgstr ""
5443
 
5444
- #: app/features/mec/booking.php:980
 
 
 
 
 
 
5445
  msgid ""
5446
  "You cannot use following MEC features so you should use WooCommerc and its "
5447
  "addons if you need them."
5448
  msgstr ""
5449
 
5450
- #: app/features/mec/booking.php:982
5451
  #, fuzzy
5452
  #| msgid "Payment Gateways"
5453
  msgid "Payment gateways"
5454
  msgstr "Zahlungs-Gateways"
5455
 
5456
- #: app/features/mec/booking.php:983
5457
  #, fuzzy
5458
  #| msgid "Price per Date"
5459
  msgid "Price per dates of tickets"
5460
  msgstr "Preis pro Datum"
5461
 
5462
- #: app/features/mec/booking.php:985
5463
  #, fuzzy
5464
  #| msgid "Ticket Variation"
5465
  msgid "Ticket variations"
5466
  msgstr "Ticket Variationen"
5467
 
5468
- #: app/features/mec/booking.php:987
5469
  #, fuzzy
5470
  #| msgid "Discount Type"
5471
  msgid "Discount Per Roles"
5472
  msgstr "Rabatt-Art"
5473
 
5474
- #: app/features/mec/booking.php:991
5475
  #, fuzzy
5476
  #| msgid "Automatically complete WC orders"
5477
  msgid "Automatically complete WooCommerce orders"
5478
  msgstr "WC-Aufträge automatisch abschließen"
5479
 
5480
- #: app/features/mec/booking.php:999
5481
  #, fuzzy
5482
  #| msgid "Automatically complete WC orders"
5483
  msgid "Auto WooCommerce orders"
5484
  msgstr "WC-Aufträge automatisch abschließen"
5485
 
5486
- #: app/features/mec/booking.php:1000
5487
- msgid "It applies only to the orders that are related to MEC."
5488
- msgstr "Sie gilt nur für Aufträge, die mit MEC zusammenhängen."
5489
-
5490
- #: app/features/mec/booking.php:1008 app/features/mec/booking.php:1146
5491
  #, fuzzy
5492
  #| msgid "Add to Cart"
5493
  msgid "After Add to Cart"
5494
  msgstr "in den Warenkorb legen"
5495
 
5496
- #: app/features/mec/booking.php:1011 app/features/mec/booking.php:1149
5497
  #, fuzzy
5498
  #| msgid "Redirection Page"
5499
  msgid "Redirect to Cart"
5500
  msgstr "Weiterleitungs Seite "
5501
 
5502
- #: app/features/mec/booking.php:1012 app/features/mec/booking.php:1150
5503
  #, fuzzy
5504
  #| msgid "Redirection Page"
5505
  msgid "Redirect to Checkout"
5506
  msgstr "Weiterleitungs Seite "
5507
 
5508
- #: app/features/mec/booking.php:1013 app/features/mec/booking.php:1151
5509
  #, fuzzy
5510
  #| msgid "View Detail Button"
5511
  msgid "Optional View Cart Button"
5512
  msgstr "Ansicht Detail Button"
5513
 
5514
- #: app/features/mec/booking.php:1014 app/features/mec/booking.php:1152
5515
  msgid "Optional Checkout Button"
5516
  msgstr ""
5517
 
5518
- #: app/features/mec/booking.php:1019
5519
  #, fuzzy
5520
  #| msgid "Booking Form"
5521
  msgid "MEC Booking Form"
5522
  msgstr "Buchungsformular"
5523
 
5524
- #: app/features/mec/booking.php:1028
5525
  msgid ""
5526
  "If enabled then users should fill the booking form in MEC and then they will "
5527
  "be redirected to checkout."
5528
  msgstr ""
5529
 
5530
- #: app/features/mec/booking.php:1054
5531
  msgid "Enable Organizer Payment Module"
5532
  msgstr ""
5533
 
5534
- #: app/features/mec/booking.php:1059
5535
  msgid ""
5536
  "By enabling this module, organizers are able to insert their own payment "
5537
  "credentials for enabled gateways per event and receive the payments directly!"
5538
  msgstr ""
5539
 
5540
- #: app/features/mec/booking.php:1069
5541
  msgid "Disable / Enable payment gateways per event"
5542
  msgstr ""
5543
 
5544
- #: app/features/mec/booking.php:1073
5545
  #, fuzzy
5546
  #| msgid "Payment Gateways"
5547
  msgid "Payment Gateways Per Event"
5548
  msgstr "Zahlungs-Gateways"
5549
 
5550
- #: app/features/mec/booking.php:1074
5551
  msgid ""
5552
  "By enabling this module, users are able to disable / enable payment gateways "
5553
  "per event"
5554
  msgstr ""
5555
 
5556
- #: app/features/mec/booking.php:1084
5557
  msgid "Automatically refund the payment"
5558
  msgstr ""
5559
 
5560
- #: app/features/mec/booking.php:1088
5561
  msgid "Auto Refund"
5562
  msgstr ""
5563
 
5564
- #: app/features/mec/booking.php:1089
5565
  msgid ""
5566
  "Automatically refund the payment when a booking paid by applicable gateways "
5567
  "(Stripe) got canceled."
5568
  msgstr ""
5569
 
5570
- #: app/features/mec/booking.php:1108
5571
  msgid "Use MEC Cart System"
5572
  msgstr ""
5573
 
5574
- #: app/features/mec/booking.php:1110
5575
  msgid ""
5576
  "If you don't want to use WooCommerce for any reason you can use MEC Cart for "
5577
  "adding a simple cart and checkout system to your website."
5578
  msgstr ""
5579
 
5580
- #: app/features/mec/booking.php:1112
5581
  msgid "You cannot use following MEC features while using MEC Cart."
5582
  msgstr ""
5583
 
5584
- #: app/features/mec/booking.php:1114
5585
  #, fuzzy
5586
  #| msgid "Payment Gateways"
5587
  msgid "WooCommerce as Payment Gateway"
5588
  msgstr "Zahlungs-Gateways"
5589
 
5590
- #: app/features/mec/booking.php:1115
5591
  #, fuzzy
5592
  #| msgid "Next Occurrence of Other Events"
5593
  msgid "Currency Per Event"
5594
  msgstr "Nächstes Auftreten von anderen Events."
5595
 
5596
- #: app/features/mec/booking.php:1116
5597
  #, fuzzy
5598
  #| msgid "Payment Gateways"
5599
  msgid "Disable Gateways Per Event"
5600
  msgstr "Zahlungs-Gateways"
5601
 
5602
- #: app/features/mec/booking.php:1117
5603
  #, fuzzy
5604
  #| msgid "Stripe"
5605
  msgid "Stripe Connect Gateway"
5606
  msgstr "Stripe"
5607
 
5608
- #: app/features/mec/booking.php:1118
5609
  #, fuzzy
5610
  #| msgid "Pay by WooCommerce"
5611
  msgid "Pay By WooCommerce Gateway"
5612
  msgstr "Zahlung über WooCommerce"
5613
 
5614
- #: app/features/mec/booking.php:1122
5615
  #, fuzzy
5616
  #| msgid "Start Date"
5617
  msgid "Cart Page"
5618
  msgstr "Start Datum"
5619
 
5620
- #: app/features/mec/booking.php:1130 app/features/mec/booking.php:1142
5621
  #: app/features/mec/settings.php:722 app/features/mec/settings.php:734
5622
  #, php-format
5623
  msgid "Put %s shortcode into the page."
5624
  msgstr "%s shortcode in die Seite einfügen"
5625
 
5626
- #: app/features/mec/booking.php:1134
5627
  #, fuzzy
5628
  #| msgid "Checkout"
5629
  msgid "Checkout Page"
5630
  msgstr "Zur Kasse gehen"
5631
 
5632
- #: app/features/mec/booking.php:1160
5633
  #, fuzzy
5634
  #| msgid "Enable Invoice"
5635
  msgid "Enable Cart Invoice"
5636
  msgstr "Rechnungen aktivieren"
5637
 
5638
- #: app/features/mec/booking.php:1243 app/features/mec/integrations.php:446
5639
  #: app/features/mec/messages.php:90 app/features/mec/modules.php:403
5640
  #: app/features/mec/notifications.php:1919 app/features/mec/settings.php:1596
5641
  #: app/features/mec/single.php:592 app/features/mec/styles.php:62
@@ -5643,7 +6266,7 @@ msgstr "Rechnungen aktivieren"
5643
  msgid "Saved"
5644
  msgstr "Gesichert"
5645
 
5646
- #: app/features/mec/booking.php:1244 app/features/mec/integrations.php:447
5647
  #: app/features/mec/messages.php:91 app/features/mec/modules.php:404
5648
  #: app/features/mec/notifications.php:1920 app/features/mec/settings.php:1597
5649
  #: app/features/mec/single.php:593 app/features/mec/styles.php:63
@@ -5651,32 +6274,28 @@ msgstr "Gesichert"
5651
  msgid "Settings Saved!"
5652
  msgstr "Einstellungen gespeichert!"
5653
 
5654
- #: app/features/mec/booking.php:1270 app/features/mec/integrations.php:473
5655
  #: app/features/mec/modules.php:430 app/features/mec/notifications.php:1947
5656
  #: app/features/mec/settings.php:1623 app/features/mec/single.php:619
5657
  msgid "Please Refresh Page"
5658
  msgstr "Bitte Seiten Refresh vornehmen"
5659
 
5660
- #: app/features/mec/dashboard.php:62
5661
  #, php-format
5662
  msgid "Welcome %s"
5663
  msgstr "Willkommen %s"
5664
 
5665
- #: app/features/mec/dashboard.php:65
5666
  #, php-format
5667
  msgid "%s - Most Powerful & Easy to Use Events Management System"
5668
  msgstr ""
5669
 
5670
- #: app/features/mec/dashboard.php:67 app/libraries/factory.php:215
5671
  msgctxt "plugin rate"
5672
  msgid "Rate the plugin ★★★★★"
5673
  msgstr "Bewerte das Plugin ★★★★★"
5674
 
5675
- #: app/features/mec/dashboard.php:72
5676
- msgid "Update"
5677
- msgstr "Update"
5678
-
5679
- #: app/features/mec/dashboard.php:99 app/features/mec/go-pro.php:66
5680
  #, php-format
5681
  msgid ""
5682
  "You're using %s version of Modern Events Calendar. To use advanced booking "
@@ -5684,65 +6303,65 @@ msgid ""
5684
  "Spots, etc you should upgrade to the Pro version."
5685
  msgstr ""
5686
 
5687
- #: app/features/mec/dashboard.php:99 app/features/mec/go-pro.php:66
5688
  msgid "lite"
5689
  msgstr ""
5690
 
5691
- #: app/features/mec/dashboard.php:102 app/features/mec/go-pro.php:69
5692
  #: app/features/mec/support.php:126
5693
  msgid "GO PREMIUM"
5694
  msgstr ""
5695
 
5696
- #: app/features/mec/dashboard.php:105 app/features/mec/go-pro.php:72
5697
  #, php-format
5698
  msgid ""
5699
  "Easily get a discount coupon by rating us on %s or following and reposting "
5700
  "us on social media. Just send a screenshot to %s and you'll receive the %s"
5701
  msgstr ""
5702
 
5703
- #: app/features/mec/dashboard.php:105 app/features/mec/go-pro.php:72
5704
  msgid "WordPress"
5705
  msgstr "WordPress"
5706
 
5707
- #: app/features/mec/dashboard.php:105 app/features/mec/go-pro.php:72
5708
  msgid "Copouns!"
5709
  msgstr "Gutscheine!"
5710
 
5711
- #: app/features/mec/dashboard.php:135
5712
  msgid "Getting started with Modern Events Calendar"
5713
  msgstr "Lege los mit dem Modernen Event Kalender "
5714
 
5715
- #: app/features/mec/dashboard.php:136
5716
  msgid ""
5717
  "In this short video, you can learn how to make an event and put a calendar "
5718
  "on your website. Please watch this 2 minutes video to the end."
5719
  msgstr ""
5720
 
5721
- #: app/features/mec/dashboard.php:152 app/features/mec/dashboard.php:176
5722
  #, fuzzy
5723
  #| msgid "MEC Activation"
5724
  msgid "License Activation"
5725
  msgstr "MEC Aktivierung"
5726
 
5727
- #: app/features/mec/dashboard.php:158 app/features/mec/dashboard.php:213
5728
  msgid "Activate Addons"
5729
  msgstr "MEC Erweiterungen Aktivieren"
5730
 
5731
- #: app/features/mec/dashboard.php:166 app/features/mec/dashboard.php:222
5732
  msgid "You cannot access this section."
5733
  msgstr ""
5734
 
5735
- #: app/features/mec/dashboard.php:182
5736
  msgid ""
5737
  "In order to use all plugin features and options, please enter your purchase "
5738
  "code."
5739
  msgstr ""
5740
 
5741
- #: app/features/mec/dashboard.php:290
5742
  msgid "Popular Gateways"
5743
  msgstr "Beliebte Zahlungsgateways"
5744
 
5745
- #: app/features/mec/dashboard.php:348
5746
  msgid "Change Log"
5747
  msgstr "Änderungsprotokoll"
5748
 
@@ -6112,12 +6731,6 @@ msgstr "Minimal"
6112
  msgid "Modern"
6113
  msgstr "Modern"
6114
 
6115
- #: app/features/mec/meta_boxes/display_options.php:51
6116
- #: app/features/mec/settings.php:404 app/features/mec/settings.php:481
6117
- #: app/features/popup/settings.php:131 app/features/popup/shortcode.php:85
6118
- msgid "Standard"
6119
- msgstr "Standard"
6120
-
6121
  #: app/features/mec/meta_boxes/display_options.php:52
6122
  #: app/features/mec/settings.php:405 app/features/mec/settings.php:482
6123
  #: app/features/popup/settings.php:132 app/features/popup/shortcode.php:90
@@ -7298,7 +7911,7 @@ msgstr ""
7298
  #: app/features/mec/single.php:526 app/features/popup/settings.php:233
7299
  #: app/features/popup/settings.php:272 app/features/search.php:109
7300
  #: app/features/speakers.php:60 app/features/speakers.php:286
7301
- #: app/libraries/main.php:7409 app/libraries/main.php:7470
7302
  #: app/libraries/search.php:334 app/libraries/skins.php:1203
7303
  #: app/modules/speakers/details.php:18
7304
  msgid "Speaker"
@@ -8638,8 +9251,8 @@ msgstr ""
8638
  msgid "only once per hour"
8639
  msgstr "nur einmal pro Tag"
8640
 
8641
- #: app/features/mec/notifications.php:1314 app/libraries/main.php:8654
8642
- #: app/libraries/main.php:8674
8643
  #, fuzzy
8644
  #| msgid "Hour"
8645
  msgid "Hours"
@@ -8969,8 +9582,8 @@ msgid "You can enable/disable Schema scripts"
8969
  msgstr ""
8970
 
8971
  #: app/features/mec/settings.php:137 app/features/mec/settings.php:148
8972
- #: app/features/popup/settings.php:41 app/libraries/main.php:7413
8973
- #: app/libraries/main.php:7474
8974
  msgid "Weekdays"
8975
  msgstr "Wochentage"
8976
 
@@ -9410,10 +10023,6 @@ msgstr "Aktivieren auf dem \"Frontend Event Submittion\" Formular"
9410
  msgid "Site Key"
9411
  msgstr "Site Key (Seitenschlüssel)"
9412
 
9413
- #: app/features/mec/settings.php:685
9414
- msgid "Secret Key"
9415
- msgstr "Geheimschlüssel"
9416
-
9417
  #: app/features/mec/settings.php:697 app/features/mec/settings.php:705
9418
  msgid "Time Format"
9419
  msgstr "Zeitformat"
@@ -9657,8 +10266,8 @@ msgstr ""
9657
  msgid "Required Fields"
9658
  msgstr "Pflichtfeld"
9659
 
9660
- #: app/features/mec/settings.php:1164 app/libraries/main.php:7445
9661
- #: app/libraries/main.php:7492
9662
  msgid "More Info Link"
9663
  msgstr "Link Mehr Informationen"
9664
 
@@ -11016,8 +11625,8 @@ msgstr "z.B.. max@mustermann.com"
11016
  msgid "eg. https://webnus.net"
11017
  msgstr "http://webnus.net"
11018
 
11019
- #: app/features/organizers.php:329 app/libraries/main.php:7448
11020
- #: app/libraries/main.php:7495 app/skins/single.php:1439
11021
  msgid "Other Organizers"
11022
  msgstr "Andere Veranstalter"
11023
 
@@ -11247,7 +11856,7 @@ msgstr ""
11247
  msgid "MEC Pro"
11248
  msgstr "Support"
11249
 
11250
- #: app/features/profile/profile.php:53 app/features/profile/profile.php:189
11251
  msgid "#"
11252
  msgstr ""
11253
 
@@ -11261,16 +11870,16 @@ msgstr "% s Rechnung"
11261
  msgid "Cancel"
11262
  msgstr "Abbrechen"
11263
 
11264
- #: app/features/profile/profile.php:122
11265
  msgid "N/A"
11266
  msgstr ""
11267
 
11268
-
2
  msgstr ""
3
  "Project-Id-Version: ME Calender\n"
4
  "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2022-01-12 09:53+0330\n"
6
+ "PO-Revision-Date: 2022-01-12 10:05+0330\n"
7
  "Last-Translator: Jogon <koenig@kafinanz.de>\n"
8
  "Language-Team: German\n"
9
  "Language: de_DE\n"
19
 
20
  #: app/addons/KC.php:68 app/addons/VC.php:59 app/features/ix/import.php:24
21
  #: app/features/ix/import.php:48 app/features/ix/import.php:77
22
+ #: app/features/ix/thirdparty.php:26 app/features/mec.php:1322
23
+ #: app/features/mec.php:1346 app/features/mec/dashboard.php:57
24
  #: app/features/mec/wizard.php:489 app/widgets/MEC.php:33
25
  msgid "Modern Events Calendar"
26
  msgstr "Moderner Event Kalender "
31
  msgid "Content"
32
  msgstr "Inhalt"
33
 
34
+ #: app/addons/KC.php:75 app/addons/VC.php:70 app/features/mec.php:588
35
+ #: app/features/mec.php:619 app/features/mec.php:649
36
  msgid "Shortcode"
37
  msgstr "Shortcode"
38
 
106
  msgid "Select Shortcode"
107
  msgstr "Neuen Shortcode hinzufügen"
108
 
109
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:54
110
+ #, fuzzy
111
+ #| msgid "View Detail"
112
+ msgid "View details"
113
+ msgstr "Details "
114
+
115
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:77
116
+ #, fuzzy, php-format
117
+ #| msgid "More Information"
118
+ msgid "More information about %s"
119
+ msgstr "z.B. Noch mehr Informationen "
120
+
121
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:128
122
+ #, fuzzy
123
+ #| msgid "Checkout"
124
+ msgid "Check for updates"
125
+ msgstr "Zur Kasse gehen"
126
+
127
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:214
128
+ #, php-format
129
+ msgctxt "the plugin title"
130
+ msgid "The %s plugin is up to date."
131
+ msgstr ""
132
+
133
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:216
134
+ #, php-format
135
+ msgctxt "the plugin title"
136
+ msgid "A new version of the %s plugin is available."
137
+ msgstr ""
138
+
139
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:218
140
+ #, php-format
141
+ msgctxt "the plugin title"
142
+ msgid "Could not determine if updates are available for %s."
143
+ msgstr ""
144
+
145
+ #: app/core/puc/Puc/v4p11/Plugin/Ui.php:224
146
+ #, php-format
147
+ msgid "Unknown update checker status \"%s\""
148
+ msgstr ""
149
+
150
+ #: app/core/puc/Puc/v4p11/Vcs/PluginUpdateChecker.php:100
151
+ msgid "There is no changelog available."
152
+ msgstr ""
153
+
154
  #: app/core/src/Books/Book.php:106 app/features/ix.php:284
155
+ #: app/libraries/main.php:7761 app/libraries/main.php:7788
156
  msgid "Rejected"
157
  msgstr "Abgelehnt"
158
 
159
  #: app/core/src/Books/Book.php:111 app/features/ix.php:283
160
+ #: app/libraries/main.php:3232 app/libraries/main.php:7760
161
+ #: app/libraries/main.php:7780
162
  msgid "Confirmed"
163
  msgstr "Bestätigt"
164
 
165
  #: app/core/src/Books/Book.php:117 app/features/mec/settings.php:742
166
+ #: app/libraries/main.php:7762 app/libraries/main.php:7784
167
  msgid "Pending"
168
  msgstr "Ausstehend"
169
 
170
  #: app/core/src/Books/Book.php:186 app/features/ix.php:289
171
  #: app/features/labels.php:119 app/features/labels.php:145
172
+ #: app/libraries/main.php:7809
173
  msgid "Canceled"
174
  msgstr "Abgesagt"
175
 
176
  #: app/core/src/Books/Book.php:191 app/features/ix.php:288
177
+ #: app/features/mec/booking.php:1251 app/features/mec/booking.php:1273
178
  #: app/features/mec/integrations.php:449 app/features/mec/integrations.php:471
179
  #: app/features/mec/modules.php:406 app/features/mec/modules.php:428
180
  #: app/features/mec/notifications.php:1922
181
  #: app/features/mec/notifications.php:1945 app/features/mec/settings.php:1599
182
  #: app/features/mec/settings.php:1621 app/features/mec/single.php:595
183
+ #: app/features/mec/single.php:617 app/libraries/main.php:7808
184
  msgid "Verified"
185
  msgstr "Verifiziert"
186
 
187
+ #: app/core/src/Books/Book.php:197 app/libraries/main.php:7810
188
  msgid "Waiting"
189
  msgstr "in Bearbeitung"
190
 
211
  #: app/core/src/Forms/FormFields.php:188 app/core/src/Forms/SettingsForm.php:93
212
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:70
213
  #: app/features/autoemails.php:60 app/features/events.php:606
214
+ #: app/features/events.php:2656 app/features/events.php:2723
215
+ #: app/features/events.php:2812 app/features/events.php:4426
216
  #: app/features/fes.php:280 app/features/fes/form.php:810
217
+ #: app/features/gateways.php:1288 app/features/gateways.php:1531
218
+ #: app/features/gateways.php:3199 app/features/login/login.php:5
219
+ #: app/features/mec/booking.php:57 app/features/mec/booking.php:794
220
+ #: app/features/mec/booking.php:892 app/features/mec/settings.php:295
221
+ #: app/features/mec/single.php:303 app/features/organizers.php:112
222
+ #: app/features/organizers.php:153 app/features/profile/profile.php:206
223
+ #: app/features/speakers.php:128 app/features/speakers.php:205
224
+ #: app/libraries/main.php:618 app/libraries/main.php:2093
225
+ #: app/libraries/main.php:2162 app/libraries/main.php:3989
226
+ #: app/libraries/notifications.php:2091 app/modules/booking/steps/form.php:69
227
+ #: app/modules/booking/steps/form.php:218 app/skins/single.php:1394
228
+ #: app/skins/single.php:1461 app/skins/single/default.php:347
229
+ #: app/skins/single/default.php:596 app/skins/single/m1.php:141
230
+ #: app/skins/single/m2.php:61 app/skins/single/modern.php:94
231
  msgid "Email"
232
  msgstr "E-Mail"
233
 
245
  #: app/core/src/Forms/FormFields.php:396 app/core/src/Forms/FormFields.php:442
246
  #: app/core/src/Forms/FormFields.php:488 app/core/src/Forms/FormFields.php:544
247
  #: app/core/src/Forms/FormFields.php:596 app/features/organizers.php:340
248
+ #: app/features/organizers.php:348 app/libraries/main.php:3897
249
+ #: app/libraries/main.php:3928 app/libraries/main.php:3958
250
+ #: app/libraries/main.php:3988 app/libraries/main.php:4019
251
+ #: app/libraries/main.php:4050 app/libraries/main.php:4080
252
+ #: app/libraries/main.php:4111 app/libraries/main.php:4142
253
+ #: app/libraries/main.php:4180 app/libraries/main.php:4204
254
+ #: app/libraries/main.php:4252 app/libraries/main.php:4300
255
+ #: app/libraries/main.php:4358 app/libraries/main.php:4408
256
  msgid "Sort"
257
  msgstr "Sortieren"
258
 
259
  #: app/core/src/Forms/FormFields.php:52 app/core/src/Forms/SettingsForm.php:88
260
+ #: app/features/events.php:2722 app/features/events.php:2811
261
  #: app/features/mec/booking.php:793 app/features/mec/booking.php:891
262
+ #: app/features/mec/single.php:302 app/libraries/main.php:3898
263
  #: app/libraries/skins.php:1377
264
  msgid "Text"
265
  msgstr "Text"
270
  #: app/core/src/Forms/FormFields.php:286 app/core/src/Forms/FormFields.php:317
271
  #: app/core/src/Forms/FormFields.php:348 app/core/src/Forms/FormFields.php:403
272
  #: app/core/src/Forms/FormFields.php:449 app/core/src/Forms/FormFields.php:495
273
+ #: app/core/src/Forms/FormFields.php:551 app/libraries/main.php:3905
274
+ #: app/libraries/main.php:3936 app/libraries/main.php:3966
275
+ #: app/libraries/main.php:3996 app/libraries/main.php:4027
276
+ #: app/libraries/main.php:4058 app/libraries/main.php:4088
277
+ #: app/libraries/main.php:4119 app/libraries/main.php:4151
278
+ #: app/libraries/main.php:4212 app/libraries/main.php:4260
279
+ #: app/libraries/main.php:4308 app/libraries/main.php:4366
280
  msgid "Required Field"
281
  msgstr "Pflichtfeld"
282
 
288
  #: app/core/src/Forms/FormFields.php:406 app/core/src/Forms/FormFields.php:452
289
  #: app/core/src/Forms/FormFields.php:505 app/core/src/Forms/FormFields.php:554
290
  #: app/core/src/Forms/FormFields.php:597 app/features/events.php:2121
291
+ #: app/features/events.php:2147 app/features/events.php:2359
292
+ #: app/features/events.php:2496 app/features/events.php:2533
293
  #: app/features/mec/booking.php:611 app/features/mec/booking.php:641
294
  #: app/features/mec/booking.php:709 app/features/mec/booking.php:741
295
  #: app/features/organizers.php:340 app/features/organizers.php:349
296
  #: app/libraries/hourlyschedule.php:53 app/libraries/hourlyschedule.php:74
297
  #: app/libraries/hourlyschedule.php:102 app/libraries/hourlyschedule.php:130
298
+ #: app/libraries/hourlyschedule.php:154 app/libraries/main.php:3908
299
+ #: app/libraries/main.php:3939 app/libraries/main.php:3969
300
+ #: app/libraries/main.php:3999 app/libraries/main.php:4030
301
+ #: app/libraries/main.php:4061 app/libraries/main.php:4091
302
+ #: app/libraries/main.php:4122 app/libraries/main.php:4160
303
+ #: app/libraries/main.php:4182 app/libraries/main.php:4215
304
+ #: app/libraries/main.php:4263 app/libraries/main.php:4318
305
+ #: app/libraries/main.php:4369 app/libraries/main.php:4409
306
  #: app/libraries/ticketVariations.php:72
307
  msgid "Remove"
308
  msgstr "Entfernen"
313
  #: app/core/src/Forms/FormFields.php:292 app/core/src/Forms/FormFields.php:323
314
  #: app/core/src/Forms/FormFields.php:354 app/core/src/Forms/FormFields.php:409
315
  #: app/core/src/Forms/FormFields.php:455 app/core/src/Forms/FormFields.php:508
316
+ #: app/core/src/Forms/FormFields.php:557 app/libraries/main.php:3911
317
+ #: app/libraries/main.php:3942 app/libraries/main.php:3972
318
+ #: app/libraries/main.php:4002 app/libraries/main.php:4033
319
+ #: app/libraries/main.php:4064 app/libraries/main.php:4094
320
+ #: app/libraries/main.php:4125 app/libraries/main.php:4163
321
+ #: app/libraries/main.php:4218 app/libraries/main.php:4266
322
+ #: app/libraries/main.php:4321 app/libraries/main.php:4372
323
  msgid "Insert a label for this field"
324
  msgstr "Geben Sie eine Bezeichnung (Label) für dieses Feld ein."
325
 
335
  msgid "MEC Last Name"
336
  msgstr "MEC Name"
337
 
338
+ #: app/core/src/Forms/FormFields.php:93 app/features/events.php:2720
339
+ #: app/features/mec/booking.php:791 app/libraries/main.php:3929
340
  msgid "MEC Name"
341
  msgstr "MEC Name"
342
 
343
  #: app/core/src/Forms/FormFields.php:158 app/core/src/Forms/SettingsForm.php:83
344
+ #: app/features/events.php:2721 app/features/mec/booking.php:792
345
+ #: app/libraries/main.php:3959
346
  msgid "MEC Email"
347
  msgstr "MEC Email"
348
 
349
  #: app/core/src/Forms/FormFields.php:219 app/features/mec/single.php:304
350
+ #: app/libraries/main.php:4020
351
  msgid "URL"
352
  msgstr ""
353
 
354
  #: app/core/src/Forms/FormFields.php:250
355
+ #: app/core/src/Forms/SettingsForm.php:108 app/features/events.php:2726
356
+ #: app/features/mec/booking.php:797 app/libraries/main.php:4051
357
  msgid "File"
358
  msgstr "Datei"
359
 
360
  #: app/core/src/Forms/FormFields.php:280 app/core/src/Forms/SettingsForm.php:98
361
  #: app/core/src/SingleBuilder/Widgets/EventDate/EventDate.php:47
362
+ #: app/features/events.php:1396 app/features/events.php:2724
363
+ #: app/features/events.php:2813 app/features/fes.php:280
364
  #: app/features/mec/booking.php:795 app/features/mec/booking.php:893
365
  #: app/features/mec/single.php:305 app/features/profile/profile.php:59
366
+ #: app/features/wc.php:79 app/libraries/main.php:4081
367
  #: app/libraries/skins.php:1289 app/modules/booking/steps/tickets.php:136
368
+ #: app/modules/next-event/details.php:145 app/skins/single.php:1186
369
  #: app/skins/single/default.php:171 app/skins/single/default.php:423
370
  #: app/skins/single/m1.php:40 app/skins/single/modern.php:253
371
  msgid "Date"
372
  msgstr "Datum"
373
 
374
  #: app/core/src/Forms/FormFields.php:311
375
+ #: app/core/src/Forms/SettingsForm.php:103 app/features/events.php:2725
376
+ #: app/features/events.php:2814 app/features/mec/booking.php:796
377
  #: app/features/mec/booking.php:894 app/features/mec/single.php:306
378
  #: app/features/organizers.php:104 app/features/organizers.php:149
379
  #: app/features/speakers.php:120 app/features/speakers.php:201
380
+ #: app/features/speakers.php:288 app/libraries/main.php:4112
381
  msgid "Tel"
382
  msgstr "Tel"
383
 
384
  #: app/core/src/Forms/FormFields.php:342
385
+ #: app/core/src/Forms/SettingsForm.php:113 app/features/events.php:2727
386
+ #: app/features/events.php:2815 app/features/mec/booking.php:798
387
  #: app/features/mec/booking.php:895 app/features/mec/single.php:307
388
+ #: app/libraries/main.php:4143
389
  msgid "Textarea"
390
  msgstr "Textbereich"
391
 
392
  #: app/core/src/Forms/FormFields.php:373
393
+ #: app/core/src/Forms/SettingsForm.php:138 app/features/events.php:2732
394
+ #: app/features/events.php:2820 app/features/mec/booking.php:803
395
  #: app/features/mec/booking.php:900 app/features/mec/settings.php:351
396
+ #: app/features/mec/single.php:308 app/libraries/main.php:4181
397
  msgid "Paragraph"
398
  msgstr "Absatz"
399
 
400
+ #: app/core/src/Forms/FormFields.php:378 app/libraries/main.php:4187
401
  msgid "HTML and shortcode are allowed."
402
  msgstr "HTML und shortcodes sind erlaubt."
403
 
404
  #: app/core/src/Forms/FormFields.php:397
405
+ #: app/core/src/Forms/SettingsForm.php:118 app/features/events.php:2728
406
+ #: app/features/events.php:2816 app/features/mec/booking.php:127
407
  #: app/features/mec/booking.php:799 app/features/mec/booking.php:896
408
+ #: app/features/mec/single.php:309 app/libraries/main.php:4205
409
  msgid "Checkboxes"
410
  msgstr "Checkboxes"
411
 
412
  #: app/core/src/Forms/FormFields.php:421 app/core/src/Forms/FormFields.php:467
413
+ #: app/core/src/Forms/FormFields.php:520 app/libraries/main.php:4232
414
+ #: app/libraries/main.php:4280 app/libraries/main.php:4335
415
  msgid "Option"
416
  msgstr "Option"
417
 
418
  #: app/core/src/Forms/FormFields.php:443
419
+ #: app/core/src/Forms/SettingsForm.php:123 app/features/events.php:2729
420
+ #: app/features/events.php:2817 app/features/mec/booking.php:800
421
  #: app/features/mec/booking.php:897 app/features/mec/single.php:310
422
+ #: app/libraries/main.php:4253
423
  msgid "Radio Buttons"
424
  msgstr "Radio Buttons"
425
 
426
  #: app/core/src/Forms/FormFields.php:489
427
+ #: app/core/src/Forms/SettingsForm.php:128 app/features/events.php:2730
428
+ #: app/features/events.php:2818 app/features/mec/booking.php:125
429
  #: app/features/mec/booking.php:801 app/features/mec/booking.php:898
430
  #: app/features/mec/meta_boxes/search_form.php:67
431
  #: app/features/mec/meta_boxes/search_form.php:75
508
  #: app/features/mec/meta_boxes/search_form.php:1094
509
  #: app/features/mec/meta_boxes/search_form.php:1116
510
  #: app/features/mec/single.php:311 app/features/popup/settings.php:348
511
+ #: app/libraries/main.php:4301
512
  msgid "Dropdown"
513
  msgstr "Dropdown"
514
 
517
  msgstr ""
518
 
519
  #: app/core/src/Forms/FormFields.php:545
520
+ #: app/core/src/Forms/SettingsForm.php:133 app/features/events.php:2731
521
+ #: app/features/events.php:2819 app/features/mec/booking.php:802
522
+ #: app/features/mec/booking.php:899 app/libraries/main.php:4359
523
  msgid "Agreement"
524
  msgstr "Zustimmung"
525
 
526
+ #: app/core/src/Forms/FormFields.php:557 app/libraries/main.php:4372
527
  #, php-format
528
  msgid "Instead of %s, the page title with a link will be show."
529
  msgstr "Anstelle von %s, wird der Seitentitel mit einem Link gezeigt"
530
 
531
  #: app/core/src/Forms/FormFields.php:559 app/features/mec/settings.php:1145
532
+ #: app/libraries/main.php:4374
533
  msgid "Agreement Page"
534
  msgstr "Zustimmungsseite"
535
 
536
  #: app/core/src/Forms/FormFields.php:570 app/features/profile/profile.php:62
537
+ #: app/libraries/main.php:4383
538
  msgid "Status"
539
  msgstr ""
540
 
541
+ #: app/core/src/Forms/FormFields.php:572 app/libraries/main.php:4385
542
  msgid "Checked by default"
543
  msgstr ""
544
 
545
+ #: app/core/src/Forms/FormFields.php:573 app/libraries/main.php:4386
546
  msgid "Unchecked by default"
547
  msgstr ""
548
 
549
+ #: app/core/src/Forms/FormFields.php:598 app/libraries/main.php:4410
550
  msgid "Insert a label for this option"
551
  msgstr "Ein neues Label für diese Option einfügen"
552
 
553
+ #: app/core/src/Forms/FormFields.php:606 app/libraries/main.php:8984
554
  msgid "Mapping with Profile Fields"
555
  msgstr ""
556
 
698
  #: app/features/events.php:1404 app/features/events.php:1541
699
  #: app/features/events.php:1666 app/features/events.php:1836
700
  #: app/features/events.php:1849 app/features/events.php:2020
701
+ #: app/features/events.php:2035 app/features/events.php:2277
702
+ #: app/features/events.php:2289 app/features/events.php:2482
703
+ #: app/features/events.php:2519 app/features/fes/form.php:458
704
  #: app/features/fes/form.php:766 app/features/fes/form.php:901
705
+ #: app/features/gateways.php:1433 app/features/gateways.php:3355
706
+ #: app/features/gateways.php:3368 app/features/gateways.php:3655
707
+ #: app/features/gateways.php:4021 app/features/gateways.php:4074
708
+ #: app/features/gateways.php:4092 app/features/gateways.php:4821
709
+ #: app/features/gateways.php:5959 app/features/gateways.php:5979
710
+ #: app/features/gateways.php:6317 app/features/locations.php:341
711
+ #: app/features/mec/booking.php:109 app/features/mec/booking.php:185
712
+ #: app/features/mec/booking.php:198 app/features/mec/booking.php:234
713
+ #: app/features/mec/booking.php:299 app/features/mec/booking.php:332
714
+ #: app/features/mec/booking.php:345 app/features/mec/booking.php:411
715
+ #: app/features/mec/booking.php:462 app/features/mec/booking.php:598
716
+ #: app/features/mec/booking.php:628 app/features/mec/booking.php:694
717
+ #: app/features/mec/booking.php:704 app/features/mec/booking.php:726
718
+ #: app/features/mec/booking.php:736 app/features/mec/booking.php:1006
719
+ #: app/features/mec/booking.php:1034 app/features/mec/integrations.php:57
720
  #: app/features/mec/integrations.php:70 app/features/mec/integrations.php:86
721
  #: app/features/mec/meta_boxes/display_options.php:98
722
  #: app/features/mec/meta_boxes/display_options.php:111
788
  #: app/features/popup/settings.php:78 app/features/popup/settings.php:161
789
  #: app/features/popup/settings.php:182 app/features/popup/settings.php:300
790
  #: app/libraries/ticketVariations.php:50 app/libraries/ticketVariations.php:65
791
+ #: app/skins/single.php:1213 app/skins/single.php:1329
792
  #: app/skins/single/default.php:25 app/skins/single/m1.php:16
793
  #: app/skins/single/m2.php:16 app/skins/single/modern.php:26
794
  msgid "Read More"
908
  msgstr ""
909
 
910
  #: app/core/src/SingleBuilder/Widgets/EventCategories/EventCategories.php:47
911
+ #: app/features/events.php:218 app/features/events.php:3858
912
  #: app/features/mec/meta_boxes/display_options.php:1657
913
  #: app/features/mec/meta_boxes/search_form.php:64
914
  #: app/features/mec/meta_boxes/search_form.php:152
925
  #: app/features/mec/settings.php:1165 app/features/mec/settings.php:1228
926
  #: app/features/mec/single.php:460 app/features/mec/single.php:513
927
  #: app/features/popup/settings.php:220 app/features/popup/settings.php:259
928
+ #: app/features/search.php:91 app/libraries/main.php:7411
929
+ #: app/libraries/main.php:7472 app/libraries/search.php:256
930
  #: app/libraries/skins.php:1090 app/skins/single.php:1090
931
  #: app/skins/single/default.php:299 app/skins/single/default.php:549
932
  #: app/skins/single/m1.php:231 app/skins/single/m2.php:151
949
  #: app/core/src/SingleBuilder/Widgets/EventCost/EventCost.php:47
950
  #: app/features/events.php:432 app/features/events.php:1283
951
  #: app/features/fes/form.php:868 app/features/mec/settings.php:1162
952
+ #: app/features/occurrences.php:511 app/libraries/main.php:7457
953
+ #: app/libraries/main.php:7504 app/libraries/skins.php:1405
954
+ #: app/skins/single.php:1121 app/skins/single/default.php:215
955
  #: app/skins/single/default.php:467 app/skins/single/m1.php:80
956
  #: app/skins/single/modern.php:293
957
  msgid "Cost"
1028
  msgstr ""
1029
 
1030
  #: app/core/src/SingleBuilder/Widgets/EventLabels/EventLabels.php:48
1031
+ #: app/features/events.php:4180 app/features/fes/form.php:998
1032
  #: app/features/labels.php:61 app/features/labels.php:227
1033
+ #: app/features/mec.php:515 app/features/mec/meta_boxes/filter.php:72
1034
+ #: app/features/mec/meta_boxes/filter.php:135 app/libraries/main.php:7412
1035
+ #: app/libraries/main.php:7473 app/skins/single.php:1248
1036
  #: app/skins/single/default.php:247 app/skins/single/default.php:496
1037
  #: app/skins/single/m1.php:95 app/skins/single/modern.php:308
1038
  msgid "Labels"
1064
  msgstr "Ort verbergen"
1065
 
1066
  #: app/core/src/SingleBuilder/Widgets/EventLocations/EventLocations.php:54
1067
+ #: app/features/events.php:3859 app/features/events.php:4173
1068
  #: app/features/locations.php:58 app/features/locations.php:267
1069
  #: app/features/locations.php:329 app/features/locations.php:331
1070
  #: app/features/locations.php:340
1087
  #: app/features/popup/event.php:118 app/features/popup/event.php:127
1088
  #: app/features/popup/settings.php:228 app/features/popup/settings.php:267
1089
  #: app/features/search.php:97 app/libraries/main.php:2961
1090
+ #: app/libraries/main.php:3238 app/libraries/main.php:7415
1091
+ #: app/libraries/main.php:7476 app/libraries/search.php:294
1092
  #: app/libraries/skins.php:1145 app/skins/single.php:1017
1093
+ #: app/skins/single.php:1520 app/skins/single/default.php:268
1094
  #: app/skins/single/default.php:519 app/skins/single/m1.php:201
1095
  #: app/skins/single/m2.php:121 app/skins/single/modern.php:153
1096
  msgid "Location"
1099
  #: app/core/src/SingleBuilder/Widgets/EventLocations/EventLocations.php:63
1100
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:77
1101
  #: app/features/speakers.php:136 app/features/speakers.php:209
1102
+ #: app/skins/single.php:1401 app/skins/single.php:1468
1103
  #: app/skins/single/default.php:276 app/skins/single/default.php:354
1104
  #: app/skins/single/default.php:526 app/skins/single/default.php:603
1105
  #: app/skins/single/m1.php:148 app/skins/single/m1.php:209
1122
  #: app/core/src/SingleBuilder/Widgets/EventMoreInfo/EventMoreInfo.php:48
1123
  #: app/features/events.php:1525 app/features/events.php:1538
1124
  #: app/features/fes/form.php:836 app/features/occurrences.php:525
1125
+ #: app/libraries/main.php:7455 app/libraries/main.php:7502
1126
+ #: app/skins/single.php:1218 app/skins/single/default.php:232
1127
  #: app/skins/single/default.php:481 app/skins/single/m1.php:257
1128
  #: app/skins/single/m2.php:178 app/skins/single/modern.php:211
1129
  #: app/widgets/single.php:105
1171
  msgstr "Veranstalter verbergen"
1172
 
1173
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:53
1174
+ #: app/features/events.php:431 app/features/events.php:3860
1175
+ #: app/features/events.php:4175 app/features/events.php:4176
1176
+ #: app/features/events.php:4177
1177
  #: app/features/mec/meta_boxes/display_options.php:1660
1178
  #: app/features/mec/meta_boxes/search_form.php:80
1179
  #: app/features/mec/meta_boxes/search_form.php:168
1195
  #: app/features/organizers.php:288 app/features/popup/event.php:165
1196
  #: app/features/popup/event.php:174 app/features/popup/settings.php:224
1197
  #: app/features/popup/settings.php:263 app/features/search.php:103
1198
+ #: app/libraries/main.php:7417 app/libraries/main.php:7478
1199
  #: app/libraries/search.php:314 app/libraries/skins.php:1174
1200
+ #: app/skins/single.php:1376 app/skins/single/default.php:329
1201
  #: app/skins/single/default.php:578 app/skins/single/m1.php:123
1202
  #: app/skins/single/m2.php:43 app/skins/single/modern.php:76
1203
  msgid "Organizer"
1204
  msgstr "Veranstalter"
1205
 
1206
  #: app/core/src/SingleBuilder/Widgets/EventOrganizers/EventOrganizers.php:63
1207
+ #: app/skins/single.php:1387 app/skins/single.php:1454
1208
  #: app/skins/single/default.php:340 app/skins/single/default.php:589
1209
  #: app/skins/single/m1.php:134 app/skins/single/m2.php:54
1210
  #: app/skins/single/modern.php:87
1238
  msgstr "Register Button"
1239
 
1240
  #: app/core/src/SingleBuilder/Widgets/EventRegisterButton/EventRegisterButton.php:48
1241
+ #: app/libraries/main.php:7451 app/libraries/main.php:7498
1242
  #: app/skins/available_spot/tpl.php:204 app/skins/carousel/render.php:105
1243
  #: app/skins/carousel/render.php:145 app/skins/grid/render.php:94
1244
  #: app/skins/grid/render.php:153 app/skins/grid/render.php:214
1245
  #: app/skins/grid/render.php:237 app/skins/list/render.php:90
1246
  #: app/skins/list/render.php:210 app/skins/masonry/render.php:151
1247
+ #: app/skins/single.php:548 app/skins/single.php:1324 app/skins/single.php:1335
1248
  #: app/skins/single/default.php:374 app/skins/single/default.php:376
1249
  #: app/skins/single/default.php:621 app/skins/single/default.php:623
1250
  #: app/skins/single/m1.php:166 app/skins/single/m1.php:168
1309
  #: app/core/src/SingleBuilder/Widgets/EventTime/EventTime.php:43
1310
  #: app/features/emails/details.php:24 app/features/emails/details.php:27
1311
  #: app/libraries/skins.php:1362 app/modules/next-event/details.php:151
1312
+ #: app/skins/single.php:1292 app/skins/single/default.php:190
1313
  #: app/skins/single/default.php:442 app/skins/single/m1.php:59
1314
  #: app/skins/single/modern.php:272
1315
  msgid "Time"
1317
 
1318
  #: app/core/src/SingleBuilder/Widgets/EventTime/EventTime.php:49
1319
  #: app/features/booking/calendar_novel.php:140
1320
+ #: app/features/search_bar/search_result.php:12 app/libraries/main.php:7460
1321
+ #: app/libraries/main.php:7507 app/libraries/notifications.php:1632
1322
  #: app/libraries/render.php:554 app/libraries/render.php:758
1323
  #: app/libraries/render.php:816 app/libraries/render.php:977
1324
  #: app/modules/local-time/details.php:52 app/modules/local-time/type1.php:47
1325
  #: app/modules/local-time/type2.php:83 app/modules/local-time/type3.php:47
1326
  #: app/modules/next-event/details.php:157
1327
+ #: app/modules/next-event/multiple.php:72 app/skins/single.php:1298
1328
  #: app/skins/single/default.php:196 app/skins/single/default.php:448
1329
  #: app/skins/single/m1.php:65 app/skins/single/modern.php:278
1330
  #, fuzzy
1366
  msgid "%s notification(s) sent."
1367
  msgstr "Benachrichtigungen"
1368
 
1369
+ #: app/features/autoemails.php:61 app/features/mec.php:532
1370
  #, fuzzy
1371
  #| msgid "Email"
1372
  msgid "Emails"
1426
  msgid "Coupon was not valid or applicable."
1427
  msgstr ""
1428
 
1429
+ #: app/features/cart.php:174 app/features/gateways.php:105
1430
+ #: app/features/gateways.php:594 app/features/gateways.php:1876
1431
+ #: app/features/gateways.php:2452 app/features/gateways.php:3778
1432
+ #: app/features/gateways.php:3956 app/features/gateways.php:5027
1433
+ #: app/features/gateways.php:5354 app/features/gateways.php:5605
1434
+ #: app/features/gateways.php:6441 app/features/gateways.php:6619
1435
  msgid "Request is invalid!"
1436
  msgstr "Die Anfrage ist ungültig!"
1437
 
1439
  msgid "Your cart is not free!"
1440
  msgstr ""
1441
 
1442
+ #: app/features/cart.php:191 app/features/gateways.php:112
1443
  #, fuzzy
1444
  #| msgid "Thanks for your booking."
1445
  msgid "Thanks for your booking."
1457
  msgid "Go to events page"
1458
  msgstr "Google Maps auf der Veranstaltungsseite anzeigen"
1459
 
1460
+ #: app/features/cart/cart.php:43 app/features/events.php:4719
1461
  #: app/features/fes.php:280 app/features/mec/booking.php:351
1462
  #: app/features/wc.php:81 app/libraries/main.php:3013
1463
  #: app/libraries/main.php:3127 app/libraries/main.php:3230
1478
 
1479
  #: app/features/cart/cart.php:45 app/features/events.php:1564
1480
  #: app/features/events.php:1930 app/libraries/book.php:172
1481
+ #: app/libraries/main.php:7445 app/modules/booking/steps/tickets.php:168
1482
  #: app/modules/booking/steps/tickets.php:174
1483
  msgid "Tickets"
1484
  msgstr "Tickets"
1523
  msgstr "kostenfrei"
1524
 
1525
  #: app/features/cart/checkout.php:96 app/features/contextual.php:308
1526
+ #: app/features/events.php:397 app/features/gateways.php:3425
1527
+ #: app/features/mec/booking.php:88 app/features/mec/notifications.php:45
1528
+ #: app/features/mec/support-page.php:110 app/features/mec/support-page.php:114
1529
+ #: app/libraries/main.php:647 app/libraries/main.php:648
1530
+ #: app/libraries/main.php:652 app/libraries/main.php:677
1531
+ #: app/libraries/main.php:795 app/libraries/main.php:3022
1532
+ #: app/libraries/main.php:7435 app/libraries/main.php:7437
1533
+ #: app/modules/booking/steps/checkout.php:146
1534
  msgid "Booking"
1535
  msgstr "Buchung / Reservierung"
1536
 
1551
  msgid "Recent Colors"
1552
  msgstr "Farbe der Veranstaltung"
1553
 
1554
+ #: app/features/contextual.php:55 app/features/mec.php:536
1555
+ #: app/features/mec/dashboard.php:126 app/features/mec/support.php:20
1556
  #: app/features/mec/wizard.php:521 app/features/popup/event.php:61
1557
  #: app/features/popup/settings.php:30 app/features/popup/shortcode.php:39
1558
  #: app/libraries/main.php:703
1560
  msgstr "Einstellungen"
1561
 
1562
  #: app/features/contextual.php:62 app/features/events.php:1571
1563
+ #: app/features/events.php:2661 app/features/mec/booking.php:756
1564
+ #: app/features/mec/booking.php:1032 app/features/mec/settings.php:1018
1565
  #: app/features/mec/support.php:29
1566
  msgid "Booking Form"
1567
  msgstr "Buchungsformular"
1741
  msgstr "Herausgenommene Tage "
1742
 
1743
  #: app/features/contextual.php:318 app/features/mec/booking.php:553
1744
+ #: app/features/mec/booking.php:989 app/libraries/main.php:649
1745
  msgid "Coupons"
1746
  msgstr "Gutscheine"
1747
 
1764
  msgid "Downloadable File"
1765
  msgstr "Download ICS Datei"
1766
 
1767
+ #: app/features/dlfile.php:142 app/features/dlfile.php:291
1768
  msgid "pdf,zip,png,jpg and gif files are allowed."
1769
  msgstr ""
1770
 
1771
+ #: app/features/dlfile.php:144 app/features/dlfile.php:293
1772
  #, fuzzy
1773
  #| msgid "Remove image"
1774
  msgid "Remove File"
1775
  msgstr "Bild entfernen"
1776
 
1777
+ #: app/features/dlfile.php:162 app/features/dlfile.php:319
1778
  msgid "Please upload a file."
1779
  msgstr ""
1780
 
1781
+ #: app/features/dlfile.php:170 app/features/dlfile.php:327
1782
  #, php-format
1783
  msgid "File extension is invalid. You can upload %s files."
1784
  msgstr ""
1785
 
1786
+ #: app/features/dlfile.php:176 app/features/dlfile.php:333
1787
  #, php-format
1788
  msgid "File is too big. Maximum size is %s KB."
1789
  msgstr ""
1790
 
1791
+ #: app/features/dlfile.php:206 app/features/dlfile.php:363
1792
  #, fuzzy
1793
  #| msgid "The image is uploaded!"
1794
  msgid "File uploaded!"
1795
  msgstr "Das Bild ist hochgeladen"
1796
 
1797
+ #: app/features/dlfile.php:287
1798
  msgid "Public File to Download"
1799
  msgstr ""
1800
 
1801
+ #: app/features/dlfile.php:297 app/features/events.php:3857
1802
+ #: app/features/events.php:4166 app/features/events.php:4713
1803
+ #: app/features/fes/form.php:260 app/features/gateways.php:1414
1804
+ #: app/features/gateways.php:3343 app/features/gateways.php:3636
1805
+ #: app/features/gateways.php:4055 app/features/gateways.php:4802
1806
+ #: app/features/gateways.php:5940 app/features/gateways.php:6298
1807
+ #: app/features/mec/booking.php:686 app/features/mec/booking.php:718
1808
+ #: app/features/mec/styling.php:134 app/libraries/hourlyschedule.php:49
1809
+ #: app/libraries/hourlyschedule.php:65 app/libraries/hourlyschedule.php:93
1810
+ #: app/libraries/hourlyschedule.php:125 app/libraries/hourlyschedule.php:145
1811
+ #: app/libraries/ticketVariations.php:39
1812
+ msgid "Title"
1813
+ msgstr "Titel"
1814
+
1815
+ #: app/features/dlfile.php:301 app/features/events.php:1994
1816
+ #: app/features/events.php:2254 app/features/events.php:4167
1817
+ #: app/libraries/hourlyschedule.php:72 app/libraries/hourlyschedule.php:100
1818
+ #: app/libraries/hourlyschedule.php:152
1819
+ msgid "Description"
1820
+ msgstr "Beschreibung"
1821
+
1822
  #: app/features/emails/details.php:26
1823
  #, fuzzy
1824
  #| msgid "Send Email"
1871
  msgstr "Nächstes Event"
1872
 
1873
  #: app/features/emails/details.php:40 app/features/events.php:192
1874
+ #: app/features/ix/export.php:37 app/features/mec/dashboard.php:217
1875
+ #: app/libraries/main.php:6430 app/libraries/main.php:6450
1876
  #: app/skins/daily_view/tpl.php:84 app/skins/monthly_view/calendar_clean.php:46
1877
  #: app/skins/monthly_view/tpl.php:76 app/skins/tile/tpl.php:85
1878
  #: app/skins/yearly_view/tpl.php:73
1887
  msgid "Placeholders"
1888
  msgstr ""
1889
 
1890
+ #: app/features/events.php:194 app/features/mec.php:512
1891
  #: app/features/mec/wizard.php:511
1892
  msgid "Add Event"
1893
  msgstr "Veranstaltung hinzufügen"
1894
 
1895
+ #: app/features/events.php:195 app/features/mec/dashboard.php:125
1896
  msgid "Add New Event"
1897
  msgstr "Neue Veranstaltung hinzufügen"
1898
 
1915
  msgid "No events found in Trash!"
1916
  msgstr "Keine Veranstaltungen im Papierkorb gefunden!"
1917
 
1918
+ #: app/features/events.php:219 app/features/events.php:3814
1919
+ #: app/features/events.php:4181 app/features/fes/form.php:972
1920
+ #: app/features/mec.php:514 app/features/mec/meta_boxes/filter.php:69
1921
+ #: app/features/mec/meta_boxes/filter.php:81 app/libraries/main.php:7410
1922
+ #: app/libraries/main.php:7471
1923
  msgid "Categories"
1924
  msgstr "Kategorien"
1925
 
2036
  msgstr "Veranstaltungsdetails"
2037
 
2038
  #: app/features/events.php:428 app/features/mec/settings.php:943
2039
+ #: app/libraries/hourlyschedule.php:36 app/skins/single.php:1560
2040
  msgid "Hourly Schedule"
2041
  msgstr "Stundenplan"
2042
 
2068
  msgid "Guest Data"
2069
  msgstr "Gäste Daten"
2070
 
2071
+ #: app/features/events.php:605 app/features/events.php:2647
2072
+ #: app/features/events.php:4423 app/features/fes.php:280
2073
+ #: app/features/fes/form.php:814 app/features/gateways.php:1282
2074
+ #: app/features/gateways.php:1372 app/features/gateways.php:1525
2075
+ #: app/features/gateways.php:1743 app/features/gateways.php:3193
2076
+ #: app/features/gateways.php:3295 app/features/labels.php:184
2077
  #: app/features/mec/booking.php:45 app/features/organizers.php:296
2078
+ #: app/features/popup/event.php:184 app/features/profile/profile.php:203
2079
  #: app/libraries/notifications.php:2090 app/modules/booking/steps/form.php:60
2080
  msgid "Name"
2081
  msgstr "Name"
2091
  msgstr "Datum und Uhrzeit"
2092
 
2093
  #: app/features/events.php:622 app/features/events.php:626
2094
+ #: app/features/events.php:3861 app/features/events.php:4168
2095
  #: app/features/fes/form.php:286 app/features/fes/form.php:290
2096
+ #: app/features/ix/import_g_calendar.php:38 app/features/mec.php:1545
2097
  #: app/features/mec/meta_boxes/display_options.php:57
2098
  #: app/features/mec/meta_boxes/display_options.php:312
2099
  #: app/features/mec/meta_boxes/display_options.php:578
2115
  msgstr "Start Datum"
2116
 
2117
  #: app/features/events.php:642 app/features/events.php:646
2118
+ #: app/features/events.php:3862 app/features/events.php:4170
2119
  #: app/features/fes/form.php:306 app/features/fes/form.php:310
2120
+ #: app/features/ix/import_g_calendar.php:44 app/features/mec.php:1546
2121
  #: app/features/mec/meta_boxes/display_options.php:73
2122
  #: app/features/mec/meta_boxes/display_options.php:328
2123
  #: app/features/mec/meta_boxes/display_options.php:594
2172
  #: app/features/events.php:716 app/features/events.php:729
2173
  #: app/features/events.php:1768 app/features/events.php:1778
2174
  #: app/features/events.php:1799 app/features/events.php:1819
2175
+ #: app/features/events.php:1874 app/features/events.php:2444
2176
+ #: app/features/events.php:2567 app/features/events.php:2678
2177
  #: app/features/fes/form.php:347 app/features/fes/form.php:360
2178
  msgid "Inherit from global options"
2179
  msgstr "Aus den globalen Einstellungen übernehmen"
2235
  msgstr "Wiederholend"
2236
 
2237
  #: app/features/events.php:770 app/features/fes/form.php:390
2238
+ #: app/features/mec.php:1548 app/skins/default_full_calendar/tpl.php:79
2239
  #: app/skins/full_calendar/tpl.php:140
2240
  msgid "Daily"
2241
  msgstr "Täglich"
2259
  msgstr "Wöchentlich"
2260
 
2261
  #: app/features/events.php:805 app/features/fes/form.php:395
2262
+ #: app/features/mec.php:1549 app/skins/default_full_calendar/tpl.php:77
2263
  #: app/skins/full_calendar/tpl.php:138
2264
  msgid "Monthly"
2265
  msgstr "Monatlich"
2266
 
2267
  #: app/features/events.php:812 app/features/fes/form.php:396
2268
+ #: app/features/mec.php:1550 app/skins/default_full_calendar/tpl.php:76
2269
  #: app/skins/full_calendar/tpl.php:137
2270
  msgid "Yearly"
2271
  msgstr "Jährlich"
2299
  msgstr "Pro Version vom Modernen Event Calendar"
2300
 
2301
  #: app/features/events.php:860 app/features/events.php:2107
2302
+ #: app/features/events.php:2135 app/features/events.php:2349
2303
  #: app/features/fes/form.php:420 app/features/ix/import_f_calendar.php:42
2304
  #: app/features/ix/import_g_calendar.php:51
2305
  #: app/features/ix/import_meetup.php:40 app/features/ix/thirdparty.php:35
2309
 
2310
  #: app/features/events.php:874 app/features/events.php:1398
2311
  #: app/features/events.php:2091 app/features/events.php:2173
2312
+ #: app/features/events.php:2338 app/features/events.php:2382
2313
+ #: app/features/events.php:2455 app/features/events.php:2572
2314
  #: app/features/fes/form.php:451 app/features/fes/form.php:1070
2315
  #: app/features/occurrences.php:113 app/features/organizers.php:340
2316
  #: app/libraries/hourlyschedule.php:57 app/libraries/hourlyschedule.php:134
2329
  msgstr ""
2330
 
2331
  #: app/features/events.php:891 app/features/events.php:2111
2332
+ #: app/features/events.php:2139 app/features/events.php:2353
2333
  #: app/features/fes/form.php:436 app/libraries/skins.php:1356
2334
  msgid "End"
2335
  msgstr "Ende"
2389
  msgid "Show only one occurrence of this event"
2390
  msgstr "Nächstes Auftreten von anderen Events."
2391
 
2392
+ #: app/features/events.php:1277 app/features/events.php:4178
2393
  #: app/features/fes/form.php:865
2394
  #: app/features/mec/meta_boxes/search_form.php:116
2395
  #: app/features/mec/meta_boxes/search_form.php:204
2415
  #: app/features/mec/notifications.php:1628
2416
  #: app/features/mec/notifications.php:1778 app/features/mec/settings.php:860
2417
  #: app/features/notifications.php:160 app/features/occurrences.php:508
2418
+ #: app/libraries/main.php:7456 app/libraries/main.php:7503
2419
  #: app/widgets/single.php:101
2420
  msgid "Event Cost"
2421
  msgstr ""
2516
 
2517
  #: app/features/events.php:1507 app/features/events.php:1515
2518
  #: app/features/fes/form.php:831 app/features/mec/settings.php:1163
2519
+ #: app/features/occurrences.php:520 app/libraries/main.php:7454
2520
+ #: app/libraries/main.php:7501
2521
  msgid "Event Link"
2522
  msgstr "Veranstaltungslink"
2523
 
2551
  msgstr "z.B. Noch mehr Informationen "
2552
 
2553
  #: app/features/events.php:1533 app/features/fes/form.php:840
2554
+ #: app/features/mec.php:1104 app/features/occurrences.php:529
2555
  #: app/features/popup/shortcode.php:481
2556
  msgid "Current Window"
2557
  msgstr "Aktuelles Fenster"
2558
 
2559
  #: app/features/events.php:1534 app/features/fes/form.php:841
2560
+ #: app/features/mec.php:1105 app/features/occurrences.php:530
2561
  #: app/features/popup/shortcode.php:485
2562
  msgid "New Window"
2563
  msgstr "Neues Fenster"
2584
  msgid "Total User Booking Limits"
2585
  msgstr "Gesamt Verfügbare Plätze"
2586
 
2587
+ #: app/features/events.php:1566 app/features/events.php:2432
2588
  msgid "Fees"
2589
  msgstr "Gebühren"
2590
 
2591
+ #: app/features/events.php:1569 app/features/events.php:2562
2592
  #: app/features/mec/settings.php:1030
2593
  msgid "Ticket Variations / Options"
2594
  msgstr ""
2595
 
2596
+ #: app/features/events.php:1573 app/features/mec/booking.php:1063
2597
  #: app/features/mec/support-page.php:118
2598
  #, fuzzy
2599
  #| msgid "Organizer Tel"
2601
  msgstr "Organisator Telefon"
2602
 
2603
  #: app/features/events.php:1581 app/features/ix/export.php:58
2604
+ #: app/libraries/main.php:7438
2605
  msgid "Bookings"
2606
  msgstr "Buchungen / Reservierungen"
2607
 
2612
  msgstr "Gesamt Verfügbare Plätze"
2613
 
2614
  #: app/features/events.php:1659 app/features/events.php:2057
2615
+ #: app/features/events.php:2304 app/modules/booking/default.php:116
2616
  #: app/modules/booking/default.php:221
2617
  #: app/modules/booking/steps/tickets.php:168
2618
  #: app/modules/booking/steps/tickets.php:174
2708
  msgstr "Email-Verifizierung"
2709
 
2710
  #: app/features/events.php:1769 app/features/events.php:1779
2711
+ #: app/features/gateways.php:5972 app/features/mec/booking.php:210
2712
+ #: app/features/mec/booking.php:277 app/features/mec/booking.php:292
2713
+ #: app/features/mec/booking.php:374 app/features/mec/booking.php:1000
2714
+ #: app/features/mec/booking.php:1027
2715
  #: app/features/mec/meta_boxes/search_form.php:66
2716
  #: app/features/mec/meta_boxes/search_form.php:74
2717
  #: app/features/mec/meta_boxes/search_form.php:82
2848
  msgstr "Deaktiviert"
2849
 
2850
  #: app/features/events.php:1770 app/features/events.php:1780
2851
+ #: app/features/gateways.php:5971 app/features/mec/booking.php:209
2852
+ #: app/features/mec/booking.php:276 app/features/mec/booking.php:293
2853
+ #: app/features/mec/booking.php:999 app/features/mec/booking.php:1028
2854
+ #: app/features/mec/modules.php:155 app/features/mec/settings.php:99
2855
+ #: app/features/popup/settings.php:357
2856
  msgid "Enabled"
2857
  msgstr "Aktiviert"
2858
 
2941
  msgstr "Ticket"
2942
 
2943
  #: app/features/events.php:1950 app/features/events.php:2217
2944
+ #: app/features/events.php:4165 app/features/fes.php:280
2945
  #: app/features/labels.php:183 app/features/locations.php:266
2946
  #: app/features/organizers.php:207 app/features/speakers.php:285
2947
  msgid "ID"
2952
  msgstr "Ticket Name"
2953
 
2954
  #: app/features/events.php:1962 app/features/events.php:2225
2955
+ #: app/features/events.php:4169 app/libraries/skins.php:1370
2956
  msgid "Start Time"
2957
  msgstr "Uhrzeit des Beginns"
2958
 
2959
  #: app/features/events.php:1976 app/features/events.php:2239
2960
+ #: app/features/events.php:4171 app/libraries/skins.php:1371
2961
  msgid "End Time"
2962
  msgstr "Uhrzeit Ende"
2963
 
 
 
 
 
 
 
2964
  #: app/features/events.php:2000 app/features/events.php:2003
2965
  #: app/features/events.php:2259 app/features/events.php:2262
2966
  #: app/features/mec/settings.php:1012
2978
 
2979
  #: app/features/events.php:2013 app/features/events.php:2017
2980
  #: app/features/events.php:2115 app/features/events.php:2142
2981
+ #: app/features/events.php:2271 app/features/events.php:2274
2982
+ #: app/features/events.php:2355 app/features/events.php:4722
2983
  #: app/features/mec/booking.php:690 app/features/mec/booking.php:693
2984
  #: app/features/mec/booking.php:722 app/features/mec/booking.php:725
2985
  #: app/libraries/ticketVariations.php:43 app/libraries/ticketVariations.php:46
2987
  msgid "Price"
2988
  msgstr "Preis"
2989
 
2990
+ #: app/features/events.php:2018 app/features/events.php:2275
2991
  #, fuzzy
2992
  #| msgid "Insert 0 for free ticket. Only numbers please."
2993
  msgid ""
2996
  msgstr "Bitte 0 für kostenloses Ticket eingeben. Bitte nur Zahlen eintragen"
2997
 
2998
  #: app/features/events.php:2027 app/features/events.php:2032
2999
+ #: app/features/events.php:2283 app/features/events.php:2286
3000
  msgid "Price Label"
3001
  msgstr "Preisschild"
3002
 
3003
+ #: app/features/events.php:2033 app/features/events.php:2287
3004
  msgid "For showing on website. e.g. $15"
3005
  msgstr "Um das auf der Webseite anzuzeigen zum Beispiel 15 €"
3006
 
3007
+ #: app/features/events.php:2044 app/features/events.php:2298
3008
  msgid "Available Tickets"
3009
  msgstr "Verfügbare Tickets: %s "
3010
 
3011
+ #: app/features/events.php:2063 app/features/events.php:2310
3012
  msgid "Minimum Ticket e.g. 3"
3013
  msgstr "Ticket minimum z.B. 3"
3014
 
3015
+ #: app/features/events.php:2066 app/features/events.php:2313
3016
  msgid "MinimumTicket"
3017
  msgstr "Ticket minimum"
3018
 
3019
+ #: app/features/events.php:2068 app/features/events.php:2315
3020
  msgid "Set a number for the minimum ticket reservation possible"
3021
  msgstr ""
3022
 
3023
+ #: app/features/events.php:2077 app/features/events.php:2324
3024
  msgid "e.g. 0"
3025
  msgstr "z.B. 0"
3026
 
3027
+ #: app/features/events.php:2079 app/features/events.php:2326
3028
  msgid "Day"
3029
  msgstr "Tag"
3030
 
3031
+ #: app/features/events.php:2080 app/features/events.php:2327
3032
  #: app/features/mec/notifications.php:1734
3033
  msgid "Hour"
3034
  msgstr "Stunde"
3035
 
3036
+ #: app/features/events.php:2082 app/features/events.php:2329
3037
  #, php-format
3038
  msgid "Stop selling ticket %s before event start."
3039
  msgstr ""
3040
 
3041
+ #: app/features/events.php:2089 app/features/events.php:2336
3042
  msgid "Price per Date"
3043
  msgstr "Preis pro Datum"
3044
 
3045
  #: app/features/events.php:2119 app/features/events.php:2145
3046
+ #: app/features/events.php:2357 app/features/labels.php:60
3047
  #: app/features/mec/meta_boxes/display_options.php:1658
3048
  #: app/features/mec/meta_boxes/search_form.php:101
3049
  #: app/features/mec/meta_boxes/search_form.php:189
3065
  msgid "Label"
3066
  msgstr "Label"
3067
 
3068
+ #: app/features/events.php:2163 app/features/events.php:2372
3069
  #, fuzzy
3070
  #| msgid "Maximum Per Ticket"
3071
  msgid "Variations Per Ticket"
3072
  msgstr "Maximum pro Ticket"
3073
 
3074
+ #: app/features/events.php:2168 app/features/events.php:2377
3075
  #, fuzzy
3076
  #| msgid "Inherit from global options"
3077
  msgid "Inherit from event options"
3078
  msgstr "Aus den globalen Einstellungen übernehmen"
3079
 
3080
+ #: app/features/events.php:2469 app/features/events.php:2508
3081
  #: app/features/mec/booking.php:590 app/features/mec/booking.php:620
3082
  msgid "Fee Title"
3083
  msgstr "Gebühren Name"
3084
 
3085
+ #: app/features/events.php:2475 app/features/events.php:2479
3086
+ #: app/features/events.php:2513 app/features/events.php:2516
3087
+ #: app/features/gateways.php:3419 app/features/mec/booking.php:594
3088
+ #: app/features/mec/booking.php:597 app/features/mec/booking.php:624
3089
+ #: app/features/mec/booking.php:627
3090
  msgid "Amount"
3091
  msgstr "Betrag"
3092
 
3093
+ #: app/features/events.php:2480 app/features/events.php:2517
3094
  #: app/features/mec/booking.php:598 app/features/mec/booking.php:628
3095
  msgid ""
3096
  "Fee amount, considered as fixed amount if you set the type to amount "
3099
  "Gebührenbetrag, gilt als fester Betrag, wenn Sie die Art auf Betrag setzen, "
3100
  "sonst als Prozentsatz"
3101
 
3102
+ #: app/features/events.php:2489 app/features/events.php:2526
3103
+ #: app/features/gateways.php:3420 app/features/mec/booking.php:605
3104
+ #: app/features/mec/booking.php:635
3105
  msgid "Percent"
3106
  msgstr "Prozent"
3107
 
3108
+ #: app/features/events.php:2490 app/features/events.php:2527
3109
  #: app/features/mec/booking.php:606 app/features/mec/booking.php:636
3110
  msgid "Amount (Per Ticket)"
3111
  msgstr "Betrag (pro Ticket)"
3112
 
3113
+ #: app/features/events.php:2491 app/features/events.php:2528
3114
  #: app/features/mec/booking.php:607 app/features/mec/booking.php:637
3115
  #, fuzzy
3116
  #| msgid "Amount (Per Ticket)"
3117
  msgid "Amount (Per Date)"
3118
  msgstr "Betrag (pro Ticket)"
3119
 
3120
+ #: app/features/events.php:2492 app/features/events.php:2529
3121
  #: app/features/mec/booking.php:608 app/features/mec/booking.php:638
3122
  msgid "Amount (Per Booking)"
3123
  msgstr "Betrag (pro Buchung)"
3124
 
3125
+ #: app/features/events.php:2664
3126
  msgid ""
3127
  "You're translating an event so MEC will use the original event for booking "
3128
  "form. You can only translate the field name and options. Please define exact "
3129
  "fields that you defined in the original event here."
3130
  msgstr ""
3131
 
3132
+ #: app/features/events.php:2690 app/features/mec/booking.php:758
3133
  #, fuzzy
3134
  #| msgid "Attendees List"
3135
  msgid "Per Attendee Fields"
3136
  msgstr "Teilnehmer Liste"
3137
 
3138
+ #: app/features/events.php:2781 app/features/mec/booking.php:856
3139
  #, fuzzy
3140
  #| msgid "Required Field"
3141
  msgid "Fixed Fields"
3142
  msgstr "Pflichtfeld"
3143
 
3144
+ #: app/features/events.php:2893 app/features/events.php:4716
3145
  #: app/features/mec/settings.php:1036 app/features/profile/profile.php:65
3146
  #: app/libraries/main.php:3048 app/libraries/main.php:3293
3147
  msgid "Attendees"
3148
  msgstr "Teilnehmer"
3149
 
3150
+ #: app/features/events.php:2896 app/features/occurrences.php:104
3151
  #, fuzzy
3152
  #| msgid "Next Occurrence"
3153
  msgid "Occurrence"
3154
  msgstr "Nächstes Event"
3155
 
3156
+ #: app/features/events.php:2897 app/features/mec.php:1764
3157
  #: app/features/occurrences.php:105
3158
  #, fuzzy
3159
  #| msgid "Next Occurrence"
3160
  msgid "Previous Occurrences"
3161
  msgstr "Nächstes Event"
3162
 
3163
+ #: app/features/events.php:2902 app/features/mec.php:1774
3164
+ #: app/features/occurrences.php:110 app/modules/next-event/multiple.php:55
3165
  #, fuzzy
3166
  #| msgid "Next Occurrence"
3167
  msgid "Next Occurrences"
3168
  msgstr "Nächstes Event"
3169
 
3170
+ #: app/features/events.php:3739 app/features/mec/meta_boxes/filter.php:199
3171
  #: app/features/mec/settings.php:517
3172
  msgid "Expired Events"
3173
  msgstr "Abgelaufene Events"
3174
 
3175
+ #: app/features/events.php:3740 app/features/mec.php:1355
3176
+ #: app/features/mec/dashboard.php:249 app/features/mec/settings.php:516
3177
  msgid "Upcoming Events"
3178
  msgstr "Bevorstehende Events"
3179
 
3180
+ #: app/features/events.php:3760 app/features/events.php:3778
3181
+ #: app/features/events.php:3796 app/features/events.php:3814
3182
  #, php-format
3183
  msgid "Show all %s"
3184
  msgstr "Zeige alle %s"
3185
 
3186
+ #: app/features/events.php:3760
3187
  msgid "labels"
3188
  msgstr "Labels + Eventstatus"
3189
 
3190
+ #: app/features/events.php:3778
3191
  msgid "locations"
3192
  msgstr "Orte"
3193
 
3194
+ #: app/features/events.php:3796
3195
  msgid "organizers"
3196
  msgstr "Veranstalter"
3197
 
3198
+ #: app/features/events.php:3830
3199
  msgid "Attendees List"
3200
  msgstr "Teilnehmer Liste"
3201
 
3202
+ #: app/features/events.php:3865
 
 
 
 
 
 
 
 
 
 
3203
  #, fuzzy
3204
  #| msgid "Tickets"
3205
  msgid "Sold Tickets"
3206
  msgstr "Tickets"
3207
 
3208
+ #: app/features/events.php:3867
3209
  msgid "Repeat"
3210
  msgstr "Wiederholen"
3211
 
3212
+ #: app/features/events.php:4036 app/features/events.php:4037
3213
  #, fuzzy
3214
  #| msgid "iCal Export"
3215
  msgid "iCal / Outlook Export"
3216
  msgstr "ical Export"
3217
 
3218
+ #: app/features/events.php:4039 app/features/events.php:4040
3219
  msgid "CSV Export"
3220
  msgstr "CSV Export"
3221
 
3222
+ #: app/features/events.php:4042 app/features/events.php:4043
3223
  msgid "MS Excel Export"
3224
  msgstr "MS Excel Export"
3225
 
3226
+ #: app/features/events.php:4045 app/features/events.php:4046
3227
  msgid "XML Export"
3228
  msgstr "XML Export"
3229
 
3230
+ #: app/features/events.php:4048 app/features/events.php:4049
3231
  msgid "JSON Export"
3232
  msgstr "JSON Export"
3233
 
3234
+ #: app/features/events.php:4051 app/features/events.php:4052
3235
+ #: app/features/events.php:4278
3236
  msgid "Duplicate"
3237
  msgstr "Kopie"
3238
 
3239
+ #: app/features/events.php:4172
3240
  msgid "Link"
3241
  msgstr "Link"
3242
 
3243
+ #: app/features/events.php:4174 app/features/locations.php:111
3244
  #: app/features/locations.php:181 app/features/locations.php:268
3245
  #: app/features/mec/meta_boxes/search_form.php:108
3246
  #: app/features/mec/meta_boxes/search_form.php:196
3258
  msgid "Address"
3259
  msgstr "Adresse"
3260
 
3261
+ #: app/features/events.php:4176
3262
  #, php-format
3263
  msgid "%s Tel"
3264
  msgstr "%s Tel"
3265
 
3266
+ #: app/features/events.php:4177
3267
  #, php-format
3268
  msgid "%s Email"
3269
  msgstr "%s Email"
3270
 
3271
+ #: app/features/events.php:4179 app/features/fes/form.php:951
3272
  #: app/features/mec/settings.php:866
3273
  msgid "Featured Image"
3274
  msgstr "Ausgewähltes Bild"
3275
 
3276
+ #: app/features/events.php:4182 app/features/fes/form.php:1044
3277
+ #: app/features/mec.php:513 app/features/mec/meta_boxes/filter.php:73
3278
  #: app/features/mec/meta_boxes/filter.php:153 app/features/tag.php:59
3279
  msgid "Tags"
3280
  msgstr "Schlagworte"
3281
 
3282
+ #: app/features/events.php:4186 app/features/fes/form.php:1066
3283
+ #: app/features/mec.php:522 app/features/mec/modules.php:34
3284
  #: app/features/mec/modules.php:43 app/features/mec/settings.php:937
3285
  #: app/features/popup/settings.php:299 app/features/speakers.php:61
3286
  #: app/libraries/hourlyschedule.php:77 app/libraries/hourlyschedule.php:105
3287
  #: app/libraries/hourlyschedule.php:157 app/libraries/main.php:659
3288
+ #: app/libraries/main.php:7418 app/libraries/main.php:7479
3289
  #: app/modules/speakers/details.php:18
3290
  msgid "Speakers"
3291
  msgstr "Sprecher"
3292
 
3293
+ #: app/features/events.php:4429 app/features/fes.php:280
3294
+ #: app/features/gateways.php:3426 app/features/profile/profile.php:209
3295
+ #: app/libraries/cart.php:64 app/libraries/main.php:3064
3296
+ #: app/libraries/main.php:3310 app/libraries/main.php:7444
3297
  msgid "Ticket"
3298
  msgstr "Ticket"
3299
 
3300
+ #: app/features/events.php:4432 app/features/profile/profile.php:212
3301
  msgid "Variations"
3302
  msgstr "Variationen"
3303
 
3304
+ #: app/features/events.php:4447 app/features/fes.php:356
3305
  msgid "Unknown"
3306
  msgstr "Unbekannt"
3307
 
3308
+ #: app/features/events.php:4475
3309
  msgid ""
3310
  "If you want to send an email, first select your attendees and then click in "
3311
  "the button below, please."
3312
  msgstr ""
3313
 
3314
+ #: app/features/events.php:4475 app/features/mec/report.php:57
3315
  msgid "Send Email"
3316
  msgstr "E-Mail senden"
3317
 
3318
+ #: app/features/events.php:4479
3319
  msgid "No Attendees Found!"
3320
  msgstr "Keine Teilnehmer gefunden!"
3321
 
3322
+ #: app/features/events.php:4777
3323
  #, fuzzy
3324
  #| msgid "No bookings found!"
3325
  msgid "No Bookings Found!"
3385
  msgid "Total Price"
3386
  msgstr "Gesamt Preis"
3387
 
3388
+ #: app/features/fes.php:280 app/features/gateways.php:189
3389
+ #: app/libraries/main.php:3122 app/libraries/main.php:3369
3390
  msgid "Gateway"
3391
  msgstr "Gateway"
3392
 
3454
  msgid "Please select at-least one label!"
3455
  msgstr "Bitte Tickets auswählen!"
3456
 
3457
+ #: app/features/fes.php:1376
3458
  #, fuzzy
3459
  #| msgid "The event submitted. It will publish as soon as possible."
3460
  msgid "Event submitted. It will publish as soon as possible."
3462
  "Die Veranstaltung wurde übermittelt. Sie wird sobald wie möglich "
3463
  "veröffentlicht werden."
3464
 
3465
+ #: app/features/fes.php:1377
3466
  msgid "The event published."
3467
  msgstr "Die Veranstaltung wurde veröffentlicht."
3468
 
3638
  msgid "No events found! %s"
3639
  msgstr "Keine Veranstaltungen gefunden! %s"
3640
 
3641
+ #: app/features/gateways.php:348
3642
+ #, fuzzy, php-format
3643
+ #| msgid ""
3644
+ #| "The %s ticket is sold out. You can try another ticket or another date."
3645
+ msgid ""
3646
+ "%s ticket is sold out! Please go back and select another ticket if available."
3647
+ msgstr ""
3648
+ "Der % s ist am gewählten Termin bereits ausgebucht. Bitte anderes Datum "
3649
+ "wählen. "
3650
+
3651
+ #: app/features/gateways.php:349 app/features/wc.php:212
3652
+ #: app/features/wc.php:238
3653
+ #, php-format
3654
+ msgid "Only %s slots remained for %s ticket so you cannot book %s ones."
3655
+ msgstr ""
3656
+
3657
+ #: app/features/gateways.php:370
3658
+ #, fuzzy, php-format
3659
+ #| msgid "MEC Transaction ID: %s"
3660
+ msgid "MEC Transaction ID: %s, Event Title: %s"
3661
+ msgstr "Transaktions-ID: %s"
3662
+
3663
+ #: app/features/gateways.php:417
3664
+ #, fuzzy, php-format
3665
+ #| msgid ""
3666
+ #| "The %s ticket is sold out. You can try another ticket or another date."
3667
+ msgid ""
3668
+ "%s Transaction: %s ticket is sold out! Please remove it and book another "
3669
+ "ticket if available."
3670
+ msgstr ""
3671
+ "Der % s ist am gewählten Termin bereits ausgebucht. Bitte anderes Datum "
3672
+ "wählen. "
3673
+
3674
+ #: app/features/gateways.php:418
3675
+ #, php-format
3676
+ msgid ""
3677
+ "%s Transaction: Only %s slots remained for %s ticket so you cannot book %s "
3678
+ "ones."
3679
+ msgstr ""
3680
+
3681
+ #: app/features/gateways.php:514
3682
+ #, fuzzy
3683
+ #| msgid ""
3684
+ #| "Thanks for your booking. Your tickets booked, booking verification might "
3685
+ #| "be needed, please check your email."
3686
+ msgid ""
3687
+ "Thank you for your booking. Your bookings are made, booking verification "
3688
+ "might be needed, please check your email."
3689
+ msgstr ""
3690
+ "Vielen Dank für Ihre Buchung. Für die gebuchten Tickets ist ggf. eine "
3691
+ "Bestätigung durch Sie erforderlich. Bitte überprüfen Sie Ihre Emails."
3692
+
3693
+ #: app/features/gateways.php:515 app/features/gateways.php:1149
3694
+ #: app/features/gateways.php:1218 app/features/gateways.php:2025
3695
+ #: app/features/gateways.php:3061 app/features/gateways.php:3130
3696
+ #: app/features/gateways.php:3720 app/features/gateways.php:4216
3697
+ #: app/features/gateways.php:4912 app/features/gateways.php:5453
3698
+ #: app/features/gateways.php:5856 app/features/gateways.php:6218
3699
+ #: app/features/gateways.php:6382 app/libraries/book.php:1104
3700
+ #: app/modules/booking/default.php:665 app/modules/booking/default.php:778
3701
+ msgid "Download Invoice"
3702
+ msgstr "Download Rechnung"
3703
+
3704
+ #: app/features/gateways.php:569 app/features/gateways.php:1404
3705
+ msgid "Stripe"
3706
+ msgstr "Stripe"
3707
+
3708
+ #: app/features/gateways.php:615 app/features/gateways.php:2473
3709
+ #: app/features/gateways.php:3799 app/features/gateways.php:4303
3710
+ #: app/features/gateways.php:5048 app/features/gateways.php:5697
3711
+ #: app/features/gateways.php:6143 app/features/gateways.php:6462
3712
+ #, fuzzy
3713
+ #| msgid "There is no attendee for booking!"
3714
+ msgid "There is no attendee for booking!"
3715
+ msgstr "Es gibt keinen Teilnehmer für die Buchung!"
3716
+
3717
+ #: app/features/gateways.php:764 app/features/gateways.php:2024
3718
+ #: app/features/gateways.php:2621 app/features/gateways.php:3874
3719
+ #: app/features/gateways.php:4428 app/features/gateways.php:4679
3720
+ #: app/features/gateways.php:5138 app/features/gateways.php:5452
3721
+ #: app/features/gateways.php:5788 app/features/gateways.php:6013
3722
+ #: app/features/gateways.php:6217 app/features/gateways.php:6537
3723
+ #: app/libraries/main.php:7439
3724
+ #, fuzzy
3725
+ #| msgid ""
3726
+ #| "Thanks for your booking. Your tickets booked, booking verification might "
3727
+ #| "be needed, please check your email."
3728
+ msgid ""
3729
+ "Thank you for booking. Your tickets are booked, booking verification might "
3730
+ "be needed, please check your email."
3731
+ msgstr ""
3732
+ "Vielen Dank für Ihre Buchung. Für die gebuchten Tickets ist ggf. eine "
3733
+ "Bestätigung durch Sie erforderlich. Bitte überprüfen Sie Ihre Emails."
3734
+
3735
+ #: app/features/gateways.php:793 app/features/gateways.php:1824
3736
+ #: app/features/gateways.php:2655
3737
+ #, fuzzy
3738
+ #| msgid "Your payment needs to get confirmed!"
3739
+ msgid "Your payment needs to be confirmed!"
3740
+ msgstr "Ihre Buchung muss bestätigt werden!"
3741
+
3742
+ #: app/features/gateways.php:794 app/features/gateways.php:831
3743
+ #: app/features/gateways.php:1825 app/features/gateways.php:1863
3744
+ #: app/features/gateways.php:2656 app/features/gateways.php:2708
3745
+ msgid "Unknown Error!"
3746
+ msgstr "Unbekannter Fehler!"
3747
+
3748
+ #: app/features/gateways.php:1155 app/features/gateways.php:1224
3749
+ #: app/features/gateways.php:3067 app/features/gateways.php:3136
3750
+ #: app/features/gateways.php:3726 app/features/gateways.php:4222
3751
+ #: app/features/gateways.php:4918 app/features/gateways.php:5862
3752
+ #: app/features/gateways.php:6219 app/features/gateways.php:6388
3753
+ #, fuzzy
3754
+ #| msgid "Download ICS file"
3755
+ msgid "Download File"
3756
+ msgstr "Download ICS Datei"
3757
+
3758
+ #: app/features/gateways.php:1294 app/features/gateways.php:1537
3759
+ #: app/features/gateways.php:3205
3760
+ msgid "Credit or debit card"
3761
+ msgstr ""
3762
+
3763
+ #: app/features/gateways.php:1306 app/features/gateways.php:1385
3764
+ #: app/features/gateways.php:1549 app/features/gateways.php:1756
3765
+ #: app/features/gateways.php:3217 app/features/gateways.php:3307
3766
+ #: app/features/gateways.php:4275 app/features/gateways.php:4569
3767
+ #: app/features/gateways.php:5011 app/features/gateways.php:5298
3768
+ msgid "Pay"
3769
+ msgstr "Bezahlen"
3770
+
3771
+ #: app/features/gateways.php:1369 app/features/gateways.php:1740
3772
+ #: app/features/gateways.php:3292
3773
+ msgid "You should complete the payment by returning back to the website."
3774
+ msgstr ""
3775
+
3776
+ #: app/features/gateways.php:1378 app/features/gateways.php:1749
3777
+ #: app/features/gateways.php:3301
3778
+ msgid "iDEAL Bank"
3779
+ msgstr ""
3780
+
3781
+ #: app/features/gateways.php:1424 app/features/gateways.php:1430
3782
+ #: app/features/gateways.php:3349 app/features/gateways.php:3354
3783
+ #: app/features/gateways.php:3367 app/features/gateways.php:3646
3784
+ #: app/features/gateways.php:3652 app/features/gateways.php:4065
3785
+ #: app/features/gateways.php:4071 app/features/gateways.php:4812
3786
+ #: app/features/gateways.php:4818 app/features/gateways.php:5950
3787
+ #: app/features/gateways.php:5956 app/features/gateways.php:6308
3788
+ #: app/features/gateways.php:6314
3789
+ msgid "Comment"
3790
+ msgstr "Kommentar"
3791
+
3792
+ #: app/features/gateways.php:1427 app/features/gateways.php:3351
3793
+ #, fuzzy
3794
+ #| msgid "Description"
3795
+ msgid "Stripe Gateway Description"
3796
+ msgstr "Beschreibung"
3797
+
3798
+ #: app/features/gateways.php:1431 app/features/gateways.php:3355
3799
+ #: app/features/gateways.php:3368 app/features/gateways.php:3653
3800
+ #: app/features/gateways.php:4072 app/features/gateways.php:4819
3801
+ #: app/features/gateways.php:5957 app/features/gateways.php:6315
3802
+ msgid "HTML allowed."
3803
+ msgstr "HTML erlaubt"
3804
+
3805
+ #: app/features/gateways.php:1440 app/features/gateways.php:3384
3806
+ #, fuzzy
3807
+ #| msgid "Date Method"
3808
+ msgid "Payment Method"
3809
+ msgstr "Datum Methode"
3810
+
3811
+ #: app/features/gateways.php:1443 app/features/gateways.php:3387
3812
+ #, fuzzy
3813
+ #| msgid "PayPal Credit Card"
3814
+ msgid "Credit Card"
3815
+ msgstr "PayPal Kreditkarte"
3816
+
3817
+ #: app/features/gateways.php:1444 app/features/gateways.php:3388
3818
+ msgid "iDEAL"
3819
+ msgstr ""
3820
+
3821
+ #: app/features/gateways.php:1450 app/features/gateways.php:1490
3822
+ #: app/features/gateways.php:3399 app/features/mec/settings.php:685
3823
+ msgid "Secret Key"
3824
+ msgstr "Geheimschlüssel"
3825
+
3826
+ #: app/features/gateways.php:1459 app/features/gateways.php:1496
3827
+ #: app/features/gateways.php:3405
3828
+ #, fuzzy
3829
+ #| msgid "Publishable Key"
3830
+ msgid "Publishable Key"
3831
+ msgstr "publizierbarer Schlüssel"
3832
+
3833
+ #: app/features/gateways.php:1467 app/features/gateways.php:1472
3834
+ #: app/features/gateways.php:3452 app/features/gateways.php:3457
3835
+ #: app/features/gateways.php:3662 app/features/gateways.php:3667
3836
+ #: app/features/gateways.php:4110 app/features/gateways.php:4115
3837
+ #: app/features/gateways.php:4866 app/features/gateways.php:4871
3838
+ #: app/features/gateways.php:5986 app/features/gateways.php:5991
3839
+ #: app/features/gateways.php:6324 app/features/gateways.php:6329
3840
+ #, fuzzy
3841
+ #| msgid "Currency Position"
3842
+ msgid "Position"
3843
+ msgstr "Position des Währungssymbols"
3844
+
3845
+ #: app/features/gateways.php:1840
3846
+ #, fuzzy, php-format
3847
+ #| msgid "MEC Transaction ID: %s"
3848
+ msgid "Transaction IDs: %s"
3849
+ msgstr "Transaktions-ID: %s"
3850
+
3851
+ #: app/features/gateways.php:2225 app/features/gateways.php:3328
3852
+ #, fuzzy
3853
+ #| msgid "Stripe"
3854
+ msgid "Stripe Connect"
3855
+ msgstr "Stripe"
3856
+
3857
+ #: app/features/gateways.php:3337
3858
+ msgid ""
3859
+ "Using this gateway, booking fee goes to the organizer account directly but "
3860
+ "you can get your fee in your Stripe account."
3861
+ msgstr ""
3862
+
3863
+ #: app/features/gateways.php:3338
3864
+ msgid ""
3865
+ "If organizer connects their account, then it will be the only enabled "
3866
+ "gateway for organizer events even if other gateways are enabled. Organizer "
3867
+ "Payment Module must be enabled to use this!"
3868
+ msgstr ""
3869
+
3870
+ #: app/features/gateways.php:3339
3871
+ #, fuzzy, php-format
3872
+ #| msgid "You should set %s as redirect page in Google App Console."
3873
+ msgid "You should set %s as Redirect URL in your Stripe dashboard."
3874
+ msgstr "Sie sollten% s als Redirect-Seite in der Google App Console setzen."
3875
+
3876
+ #: app/features/gateways.php:3362
3877
+ #, fuzzy
3878
+ #| msgid "Event Organizer"
3879
+ msgid "Comment for Organizer"
3880
+ msgstr "Veranstaltungsmanager"
3881
+
3882
+ #: app/features/gateways.php:3375
3883
+ #, fuzzy
3884
+ #| msgid "Countdown View"
3885
+ msgid "Connection Method"
3886
+ msgstr "Countdownansicht"
3887
+
3888
+ #: app/features/gateways.php:3378
3889
+ #: app/features/mec/meta_boxes/display_options.php:51
3890
+ #: app/features/mec/settings.php:404 app/features/mec/settings.php:481
3891
+ #: app/features/popup/settings.php:131 app/features/popup/shortcode.php:85
3892
+ msgid "Standard"
3893
+ msgstr "Standard"
3894
+
3895
+ #: app/features/gateways.php:3379
3896
+ #, fuzzy
3897
+ #| msgid "PayPal Express"
3898
+ msgid "Express"
3899
+ msgstr "PayPal Express"
3900
+
3901
+ #: app/features/gateways.php:3393
3902
+ #, fuzzy
3903
+ #| msgid "App Client ID"
3904
+ msgid "Client ID"
3905
+ msgstr "App Client ID"
3906
+
3907
+ #: app/features/gateways.php:3411
3908
+ msgid "Your Fee"
3909
+ msgstr ""
3910
+
3911
+ #: app/features/gateways.php:3418
3912
+ #, fuzzy
3913
+ #| msgid "Select All"
3914
+ msgid "Fee Type"
3915
+ msgstr "Alles Auswählen"
3916
+
3917
+ #: app/features/gateways.php:3424
3918
+ msgid "Per"
3919
+ msgstr "Pro"
3920
+
3921
+ #: app/features/gateways.php:3434 app/features/gateways.php:3444
3922
+ #, fuzzy
3923
+ #| msgid "Redirection Page"
3924
+ msgid "Redirection Page"
3925
+ msgstr "Weiterleitungs Seite "
3926
+
3927
+ #: app/features/gateways.php:3445
3928
+ msgid ""
3929
+ "Users will redirect to this page after connecting to your Stripe account. "
3930
+ "You can create a page to thank them. If you leave it empty then users will "
3931
+ "redirect to home page!"
3932
+ msgstr ""
3933
+
3934
+ #: app/features/gateways.php:3506 app/features/gateways.php:3513
3935
+ #, fuzzy
3936
+ #| msgid "Connect Your Account"
3937
+ msgid "Connect New Account"
3938
+ msgstr "Account verbinden"
3939
+
3940
+ #: app/features/gateways.php:3506
3941
+ msgid "Connect"
3942
+ msgstr ""
3943
+
3944
+ #: app/features/gateways.php:3509 app/features/gateways.php:3516
3945
+ msgid ""
3946
+ "You're connected to our account successfully and you will receive payments "
3947
+ "in your stripe account directly after deducting the fees."
3948
+ msgstr ""
3949
+
3950
+ #: app/features/gateways.php:3510
3951
+ #, fuzzy
3952
+ #| msgid "Login to Dashboard"
3953
+ msgid "Visit your dashboard"
3954
+ msgstr "Ins Dashboard einloggen"
3955
+
3956
+ #: app/features/gateways.php:3513
3957
+ msgid "Connect Your Account"
3958
+ msgstr "Account verbinden"
3959
+
3960
+ #: app/features/gateways.php:3560 app/features/gateways.php:4422
3961
+ #: app/features/gateways.php:4673 app/features/gateways.php:6008
3962
+ #, fuzzy
3963
+ #| msgid "Waiting for getting response from gateway."
3964
+ msgid "Waiting for a response from gateway."
3965
+ msgstr "Warte auf Antwort des Gateways."
3966
+
3967
+ #: app/features/gateways.php:3568
3968
+ #, fuzzy
3969
+ #| msgid "User get connected sucessfully!"
3970
+ msgid "User connected successfully!"
3971
+ msgstr "Nutzer wurde erfolgreich verbunden!"
3972
+
3973
+ #: app/features/gateways.php:3604 app/features/gateways.php:3625
3974
+ msgid "Pay Locally"
3975
+ msgstr "Vor Ort bezahlen"
3976
+
3977
+ #: app/features/gateways.php:3649
3978
+ #, fuzzy
3979
+ #| msgid "Geo latitude (Optional)"
3980
+ msgid "Pay Locally Description"
3981
+ msgstr "Geologischer Breitengrad (Optional)"
3982
+
3983
+ #: app/features/gateways.php:3674 app/features/gateways.php:6336
3984
+ #, fuzzy
3985
+ #| msgid "Confirmation"
3986
+ msgid "Disable Auto Confirmation"
3987
+ msgstr "Bestätigung"
3988
+
3989
+ #: app/features/gateways.php:3762 app/features/gateways.php:3895
3990
+ #: app/features/gateways.php:6425 app/features/gateways.php:6558
3991
+ #: app/modules/booking/steps/form.php:385
3992
+ msgid "Submit"
3993
+ msgstr "Buchung abschließen"
3994
+
3995
+ #: app/features/gateways.php:3996 app/features/gateways.php:4044
3996
+ msgid "PayPal Express"
3997
+ msgstr "PayPal Express"
3998
+
3999
+ #: app/features/gateways.php:4015 app/features/gateways.php:4020
4000
+ #: app/features/gateways.php:4082 app/features/gateways.php:4089
4001
+ msgid "Business Account"
4002
+ msgstr "Kundenkonto"
4003
+
4004
+ #: app/features/gateways.php:4021 app/features/gateways.php:4090
4005
+ msgid "Normally PayPal Email."
4006
+ msgstr "Normale PayPal Email."
4007
+
4008
+ #: app/features/gateways.php:4068
4009
+ #, fuzzy
4010
+ #| msgid "Description"
4011
+ msgid "Paypal Express Description"
4012
+ msgstr "Beschreibung"
4013
+
4014
+ #: app/features/gateways.php:4100 app/features/gateways.php:4856
4015
+ msgid "Mode"
4016
+ msgstr "Modus"
4017
+
4018
+ #: app/features/gateways.php:4104 app/features/gateways.php:4860
4019
+ msgid "Live"
4020
+ msgstr "Live"
4021
+
4022
+ #: app/features/gateways.php:4105 app/features/gateways.php:4861
4023
+ msgid "Sandbox"
4024
+ msgstr "Sandbox"
4025
+
4026
+ #: app/features/gateways.php:4287 app/features/gateways.php:4642
4027
+ #, fuzzy
4028
+ #| msgid "Redirection Page"
4029
+ msgid "Ready to checkout."
4030
+ msgstr "Weiterleitungs Seite "
4031
+
4032
+ #: app/features/gateways.php:4445 app/features/gateways.php:4684
4033
+ #: app/features/gateways.php:6021
4034
+ #, fuzzy
4035
+ #| msgid "Payment was invalid! Booking failed."
4036
+ msgid "Payment invalid! Booking failed."
4037
+ msgstr "Die Transaktion war ungültig. Die Buchung wurde nicht durchgeführt."
4038
+
4039
+ #: app/features/gateways.php:4717 app/features/gateways.php:4786
4040
+ msgid "PayPal Credit Card"
4041
+ msgstr "PayPal Kreditkarte"
4042
+
4043
+ #: app/features/gateways.php:4751 app/features/gateways.php:4829
4044
+ #, fuzzy
4045
+ #| msgid "API Username"
4046
+ msgid "API Username"
4047
+ msgstr "API Nutzername"
4048
+
4049
+ #: app/features/gateways.php:4757 app/features/gateways.php:4838
4050
+ #, fuzzy
4051
+ #| msgid "API Password"
4052
+ msgid "API Password"
4053
+ msgstr "API Passwort"
4054
+
4055
+ #: app/features/gateways.php:4763 app/features/gateways.php:4847
4056
+ msgid "API Signature"
4057
+ msgstr "API Signatur"
4058
+
4059
+ #: app/features/gateways.php:4796
4060
+ msgid ""
4061
+ "Below error is the latest error received from Paypal during the payment in "
4062
+ "frontend so it's not related to the configuration form. It might help you to "
4063
+ "find some misconfiguration on your Paypal account or inserted credentials."
4064
+ msgstr ""
4065
+
4066
+ #: app/features/gateways.php:4815
4067
+ #, fuzzy
4068
+ #| msgid "PayPal Credit Card"
4069
+ msgid "Paypal Credit Card Description"
4070
+ msgstr "PayPal Kreditkarte"
4071
+
4072
+ #: app/features/gateways.php:4965 app/features/gateways.php:5252
4073
+ #, fuzzy
4074
+ #| msgid "First name"
4075
+ msgid "First name"
4076
+ msgstr "Vorname"
4077
+
4078
+ #: app/features/gateways.php:4969 app/features/gateways.php:5256
4079
+ #, fuzzy
4080
+ #| msgid "Last name"
4081
+ msgid "Last name"
4082
+ msgstr "Nachname"
4083
+
4084
+ #: app/features/gateways.php:4973 app/features/gateways.php:5260
4085
+ msgid "Card Type"
4086
+ msgstr "Kartentyp"
4087
+
4088
+ #: app/features/gateways.php:4975 app/features/gateways.php:5262
4089
+ msgid "Visa"
4090
+ msgstr "Visa"
4091
+
4092
+ #: app/features/gateways.php:4976 app/features/gateways.php:5263
4093
+ msgid "MasterCard"
4094
+ msgstr "MasterCard"
4095
+
4096
+ #: app/features/gateways.php:4977 app/features/gateways.php:5264
4097
+ msgid "Discover"
4098
+ msgstr "Discover"
4099
+
4100
+ #: app/features/gateways.php:4978 app/features/gateways.php:5265
4101
+ msgid "American Express"
4102
+ msgstr "American Express"
4103
+
4104
+ #: app/features/gateways.php:4982 app/features/gateways.php:5269
4105
+ msgid "CC Number"
4106
+ msgstr "Kartennummer"
4107
+
4108
+ #: app/features/gateways.php:4986 app/features/gateways.php:5273
4109
+ msgid "Expiration Date"
4110
+ msgstr "Ablaufdatum"
4111
+
4112
+ #: app/features/gateways.php:5003 app/features/gateways.php:5290
4113
+ msgid "CVV2"
4114
+ msgstr "Kartenprüfnummer (CVV)"
4115
+
4116
+ #: app/features/gateways.php:5063 app/features/gateways.php:5371
4117
+ msgid "Payment is invalid."
4118
+ msgstr "Die Zahlung ist ungültig."
4119
+
4120
+ #: app/features/gateways.php:5508
4121
+ #, fuzzy, php-format
4122
+ #| msgid "Transaction ID"
4123
+ msgid "Transactions: %s"
4124
+ msgstr "Transaktions-ID"
4125
+
4126
+ #: app/features/gateways.php:5582 app/features/gateways.php:5925
4127
+ #, fuzzy
4128
+ #| msgid "Pay by WooCommerce"
4129
+ msgid "Pay by WooCommerce"
4130
+ msgstr "Zahlung über WooCommerce"
4131
+
4132
+ #: app/features/gateways.php:5664
4133
+ #, php-format
4134
+ msgid "Booking fee for %s"
4135
+ msgstr "Buchungsgebühr für% s"
4136
+
4137
+ #: app/features/gateways.php:5677
4138
+ #, fuzzy
4139
+ #| msgid "Your order is created. Please proceed with checkout."
4140
+ msgid "Order created. Please proceed with checkout."
4141
+ msgstr "Ihre Buchung ist erstellt. Bitte fortfahren mit checkout."
4142
+
4143
+ #: app/features/gateways.php:5903 app/features/gateways.php:5907
4144
+ #: app/libraries/cart.php:71 app/libraries/wc.php:109
4145
+ #: app/modules/booking/steps/checkout.php:55
4146
+ msgid "Checkout"
4147
+ msgstr "Zur Kasse gehen"
4148
+
4149
+ #: app/features/gateways.php:5936
4150
+ msgid "WooCommerce must be installed and activated first."
4151
+ msgstr "WooCommerce muss installiert werden und erst aktiviert werden."
4152
+
4153
+ #: app/features/gateways.php:5953
4154
+ #, fuzzy
4155
+ #| msgid "Pay by WooCommerce"
4156
+ msgid "WooCommerce Gateway Description"
4157
+ msgstr "Zahlung über WooCommerce"
4158
+
4159
+ #: app/features/gateways.php:5967
4160
+ #, fuzzy
4161
+ #| msgid "Automatically complete WC orders"
4162
+ msgid "Automatically complete WC orders"
4163
+ msgstr "WC-Aufträge automatisch abschließen"
4164
+
4165
+ #: app/features/gateways.php:5976
4166
+ #, fuzzy
4167
+ #| msgid "Automatically complete WC orders"
4168
+ msgid "Auto WC orders"
4169
+ msgstr "WC-Aufträge automatisch abschließen"
4170
+
4171
+ #: app/features/gateways.php:5977 app/features/mec/booking.php:1005
4172
+ msgid "It applies only to the orders that are related to MEC."
4173
+ msgstr "Sie gilt nur für Aufträge, die mit MEC zusammenhängen."
4174
+
4175
+ #: app/features/gateways.php:6108 app/libraries/main.php:4424
4176
+ msgid "Free"
4177
+ msgstr "kostenfrei"
4178
+
4179
+ #: app/features/gateways.php:6129
4180
+ msgid "This booking is not free!"
4181
+ msgstr "Diese Buchung ist nicht kostenlos!"
4182
+
4183
+ #: app/features/gateways.php:6266 app/features/gateways.php:6287
4184
+ msgid "Bank Transfer"
4185
+ msgstr ""
4186
+
4187
+ #: app/features/gateways.php:6311
4188
+ #, fuzzy
4189
+ #| msgid "Description"
4190
+ msgid "Bank Transfer Description"
4191
+ msgstr "Beschreibung"
4192
+
4193
  #: app/features/ix.php:108
4194
  msgid "MEC - Import / Export"
4195
  msgstr "MEC - Import / Export"
4541
  msgid "Add to Google Calendar"
4542
  msgstr "Zum Google Kalender hinzufügen"
4543
 
4544
+ #: app/features/ix/export_g_calendar.php:100 app/features/mec/booking.php:1253
4545
  #: app/features/mec/integrations.php:451 app/features/mec/modules.php:408
4546
  #: app/features/mec/notifications.php:1924 app/features/mec/settings.php:1601
4547
  #: app/features/mec/single.php:597
4657
  msgid "Import all of your Facebook events into MEC."
4658
  msgstr "Importiere alle Deine Facebook Events zum MEC"
4659
 
4660
+ #: app/features/ix/import_f_calendar.php:27 app/features/mec/dashboard.php:127
4661
  #: app/features/mec/support-page.php:11 app/features/mec/support.php:100
4662
  msgid "Documentation"
4663
  msgstr "Dokumentation"
5068
  msgid "Event %s"
5069
  msgstr "Event %s"
5070
 
5071
+ #: app/features/locations.php:59 app/features/mec.php:516
5072
+ #: app/features/mec/dashboard.php:231 app/features/mec/meta_boxes/filter.php:70
5073
+ #: app/features/mec/meta_boxes/filter.php:99 app/libraries/main.php:7414
5074
+ #: app/libraries/main.php:7475
5075
  msgid "Locations"
5076
  msgstr "Orte"
5077
 
5190
  msgid "Don't show map in single event page"
5191
  msgstr "Karte in Einzelansicht nicht anzeigen"
5192
 
5193
+ #: app/features/locations.php:409 app/libraries/main.php:7459
5194
+ #: app/libraries/main.php:7506
5195
  msgid "Other Locations"
5196
  msgstr "Andere Orte"
5197
 
5229
  msgid "Forgot Password?"
5230
  msgstr "API Passwort"
5231
 
5232
+ #: app/features/mec.php:217
5233
  msgid ""
5234
  "Activation failed. Please check your purchase code or license type."
5235
  "<br><b>Note: Your purchase code should match your licesne type.</b>"
5236
  msgstr ""
5237
 
5238
+ #: app/features/mec.php:217 app/features/mec/support-page.php:136
5239
  msgid "Troubleshooting"
5240
  msgstr "Problembehebung"
5241
 
5242
+ #: app/features/mec.php:332
5243
  #, fuzzy
5244
  #| msgid "Select All"
5245
  msgid "Select Date"
5246
  msgstr "Alles Auswählen"
5247
 
5248
+ #: app/features/mec.php:336 app/skins/masonry.php:265
5249
  msgid "All"
5250
  msgstr "Alle"
5251
 
5252
+ #: app/features/mec.php:378
5253
  msgid ""
5254
  "Your option is not in JSON format. Please insert correct options in this "
5255
  "field and try again."
5256
  msgstr ""
5257
 
5258
+ #: app/features/mec.php:385
5259
  msgid "Your options field can not be empty!"
5260
  msgstr "Ihr Optionen Feld darf nicht leer sein!"
5261
 
5262
+ #: app/features/mec.php:391
5263
  msgid "Your options imported successfuly."
5264
  msgstr "Ihre Einstellungen wurden erfolgreich importiert."
5265
 
5266
+ #: app/features/mec.php:496
5267
  msgid "MEC - Support"
5268
  msgstr "MEC - Support"
5269
 
5270
+ #: app/features/mec.php:496 app/features/mec/support-page.php:9
5271
  #: app/features/mec/support.php:80 app/features/mec/support.php:93
5272
  msgid "Support"
5273
  msgstr "Support"
5274
 
5275
+ #: app/features/mec.php:517 app/features/mec/dashboard.php:238
5276
  #: app/features/mec/meta_boxes/filter.php:71
5277
  #: app/features/mec/meta_boxes/filter.php:117 app/features/organizers.php:59
5278
+ #: app/libraries/main.php:7416 app/libraries/main.php:7477
5279
  msgid "Organizers"
5280
  msgstr "Veranstalter"
5281
 
5282
+ #: app/features/mec.php:526 app/features/mec.php:587
5283
+ #: app/features/mec/dashboard.php:224
5284
  msgid "Shortcodes"
5285
  msgstr "Shortcodes"
5286
 
5287
+ #: app/features/mec.php:536
5288
  msgid "MEC - Settings"
5289
  msgstr "MEC - Einstellungen"
5290
 
5291
+ #: app/features/mec.php:538
5292
  msgid "MEC - Addons"
5293
  msgstr "MEC - Erweiterungen"
5294
 
5295
+ #: app/features/mec.php:538 app/features/mec/addons.php:11
5296
  msgid "Addons"
5297
  msgstr "Erweiterungen"
5298
 
5299
+ #: app/features/mec.php:539
5300
  msgid "MEC - Wizard"
5301
  msgstr ""
5302
 
5303
+ #: app/features/mec.php:539 app/features/mec/wizard.php:512
5304
  #: app/features/mec/wizard.php:517 app/features/mec/wizard.php:522
5305
  msgid "Wizard"
5306
  msgstr ""
5307
 
5308
+ #: app/features/mec.php:543
5309
  #, fuzzy
5310
  #| msgid "Support"
5311
  msgid "MEC - Report"
5312
  msgstr "Support"
5313
 
5314
+ #: app/features/mec.php:543
5315
  #, fuzzy
5316
  #| msgid "Export"
5317
  msgid "Report"
5318
  msgstr "Export"
5319
 
5320
+ #: app/features/mec.php:546
5321
  #, fuzzy
5322
  #| msgid "Support"
5323
  msgid "MEC - Go Pro"
5324
  msgstr "Support"
5325
 
5326
+ #: app/features/mec.php:546 app/features/mec.php:1426
5327
  #: app/features/mec/go-pro.php:9
5328
  msgid "Go Pro"
5329
  msgstr ""
5330
 
5331
+ #: app/features/mec.php:589 app/features/mec/wizard.php:516
5332
  msgid "Add Shortcode"
5333
  msgstr "Shortcode hinzufügen"
5334
 
5335
+ #: app/features/mec.php:590
5336
  msgid "Add New Shortcode"
5337
  msgstr "Neuen Shortcode hinzufügen"
5338
 
5339
+ #: app/features/mec.php:591
5340
  msgid "No shortcodes found!"
5341
  msgstr "Keine Shortcodes gefunden!"
5342
 
5343
+ #: app/features/mec.php:592
5344
  msgid "All Shortcodes"
5345
  msgstr "Alle Shortcodes"
5346
 
5347
+ #: app/features/mec.php:593
5348
  msgid "Edit shortcodes"
5349
  msgstr "Shortcode ändern"
5350
 
5351
+ #: app/features/mec.php:594
5352
  msgid "No shortcodes found in Trash!"
5353
  msgstr "Keine Shortcodes im Papierkorb gefunden!"
5354
 
5355
+ #: app/features/mec.php:647
5356
  msgid "Display Options"
5357
  msgstr "Darstellungsoptionen"
5358
 
5359
+ #: app/features/mec.php:648
5360
  msgid "Filter Options"
5361
  msgstr "Filteroptionen"
5362
 
5363
+ #: app/features/mec.php:650
5364
  msgid "Search Form"
5365
  msgstr "Suche Formular"
5366
 
5367
+ #: app/features/mec.php:1085
5368
  msgid "Display content's images as Popup"
5369
  msgstr ""
5370
 
5371
+ #: app/features/mec.php:1099 app/features/popup/shortcode.php:477
5372
  msgid "Single Event Display Method"
5373
  msgstr "Single Event Anzeigemethode"
5374
 
5375
+ #: app/features/mec.php:1106 app/features/popup/shortcode.php:489
5376
  #, fuzzy
5377
  #| msgid "Modal 1"
5378
  msgid "Modal Popup"
5379
  msgstr "Modal 1"
5380
 
5381
+ #: app/features/mec.php:1107
5382
  #, fuzzy
5383
  #| msgid "Disabled"
5384
  msgid "Disable Link"
5385
  msgstr "Deaktiviert"
5386
 
5387
+ #: app/features/mec.php:1117
5388
  msgid "Descending Order"
5389
  msgstr ""
5390
 
5391
+ #: app/features/mec.php:1133
5392
  #, fuzzy
5393
  #| msgid "Booking Options"
5394
  msgid "Booking Button / Icon"
5395
  msgstr "Buchungsoptionen"
5396
 
5397
+ #: app/features/mec.php:1146
5398
  #, fuzzy
5399
  #| msgid "Organizers"
5400
  msgid "Display Organizers"
5401
  msgstr "Veranstalter"
5402
 
5403
+ #: app/features/mec.php:1159
5404
  #, fuzzy
5405
  #| msgid "Custom Styles"
5406
  msgid "Display Custom Fields"
5407
  msgstr "Benutzerdefinierte Stile"
5408
 
5409
+ #: app/features/mec.php:1172
5410
  #, fuzzy
5411
  #| msgid "Date And Time"
5412
  msgid "Detailed Time"
5413
  msgstr "Datum und Uhrzeit"
5414
 
5415
+ #: app/features/mec.php:1173
5416
  #, fuzzy
5417
  #| msgid "Multiple Day Events"
5418
  msgid "For Multiple Day Events"
5419
  msgstr "Mehrtagesveranstaltung"
5420
 
5421
+ #: app/features/mec.php:1330 app/features/mec.php:1506
5422
  msgid "Total Bookings"
5423
  msgstr "Gesamte Buchungen"
5424
 
5425
+ #: app/features/mec.php:1346 app/features/mec/dashboard.php:57
5426
  msgid "Modern Events Calendar (Lite)"
5427
  msgstr "Moderner Event Kalender (Lite)"
5428
 
5429
+ #: app/features/mec.php:1412
5430
  #, fuzzy
5431
  #| msgid "Update %s"
5432
  msgid "News & Updates"
5433
  msgstr "Update %s"
5434
 
5435
+ #: app/features/mec.php:1425
5436
  msgid "Blog"
5437
  msgstr ""
5438
 
5439
+ #: app/features/mec.php:1425
5440
  msgid "Help"
5441
  msgstr ""
5442
 
5443
+ #: app/features/mec.php:1480
5444
  #, fuzzy, php-format
5445
  #| msgid "Total Sells (%s)"
5446
  msgid "Total Sales (%s)"
5447
  msgstr "Alle Verkäufe (%s)"
5448
 
5449
+ #: app/features/mec.php:1515
5450
  msgid "This Month"
5451
  msgstr "Diesen Monat"
5452
 
5453
+ #: app/features/mec.php:1521
5454
  msgid "Last Month"
5455
  msgstr "Letzten Monat"
5456
 
5457
+ #: app/features/mec.php:1527
5458
  msgid "This Year"
5459
  msgstr "Diese Jahr"
5460
 
5461
+ #: app/features/mec.php:1533
5462
  msgid "Last Year"
5463
  msgstr "Letztes Jahr"
5464
 
5465
+ #: app/features/mec.php:1553
5466
  msgid "Bar"
5467
  msgstr "Bar"
5468
 
5469
+ #: app/features/mec.php:1554
5470
  msgid "Line"
5471
  msgstr "Linie"
5472
 
5473
+ #: app/features/mec.php:1556 app/skins/general_calendar/tpl.php:145
5474
  msgid "Filter"
5475
  msgstr "Filter"
5476
 
5477
+ #: app/features/mec.php:1580
5478
  #, fuzzy
5479
  #| msgid "Modern Events Calendar"
5480
  msgid "Print Calendar"
5481
  msgstr "Moderner Event Kalender "
5482
 
5483
+ #: app/features/mec.php:1595
5484
  #, fuzzy
5485
  #| msgid "Multiple Day Events"
5486
  msgid "Display Events"
5487
  msgstr "Mehrtagesveranstaltung"
5488
 
5489
+ #: app/features/mec.php:1642
5490
  #, fuzzy
5491
  #| msgid "Include Expired Events"
5492
  msgid "Include MEC Assets"
5493
  msgstr "Inklusive abgelaufene Events"
5494
 
5495
+ #: app/features/mec.php:1653
5496
  msgid "Include Modern Events Calendar Assets (CSS, JavaScript, etc files.)"
5497
  msgstr ""
5498
 
5499
  #: app/features/mec/addons.php:16 app/features/mec/addons.php:62
5500
+ #: app/features/mec/dashboard.php:67 app/features/mec/go-pro.php:14
5501
  #: app/features/mec/report.php:21 app/features/mec/support-page.php:21
5502
  msgid "Version"
5503
  msgstr "Version"
5521
  msgstr "Suche…"
5522
 
5523
  #: app/features/mec/booking.php:72 app/features/mec/booking.php:906
5524
+ #: app/features/mec/booking.php:1103 app/features/mec/booking.php:1178
5525
+ #: app/features/mec/booking.php:1188 app/features/mec/booking.php:1270
5526
+ #: app/features/mec/booking.php:1284 app/features/mec/integrations.php:24
5527
  #: app/features/mec/integrations.php:400 app/features/mec/integrations.php:410
5528
  #: app/features/mec/integrations.php:468 app/features/mec/integrations.php:482
5529
  #: app/features/mec/messages.php:20 app/features/mec/messages.php:60
5965
  "new menu on the Dashboard > Booking"
5966
  msgstr ""
5967
 
5968
+ #: app/features/mec/booking.php:571 app/features/mec/booking.php:991
5969
  #: app/libraries/main.php:650
5970
  msgid "Taxes / Fees"
5971
  msgstr "Steuern/Gebühren"
6062
  "fields etc, you need to configure WooCommerce on your website."
6063
  msgstr ""
6064
 
6065
+ #: app/features/mec/booking.php:982
6066
+ msgid ""
6067
+ "Please disable MEC Cart first otherwise you're not able to use WooCommerce "
6068
+ "feature."
6069
+ msgstr ""
6070
+
6071
+ #: app/features/mec/booking.php:985
6072
  msgid ""
6073
  "You cannot use following MEC features so you should use WooCommerc and its "
6074
  "addons if you need them."
6075
  msgstr ""
6076
 
6077
+ #: app/features/mec/booking.php:987
6078
  #, fuzzy
6079
  #| msgid "Payment Gateways"
6080
  msgid "Payment gateways"
6081
  msgstr "Zahlungs-Gateways"
6082
 
6083
+ #: app/features/mec/booking.php:988
6084
  #, fuzzy
6085
  #| msgid "Price per Date"
6086
  msgid "Price per dates of tickets"
6087
  msgstr "Preis pro Datum"
6088
 
6089
+ #: app/features/mec/booking.php:990
6090
  #, fuzzy
6091
  #| msgid "Ticket Variation"
6092
  msgid "Ticket variations"
6093
  msgstr "Ticket Variationen"
6094
 
6095
+ #: app/features/mec/booking.php:992
6096
  #, fuzzy
6097
  #| msgid "Discount Type"
6098
  msgid "Discount Per Roles"
6099
  msgstr "Rabatt-Art"
6100
 
6101
+ #: app/features/mec/booking.php:996
6102
  #, fuzzy
6103
  #| msgid "Automatically complete WC orders"
6104
  msgid "Automatically complete WooCommerce orders"
6105
  msgstr "WC-Aufträge automatisch abschließen"
6106
 
6107
+ #: app/features/mec/booking.php:1004
6108
  #, fuzzy
6109
  #| msgid "Automatically complete WC orders"
6110
  msgid "Auto WooCommerce orders"
6111
  msgstr "WC-Aufträge automatisch abschließen"
6112
 
6113
+ #: app/features/mec/booking.php:1013 app/features/mec/booking.php:1151
 
 
 
 
6114
  #, fuzzy
6115
  #| msgid "Add to Cart"
6116
  msgid "After Add to Cart"
6117
  msgstr "in den Warenkorb legen"
6118
 
6119
+ #: app/features/mec/booking.php:1016 app/features/mec/booking.php:1154
6120
  #, fuzzy
6121
  #| msgid "Redirection Page"
6122
  msgid "Redirect to Cart"
6123
  msgstr "Weiterleitungs Seite "
6124
 
6125
+ #: app/features/mec/booking.php:1017 app/features/mec/booking.php:1155
6126
  #, fuzzy
6127
  #| msgid "Redirection Page"
6128
  msgid "Redirect to Checkout"
6129
  msgstr "Weiterleitungs Seite "
6130
 
6131
+ #: app/features/mec/booking.php:1018 app/features/mec/booking.php:1156
6132
  #, fuzzy
6133
  #| msgid "View Detail Button"
6134
  msgid "Optional View Cart Button"
6135
  msgstr "Ansicht Detail Button"
6136
 
6137
+ #: app/features/mec/booking.php:1019 app/features/mec/booking.php:1157
6138
  msgid "Optional Checkout Button"
6139
  msgstr ""
6140
 
6141
+ #: app/features/mec/booking.php:1024
6142
  #, fuzzy
6143
  #| msgid "Booking Form"
6144
  msgid "MEC Booking Form"
6145
  msgstr "Buchungsformular"
6146
 
6147
+ #: app/features/mec/booking.php:1033
6148
  msgid ""
6149
  "If enabled then users should fill the booking form in MEC and then they will "
6150
  "be redirected to checkout."
6151
  msgstr ""
6152
 
6153
+ #: app/features/mec/booking.php:1059
6154
  msgid "Enable Organizer Payment Module"
6155
  msgstr ""
6156
 
6157
+ #: app/features/mec/booking.php:1064
6158
  msgid ""
6159
  "By enabling this module, organizers are able to insert their own payment "
6160
  "credentials for enabled gateways per event and receive the payments directly!"
6161
  msgstr ""
6162
 
6163
+ #: app/features/mec/booking.php:1074
6164
  msgid "Disable / Enable payment gateways per event"
6165
  msgstr ""
6166
 
6167
+ #: app/features/mec/booking.php:1078
6168
  #, fuzzy
6169
  #| msgid "Payment Gateways"
6170
  msgid "Payment Gateways Per Event"
6171
  msgstr "Zahlungs-Gateways"
6172
 
6173
+ #: app/features/mec/booking.php:1079
6174
  msgid ""
6175
  "By enabling this module, users are able to disable / enable payment gateways "
6176
  "per event"
6177
  msgstr ""
6178
 
6179
+ #: app/features/mec/booking.php:1089
6180
  msgid "Automatically refund the payment"
6181
  msgstr ""
6182
 
6183
+ #: app/features/mec/booking.php:1093
6184
  msgid "Auto Refund"
6185
  msgstr ""
6186
 
6187
+ #: app/features/mec/booking.php:1094
6188
  msgid ""
6189
  "Automatically refund the payment when a booking paid by applicable gateways "
6190
  "(Stripe) got canceled."
6191
  msgstr ""
6192
 
6193
+ #: app/features/mec/booking.php:1113
6194
  msgid "Use MEC Cart System"
6195
  msgstr ""
6196
 
6197
+ #: app/features/mec/booking.php:1115
6198
  msgid ""
6199
  "If you don't want to use WooCommerce for any reason you can use MEC Cart for "
6200
  "adding a simple cart and checkout system to your website."
6201
  msgstr ""
6202
 
6203
+ #: app/features/mec/booking.php:1117
6204
  msgid "You cannot use following MEC features while using MEC Cart."
6205
  msgstr ""
6206
 
6207
+ #: app/features/mec/booking.php:1119
6208
  #, fuzzy
6209
  #| msgid "Payment Gateways"
6210
  msgid "WooCommerce as Payment Gateway"
6211
  msgstr "Zahlungs-Gateways"
6212
 
6213
+ #: app/features/mec/booking.php:1120
6214
  #, fuzzy
6215
  #| msgid "Next Occurrence of Other Events"
6216
  msgid "Currency Per Event"
6217
  msgstr "Nächstes Auftreten von anderen Events."
6218
 
6219
+ #: app/features/mec/booking.php:1121
6220
  #, fuzzy
6221
  #| msgid "Payment Gateways"
6222
  msgid "Disable Gateways Per Event"
6223
  msgstr "Zahlungs-Gateways"
6224
 
6225
+ #: app/features/mec/booking.php:1122
6226
  #, fuzzy
6227
  #| msgid "Stripe"
6228
  msgid "Stripe Connect Gateway"
6229
  msgstr "Stripe"
6230
 
6231
+ #: app/features/mec/booking.php:1123
6232
  #, fuzzy
6233
  #| msgid "Pay by WooCommerce"
6234
  msgid "Pay By WooCommerce Gateway"
6235
  msgstr "Zahlung über WooCommerce"
6236
 
6237
+ #: app/features/mec/booking.php:1127
6238
  #, fuzzy
6239
  #| msgid "Start Date"
6240
  msgid "Cart Page"
6241
  msgstr "Start Datum"
6242
 
6243
+ #: app/features/mec/booking.php:1135 app/features/mec/booking.php:1147
6244
  #: app/features/mec/settings.php:722 app/features/mec/settings.php:734
6245
  #, php-format
6246
  msgid "Put %s shortcode into the page."
6247
  msgstr "%s shortcode in die Seite einfügen"
6248
 
6249
+ #: app/features/mec/booking.php:1139
6250
  #, fuzzy
6251
  #| msgid "Checkout"
6252
  msgid "Checkout Page"
6253
  msgstr "Zur Kasse gehen"
6254
 
6255
+ #: app/features/mec/booking.php:1165
6256
  #, fuzzy
6257
  #| msgid "Enable Invoice"
6258
  msgid "Enable Cart Invoice"
6259
  msgstr "Rechnungen aktivieren"
6260
 
6261
+ #: app/features/mec/booking.php:1248 app/features/mec/integrations.php:446
6262
  #: app/features/mec/messages.php:90 app/features/mec/modules.php:403
6263
  #: app/features/mec/notifications.php:1919 app/features/mec/settings.php:1596
6264
  #: app/features/mec/single.php:592 app/features/mec/styles.php:62
6266
  msgid "Saved"
6267
  msgstr "Gesichert"
6268
 
6269
+ #: app/features/mec/booking.php:1249 app/features/mec/integrations.php:447
6270
  #: app/features/mec/messages.php:91 app/features/mec/modules.php:404
6271
  #: app/features/mec/notifications.php:1920 app/features/mec/settings.php:1597
6272
  #: app/features/mec/single.php:593 app/features/mec/styles.php:63
6274
  msgid "Settings Saved!"
6275
  msgstr "Einstellungen gespeichert!"
6276
 
6277
+ #: app/features/mec/booking.php:1275 app/features/mec/integrations.php:473
6278
  #: app/features/mec/modules.php:430 app/features/mec/notifications.php:1947
6279
  #: app/features/mec/settings.php:1623 app/features/mec/single.php:619
6280
  msgid "Please Refresh Page"
6281
  msgstr "Bitte Seiten Refresh vornehmen"
6282
 
6283
+ #: app/features/mec/dashboard.php:54
6284
  #, php-format
6285
  msgid "Welcome %s"
6286
  msgstr "Willkommen %s"
6287
 
6288
+ #: app/features/mec/dashboard.php:57
6289
  #, php-format
6290
  msgid "%s - Most Powerful & Easy to Use Events Management System"
6291
  msgstr ""
6292
 
6293
+ #: app/features/mec/dashboard.php:59 app/libraries/factory.php:217
6294
  msgctxt "plugin rate"
6295
  msgid "Rate the plugin ★★★★★"
6296
  msgstr "Bewerte das Plugin ★★★★★"
6297
 
6298
+ #: app/features/mec/dashboard.php:82 app/features/mec/go-pro.php:66
 
 
 
 
6299
  #, php-format
6300
  msgid ""
6301
  "You're using %s version of Modern Events Calendar. To use advanced booking "
6303
  "Spots, etc you should upgrade to the Pro version."
6304
  msgstr ""
6305
 
6306
+ #: app/features/mec/dashboard.php:82 app/features/mec/go-pro.php:66
6307
  msgid "lite"
6308
  msgstr ""
6309
 
6310
+ #: app/features/mec/dashboard.php:85 app/features/mec/go-pro.php:69
6311
  #: app/features/mec/support.php:126
6312
  msgid "GO PREMIUM"
6313
  msgstr ""
6314
 
6315
+ #: app/features/mec/dashboard.php:88 app/features/mec/go-pro.php:72
6316
  #, php-format
6317
  msgid ""
6318
  "Easily get a discount coupon by rating us on %s or following and reposting "
6319
  "us on social media. Just send a screenshot to %s and you'll receive the %s"
6320
  msgstr ""
6321
 
6322
+ #: app/features/mec/dashboard.php:88 app/features/mec/go-pro.php:72
6323
  msgid "WordPress"
6324
  msgstr "WordPress"
6325
 
6326
+ #: app/features/mec/dashboard.php:88 app/features/mec/go-pro.php:72
6327
  msgid "Copouns!"
6328
  msgstr "Gutscheine!"
6329
 
6330
+ #: app/features/mec/dashboard.php:118
6331
  msgid "Getting started with Modern Events Calendar"
6332
  msgstr "Lege los mit dem Modernen Event Kalender "
6333
 
6334
+ #: app/features/mec/dashboard.php:119
6335
  msgid ""
6336
  "In this short video, you can learn how to make an event and put a calendar "
6337
  "on your website. Please watch this 2 minutes video to the end."
6338
  msgstr ""
6339
 
6340
+ #: app/features/mec/dashboard.php:135 app/features/mec/dashboard.php:159
6341
  #, fuzzy
6342
  #| msgid "MEC Activation"
6343
  msgid "License Activation"
6344
  msgstr "MEC Aktivierung"
6345
 
6346
+ #: app/features/mec/dashboard.php:141 app/features/mec/dashboard.php:196
6347
  msgid "Activate Addons"
6348
  msgstr "MEC Erweiterungen Aktivieren"
6349
 
6350
+ #: app/features/mec/dashboard.php:149 app/features/mec/dashboard.php:205
6351
  msgid "You cannot access this section."
6352
  msgstr ""
6353
 
6354
+ #: app/features/mec/dashboard.php:165
6355
  msgid ""
6356
  "In order to use all plugin features and options, please enter your purchase "
6357
  "code."
6358
  msgstr ""
6359
 
6360
+ #: app/features/mec/dashboard.php:273
6361
  msgid "Popular Gateways"
6362
  msgstr "Beliebte Zahlungsgateways"
6363
 
6364
+ #: app/features/mec/dashboard.php:331
6365
  msgid "Change Log"
6366
  msgstr "Änderungsprotokoll"
6367
 
6731
  msgid "Modern"
6732
  msgstr "Modern"
6733
 
 
 
 
 
 
 
6734
  #: app/features/mec/meta_boxes/display_options.php:52
6735
  #: app/features/mec/settings.php:405 app/features/mec/settings.php:482
6736
  #: app/features/popup/settings.php:132 app/features/popup/shortcode.php:90
7911
  #: app/features/mec/single.php:526 app/features/popup/settings.php:233
7912
  #: app/features/popup/settings.php:272 app/features/search.php:109
7913
  #: app/features/speakers.php:60 app/features/speakers.php:286
7914
+ #: app/libraries/main.php:7419 app/libraries/main.php:7480
7915
  #: app/libraries/search.php:334 app/libraries/skins.php:1203
7916
  #: app/modules/speakers/details.php:18
7917
  msgid "Speaker"
9251
  msgid "only once per hour"
9252
  msgstr "nur einmal pro Tag"
9253
 
9254
+ #: app/features/mec/notifications.php:1314 app/libraries/main.php:8664
9255
+ #: app/libraries/main.php:8684
9256
  #, fuzzy
9257
  #| msgid "Hour"
9258
  msgid "Hours"
9582
  msgstr ""
9583
 
9584
  #: app/features/mec/settings.php:137 app/features/mec/settings.php:148
9585
+ #: app/features/popup/settings.php:41 app/libraries/main.php:7423
9586
+ #: app/libraries/main.php:7484
9587
  msgid "Weekdays"
9588
  msgstr "Wochentage"
9589
 
10023
  msgid "Site Key"
10024
  msgstr "Site Key (Seitenschlüssel)"
10025
 
 
 
 
 
10026
  #: app/features/mec/settings.php:697 app/features/mec/settings.php:705
10027
  msgid "Time Format"
10028
  msgstr "Zeitformat"
10266
  msgid "Required Fields"
10267
  msgstr "Pflichtfeld"
10268
 
10269
+ #: app/features/mec/settings.php:1164 app/libraries/main.php:7455
10270
+ #: app/libraries/main.php:7502
10271
  msgid "More Info Link"
10272
  msgstr "Link Mehr Informationen"
10273
 
11625
  msgid "eg. https://webnus.net"
11626
  msgstr "http://webnus.net"
11627
 
11628
+ #: app/features/organizers.php:329 app/libraries/main.php:7458
11629
+ #: app/libraries/main.php:7505 app/skins/single.php:1434
11630
  msgid "Other Organizers"
11631
  msgstr "Andere Veranstalter"
11632
 
11856
  msgid "MEC Pro"
11857
  msgstr "Support"
11858
 
11859
+ #: app/features/profile/profile.php:53 app/features/profile/profile.php:200
11860
  msgid "#"
11861
  msgstr ""
11862
 
11870
  msgid "Cancel"
11871
  msgstr "Abbrechen"
11872
 
11873
+ #: app/features/profile/profile.php:125
11874
  msgid "N/A"
11875
  msgstr ""
11876