File manager - Edit - /home/premiey/www/wp-includes/images/media/docs.tar
Back
core/database/query-builder.md 0000666 00000026016 15166361134 0012372 0 ustar 00 # Query Builder ## Product Knowledge Base: - [Laravel's Query Builder](https://laravel.com/docs/master/queries) ## Introduction: Elementor's database Query Builder provides a convenient, fluent interface to creating and running database queries. It can be used to perform most database operations and is heavily inspired by [Laravel's Query Builder](https://laravel.com/docs/master/queries). It integrates flawlessly with `WPDB` and automatically prepares and binds the SQL queries in order to prevent SQLi. ## Available Methods: Most of the methods are self-explanatory, and those which have some caveats will be explained below. - [`table()` / `from()`](#retrieve-all-rows-from-a-table---table--from) - [`select()`](#retrieve-specific-columns-from-a-table---select) - [`select_raw()`](#select-raw-columns---select_raw) - [`add_sub_select()`](#add-a-sub-select---add_sub_select) - [`add_count_select()`](#select-column-count---add_count_select) - [`when()`](#add-conditional-query-operations---when) - [`where()`](#filter-rows-by-conditions---where) - `or_where()` - [`where_null()`](#compare-to-null---where_null) - `or_where_null()` - [`where_column()`](#compare-column---where_column) - `or_where_column()` - [`where_in()`](#where-in---where_in) - `or_where_in()` - `where_not_in()` - `or_where_not_in()` - [`where_exists()`](#where-exists---where_exists) - `or_where_exists()` - `where_not_exists()` - `or_where_not_exists()` - `having_raw()` - `or_having_raw()` - [`join()`](#join-tables---join) - `left_join()` - `right_join()` - [`limit()`](#limit-results---limit-offset) - [`offset()`](#limit-results---limit-offset) - [`order_by()`](#order-results---order_by) - [`group_by()`](#group-results---group_by) - [`find()`](#find--get-the-first-row-by-a-single-condition---find) - [`first()`](#get-the-first-row-from-the-results---first) - [`get()`](#get-query-results---get) - [`to_sql()`](#get-sql-for-the-current-query---to_sql) - [`insert()`](#insert-new-row-to-a-table---insert) - [`update()`](#update-rows-in-a-table---update) - [`delete()`](#delete-rows-from-a-table---delete) ## Running Database Quries: Writing queries using the Query Builder is very similar to standard SQL syntax, just using composable functions. > *Note:* All of the examples below are assumed to have `$query = new Query_Builder()`. > *Note:* The Query Builder results always return a `Collection` instance (expect for `find()` & `first()` which return the first result). ### Retrieve All Rows From A Table - `table()` / `from()`: Select data from a specific table using the `table()` method: ```PHP $users = $query->table( 'users' )->get(); // Equivalent to: SELECT * FROM `users` ``` In addition, the method can receive a second parameter to define an alias: ```PHP $users = $query->table( 'users', 'test' )->get(); // Equivalent to: SELECT * FROM `users` AS `test` ``` ### Retrieve Specific Columns From A Table - `select()`: By default, when a `select()` isn't provided, all of the columns are selected. But sometimes only specific columns are needed: ```PHP $users = $query->select( [ 'id', 'user_name' ] ) ->from( 'users' ) ->get(); // Equivalent to: SELECT `id`, `user_name` FROM `users` ``` ### Select Raw Columns - `select_raw()`: When selecting raw columns, the `Query_Builder` won't prepare / bind the values, so it might cause SQLi - USE WITH CAUTION. ```PHP $data = $query->select_raw( [ 1, 'AVG( id )', 'DATE( "1970-01-01" )' ] ) ->from( 'users' ) ->get(); // Equivalent to: SELECT 1, AVG( id ), DATE( "1970-01-01" ) FROM `users` ``` ### Add A Sub Select - `add_sub_select()`: Add a sub select (e.g. `(SELECT ... ) AS alias`) to the query. This method expects a closure as a first parameter. The closure will receive a new instance of `Query_Builder` where a new query can be created. The second parameter is an alias of the sub select: ```PHP $data = $query->from( 'users' ) ->select( [ 'id' ] ) ->add_sub_select( function ( Query_Builder $q ) { $q->from( 'comments' ) ->select_raw( [ 'COUNT( `replies`.`id` )' ] ) ->where_column( 'comments.author_id', '=', 'users.id' ); }, 'comments_count' ) ->get(); /** * Equivalent to: * * SELECT `id`, * ( * SELECT COUNT( `replies`.`id` ) * FROM `comments` * WHERE `comments`.`author_id` = `users`.`id` * ) AS `comments_count` * * FROM `users` */ ``` ### Select Column count - `add_count_select()`: ```PHP $data = $query->from( 'users' ) ->select( [ 'id' ] ) ->add_count_select( 'id', 'users_count' ) ->get(); // Equivalent to: SELECT `id`, COUNT( `id` ) FROM `users` ``` ### Add Conditional Query Operations - `when()`: Sometimes query operations need to be added based on conditions, so in order to be able to continue the functions concatenation flow with `if`s, there is a way to execute those operations on the fly. This method expects a condition as a first parameter, and 2 closures as the other parameters. The closures will receive the current instance of the `Query_Builder` in order to modify it, and will also receive the condition as a second parameter. The first callback is required and will be executed when the condition is truthy, while the second one is optional and will be executed when the condition is falsy. ```PHP $users_ids = [ 1, 2, 3 ]; $data = $query->from( 'users' ) ->select( [ 'id', 'user_name' ] ) ->when( $users_ids, function( Query_Builder $q, $users_ids ) { $q->where_in( 'id', $users_ids ); }, function( Query_Builder $q ) { $q->where( 'id', '=', 1 ); } ) ->get(); /** * When `$users_ids` is truthy, it's equivalent to: * SELECT `id`, `user_name` FROM `users` WHERE `id` IN ( 1, 2, 3 ) * * When `$users_ids` is falsy, it's equivalent to: * SELECT `id`, `user_name` FROM `users` WHERE `id` = 1 */ ``` ### Filter Rows by conditions - `where()`: The `where()` method can filter the results and has multiple options depends on the provided parameters. #### Simple - `where( string $column, string $operator, string $value )` ```PHP $users = $query->from( 'users' ) ->where( 'id', '=', 1 ) ->get(); // Equivalent to: SELECT * FROM `users` WHERE `id` = 1 ``` #### Nested - `where( callable $callback )` Used to support nested conditions. ```PHP $users = $query->from( 'users' ) ->where( 'user_name', 'like', '%a%' ) ->where( function ( Query_Builder $q ) { $q->where( 'id', '=', 1 ) ->or_where( 'id', '=', 2 ); } ) ->get(); // Equivalent to: SELECT * FROM `users` WHERE `id` LIKE "%a%" AND ( `id` = 1 OR `id` = 2 ) ``` #### Sub select - `where( string $column, string $operator, callable $callback )` Used to support sub selects in `WHERE` statements. ```PHP $users = $query->from( 'users' ) ->where( 'user_name', '=', function ( Query_Builder $q ) { $q->select( [ 'author_name' ] ) ->from( 'posts' ) ->where( 'id', '=', 1 ); } ) ->get(); // Equivalent to: SELECT * FROM `users` WHERE `user_name` = ( SELECT `author_name` FROM `posts` WHERE `id` = 1 ) ``` #### Compare To NULL - `where_null()` ```PHP $users = $query->from( 'users' ) ->where_null( 'user_name' ) ->get(); // Equivalent to: SELECT * FROM `users` WHERE `user_name` IS NULL ``` #### Compare Columns - `where_column()` ```PHP $users = $query->from( 'users' ) ->where_column( 'user_name', '=', 'display_name' ) ->get(); // Equivalent to: SELECT * FROM `users` WHERE `user_name` = `display_name` ``` #### Where in - `where_in()` ```PHP $users = $query->from( 'users' ) ->where_in( 'id', [ 1, 2, 3 ] ) ->get(); // Equivalent to: SELECT * FROM `users` WHERE `id` IN ( 1, 2, 3 ) ``` #### Where exists - `where_exists()` Used to support `WHERE EXISTS` queries. The method expects a callback which receives a new instance of `Query_Builder`. ```PHP $users = $query->from( 'users' ) ->where_exists( function ( Query_Builder $q ) { $q->from( 'posts' ) ->select_raw( [ 1 ] ) ->where( 'posts.author_id', '=', 'users.id' ); } ) ->get(); // Equivalent to: SELECT * FROM `users` WHERE `id` IN ( 1, 2, 3 ) ``` ### Join Tables - `join()`: The `join()` methods expects a callback which receives a new instance of `Join_Clause`. ```PHP $users = $query->from( 'users' ) ->join( function ( Join_Clause $q ) { $q->table( 'posts' ) ->on_column( 'users.id', '=', 'posts.author_id' ); } ) ->get(); // Equivalent to: SELECT * FROM `users` JOIN `posts` ON `users`.`id` = `posts`.`author_id` ``` ### Limit Results - `limit()`, `offset()`: ```PHP $users = $query->from( 'users' ) ->limit( 10 ) ->offset( 2 ) ->get(); // Equivalent to: SELECT * FROM `users` LIMIT 10 OFFSET 2 ``` ### Order Results - `order_by()`: ```PHP $users = $query->from( 'users' ) ->order_by( 'id', 'asc' ) ->get(); // Equivalent to: SELECT * FROM `users` ORDER BY `id` ASC ``` ### Group Results - `group_by()`: ```PHP $users = $query->from( 'users' ) ->group_by( 'id' ) ->group_by( 'user_name' ) ->get(); // Equivalent to: SELECT * FROM `users` GROUP BY `id`, `user_name` ``` ### Find & Get The First Row By A Single Condition - `find()`: ```PHP $users = $query->table( 'users' )->find( 1 ); // Equivalent to: SELECT * FROM `users` WHERE `id` = 1 ``` The default column is `id`, but it can be overridden by passing a second parameter: ```PHP $users = $query->table( 'users' )->find( 1, 'user_id' ); // Equivalent to: SELECT * FROM `users` WHERE `user_id` = 1 ``` ### Get The First Row From The Results - `first()`: ```PHP $users = $query->table( 'users' ) ->where( 'id', '=', 1 ) ->first(); // Equivalent to: SELECT * FROM `users` WHERE `id` = 1 LIMIT 1 ``` ### Get Query Results - `get()`: ```PHP var_dump( $query->table( 'users' )->get() ); // Output: Collection with all of the users inside. ``` ### Get SQL For The Current Query - `to_sql()`: Get the SQL string *without bindings*: ```PHP echo $query->from( 'users' ) ->where( 'id', '=', 1 ) ->to_sql(); // Output: SELECT * FROM `users` WHERE `id` = %d ``` ### Insert New Row To A Table - `insert()`: Insert data to a table. The data should be an associative array with `column_name => value` pairs. Unlike any other SQL action in the Query Builder, under the hood this function uses `WPDB`'s built-in `insert()` method. ```PHP $inserted_id = $query->table( 'users' ) ->insert( [ 'user_name' => 'admin', 'password' => 'super_secret', ] ); // Equivalent to: INSERT INTO `users` ( `user_name`, `password` ) VALUES ( 'admin', 'super_secret' ) ``` ### Update Rows In A Table - `update()`: Update rows in a table. The data should be an associative array with `column_name => value` pairs. ```PHP $inserted_id = $query->table( 'users' ) ->where( 'id', '=', 1 ) ->update( [ 'email' => 'new_email@elementor.com', ] ); // Equivalent to: UPDATE `users` SET `email` = 'new_email@elementor.com' WHERE `id` = 1 ``` ### Delete Rows From A Table - `delete()`: ```PHP $inserted_id = $query->table( 'users' ) ->where( 'id', '=', 1 ) ->delete(); // Equivalent to: DELETE FROM `users` WHERE `id` = 1 ``` modules/forms/submissions/index.md 0000666 00000006270 15166361134 0013370 0 ustar 00 # Submissions The "Submissions" component is responsible for saving form submissions records in the database. It should be some kind of log that saves the user input data + status about the other actions assigned to the specific form. There are 4 subjects that will be explained in this document: database, "save-to-database" action, REST API, and the admin page. ## Database When the admin of the website enable 'submission' experiment the module immediately runs the database migrations (`modules/forms/submissions/database/migration.php`) which create 3 tables: 1. `e_submissions` - Holds the submission itself ( related_post, related_form, and some metadata ). 2. `e_submissions_values` - Each row has the field key, the input of the user, and the `submission_id`. 3. `e_submissions_action_log` - The table is a log that represents the other actions that run for the current submission (e.g, email, Mailchimp integration, etc.). Each row has a status, and a log message if exists. ## Save to Database Action This is a regular form action that extends the Base Action of Elementor which does 3 things: 1. Creates a new submission in the `e_submissions` table and multiple rows in `e_submissions_values` based on the form fields. 2. Saves a snapshot of the current form fields - this will help us later for showing the submissions result in the admin page to export the form values as CSV. 3. Listens to the responses of all the other form actions and saves them in the `e_submissions_action_log` table (this is the reason why the "save-to-database" action must be the first action that runs). ## REST API To show the admin all the submissions, the module introduces a few REST endpoints that return the submission data: 1. GET `/submissions` - which returns all the submissions without the values. 2. GET `/submissions/:id` - which returns a specific submission with its values. 3. GET `/forms` - which returns all the forms fields. - There are more routes that are less important such as the "export" route and "referer" route. - All those routes are available only for authenticated users that have the role of "admin". - Those routes can be used outside the admin page. ## Admin The admin page is responsible for showing all the submissions to the admin of the website. The submissions can be sorted, filtered, and exported, and edited. The page itself is built with React to provide a better user experience and uses the REST API as the source of data. ## Attention Needed - The DB migration is an independent system and doesn't use Elementor's upgrade system. - To create a new migration, just add a new class to the migrations folder and register it in the static prop `migrations` in `modules/forms/submissions/database/migration.php` + make sure to update the const `CURRENT_DB_VERSION` to the new version that you created. - Please review other migration files to make sure we don't repeat some issues twice (like `max index length`, and `charset` for the tables). - If you add some more data that belongs to a specific user, make sure to adjust `modules/forms/submissions/personal-data.php`. This class is responsible for exporting and removing the user-specific data, in order to get in line with the rules of GDPR, CCPA, etc. modules/code-highlight/code-highlight.md 0000666 00000010453 15166361134 0014311 0 ustar 00 ## Product knowledge base ### Quick Links * [PrismJS Website](https://prismjs.com/) * [PrismJS Line Numbers Plugin](https://prismjs.com/plugins/line-numbers/) * [PrismJS Line Height Plugin](https://prismjs.com/plugins/line-highlight/) * [PrismJS Copy to Clipboard Plugin](https://prismjs.com/plugins/copy-to-clipboard/) ### Video TBD: create a video tutorial ## Technical description The widget allow users to add code block with the abilities to: * Add specific code language. * Add line numbers for evey code block line. * Add a copy to clipboard button. * Highlight specific code block lines. * Break long code block lines to prevent a horizontal scroll. * Choose a specific theme for each code block. * Limit the height of the code block. * Change the font size of the code block ## Known issues / attention needed ### Style (CSS) All the css files for the 6 themes and 3 plugins are local and combined to a single CSS file instead of using the CDN, in order to avoid too many requests. Another reason is because we use custom classes to handle the selected themes and features (as line-numbers and such) when the code highlight is being used more than once in the same page. There are 3 SCSS files that gets combined into a single file: * `line-highlight.scss` - Includes the style for the line highlight plugin. (ver 1.23.0) * `line-numbers.scss` - Includes the style for the line numbers plugin. (ver 1.23.0) * `main-style.scss` - Includes the rest of the styles needed for the themes and plugins: * 6 themes: prism-twilight, prism-tomorrow, prism-solarizedlight, prism-okaidia, prism-dark, prism-solid. (ver 1.23.0) Each theme style is prefixed with a class specific for the theme (in order to support different themes for multiple code highlight instances on the same page). * 1 plugin: "copy to clipboard" style prefixed with a class (to support copy functionality only if the user has enabled it). (ver 1.23.0) * Specific style for the word-wrap feature * `code-highlight.scss` - The file helps to minimize HTTP requests by combining all the SCSS files to a single CSS file. There is a small CSS fix in `main-style.scss` which solves a conflict when highlighting lines while hiding line numbers. ### Functionality (JS) All the scripts are requested from a CDN instead of using local files since we found it difficult to manage all the plugins to work properly when combined to a single local file. There are 7 JS Files which we use from a CDN, the last 3 are added only if the user chose the functionality they responsible for: * `prismjs_core` - The minimum required code for the plugin functionality. (ver 1.23.0) * `prismjs_loader` Dynamically loading the language according to the user choice. (ver 1.23.0) * `prismjs_normalize` - Trimming all leading and trailing whitespace of every code block. (ver 1.23.0) * `prismjs_line_numbers` - Adding line numbers to the code block. (ver 1.23.0) * `prismjs_line_highlight` - Highlighting specific lines in code block. (ver 1.23.0) * `prismjs_toolbar` - Registering buttons (we use it for the copy to clipboard button). (ver 1.23.0) * `prismjs_copy_to_clipboard` - Adding the ability to copy the code block to the clipboard. (ver 1.23.0) `handler.js` - For the “word wrap” feature to work, we use the `onElementChange` method to run the prism plugin again and adjust to the changes. There is a plugin named `inline-color` that we had to remove since it only worked when we used the `PrismJS` plugin with all the languages included in the same file. That means one big file that includes the whole functionality of the plugin AND all the languages, which is a huge performance penalty. Instead, we use the prisms-loader plugin which dynamically loads the needed language when the user selects it and it means a smaller JS bundle. ### Functionality (PHP) `code-highlight.php` - The language control is used to give the user a code language selection from the most popular code languages. We've added an `apply_filter` to the control in order to give the user more flexibility when choosing a code language. We replaced the `typography` group control with just a `font-size` control since we didn’t manage to make the `line-height` work with the line numbers. This decision was made since most of the controls in the `typography` group control are not so useful in this case anyway. modules/page-transitions/assets/js/editor/module.md 0000666 00000001725 15166361134 0016535 0 ustar 00 # Page Transitions Editor Module ## Product Knowledge Base: - [Elementor Commands API](https://github.com/elementor/elementor/blob/master/docs/core/common/assets/js/api/core/commands.md) ## Technical Description: The Editor JS module for Elementor's Page Transitions. It registers all of the `hooks` & `commands` that are used in this module. ### Hooks: - Data Hook - `AnimatePageTransition` - Animates the Page Transition component when entrance / exit animations are changed. - Data Hook - `ReRenderPageTransition` - Passes the new settings from the panel as attributes to the Page Transition component, in order to re-render it. - Route Hook - `PageTransitionPreview` - Changes the Page Transition component state to preview mode when navigating to the `Site Settings -> Page Transitions` tab, so the user will be able to see what's changed in the Page Transition. ### Commands: - `$e.run( 'page-transitions/animate' )` - Animates the Page Transition component. modules/page-transitions/assets/js/frontend/components/page-transition.md 0000666 00000004410 15166361134 0023064 0 ustar 00 # Page Transitions Web Component - `<e-page-transition>` ## Product Knowledge Base: - [Web Components](https://developer.mozilla.org/en-US/docs/Web/Web_Components) - [Using custom elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) - [Using shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) - [Using templates and slots](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots) - [Barba.js](https://barba.js.org/) - 3rd party page transitions library. - [Swup.js](https://swup.js.org/) - 3rd party page transitions library. - [Instant Page](https://instant.page/) - Improves pages load using `<link relf="prefetch" />` ## Technical Description: A custom element that's responsible for creating & animating Elementor's Page Transitions. It's built as a Web Component and uses [Instant Page](https://instant.page/) library. This element can render an icon, an image or a custom pre-loader (using `<e-preloader>`) based on HTML attributes. (`preloader-type`, `preloader-icon`, `preloader-image-url`, `preloader-animation-type`). ## Attention Needed / Known Issues: - The CSS isn't encapsulated because some styles (CSS variables, etc.) are applied from the `Site Settings`, and we didn't use Shadow DOM, so any external CSS _could potentially be applied_ to this element. Use with caution. - Most of the styles are based on CSS variables (colors, animations, etc.) - see the code for reference. - The animation sequence is pretty complex. On page _enter_, the Page Transition component actually _exits_ the viewport, so it's treated as an exit animation in the code (and vice-versa). Additionally, the exit animation is actually handled by CSS, and the entrance animation by JS, which means the transition between pages is just an optical illusion for the user (plus it makes the code harder to maintain). We chose this approach since it's the only one that can make such feature work inside an existing WordPress website without converting everything to an SPA using AJAX over a headless WordPress setup (Or similar solutions). - "Instant Page" creates a `<link rel="prefetch" />` each time the mouse enters a link that should trigger a Page Transition. modules/page-transitions/assets/js/frontend/components/preloader.md 0000666 00000002560 15166361134 0021741 0 ustar 00 # Preloader Web Component - `<e-preloader>` ## Product Knowledge Base: - [Web Components](https://developer.mozilla.org/en-US/docs/Web/Web_Components) - [Using custom elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) - [Using shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) - [Using templates and slots](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots) - [CSS Loading Animations](https://codepen.io/EvyatarDa/pen/zNmdGb) ## Technical Description: A custom element that's responsible for preloading animations in Elementor's Page Transitions. It's built as a Web Component and renders some basic HTML structures for loading animations. This element can render custom pre-loaders based on the `type` attribute (`circle`, `circle-dashed`, `bouncing-dots`, `pulsing-dots`, etc.). ## Attention Needed / Known Issues: - The CSS isn't encapsulated, and we didn't use Shadow DOM, so any external CSS _could potentially be applied_ to this element, so use with caution. - Most of the styles are based on CSS variables (colors, animations, etc.) - see the code for reference. - All of the CSS selectors are based on the element name and the `type` attribute, and not using class names, so note that when you want to style a loader using an external CSS. modules/page-transitions/module.md 0000666 00000004173 15166361134 0013331 0 ustar 00 # Page Transitions Module ## Product Knowledge Base: - [ Prefetching, preloading, prebrowsing ](https://css-tricks.com/prefetching-preloading-prebrowsing/) on CSS Tricks. - [Instant Page](https://instant.page/) - [Preload, prefetch and other <link> tags](https://3perf.com/blog/link-rels/). ## Technical Description: This is the `Page Trantisions` module for the Pro version of Elementor (An experiment as of writing those lines). Page Transitions have been common in the web world for several years. Therefore, in order to align with the industry, we've added this feature. Our Page Transitions lets the user create rich transition between internal pages using spectacular entrance & exit animations, as well as custom loaders. ## Attention Needed / Known Issues: - At first, we thought about using a Page Transitions library for this feature, but all of them (or at least those we checked) don't really unloads the current page and loads a new one. They all use a custom mechanism that loads the next page into a "hidden browser tab" and then injects the HTML markup into the current page, while replacing the old content, which causes issues with scripts that should run on specific load events (`load`, `DOMContentLoaded`, etc.). Therefore, we ended up using a 3rd party library called [Instant Page](https://instant.page/) for faster loading times. Using this polyfill decreased the loading times by about 30% (!). See Also: [Barba.js](https://barba.js.org/), [Swup.js](https://swup.js.org/), [Instant Page](https://instant.page/). - This feature is also our first one ever that uses [Web Components](https://developer.mozilla.org/en-US/docs/Web/Web_Components) (!). Due to some technical difficulties (specifically changing settings on-the-fly from the Page Settings panel), we decided to use Web Components for the Page Transition element, and for the custom loaders (`e-page-transition` & `e-preloader` respectively). ___ See Also: [`module.js`](./assets/js/editor/module.md), [`<e-page-trantition>`](./assets/js/frontend/components/page-transition.md) & [`<e-preloader>`](./assets/js/frontend/components/preloader.md) modules/payments/classes/payment-button.php.md 0000666 00000003754 15166361134 0015632 0 ustar 00 # Payment-Button.php ## Technical Description: This is an abstract class that every payment button widget will inherit from. Because every payment button is, after all, a button, this class inherits from `Widget_Button` in order to keep it as close as possible to the default button widget ( and of course to avoid unnecessary code duplications ). This class is responsible for creating the universal sections && controls of the payment buttons. In addition, it has some abstract functions to make sure that every payment button will work as it should. ## Attention Needed / Known Issues: - Use the `register_account_section()` function in order to add the API controls for your payment provider. See `widgets/paypal-button.php` for reference. - Use the `register_sandbox_controls()` function if you need more sandbox controls than the default `sandbox_mode` switch. By default, they will be registered just after the switch. - Use the `after_product_type()` function when you need to add something after the product type select-box. This is useful when you want to add a note to the user. See `widgets/paypal-button.php` for reference. - Use the `after_custom_messages_toggle()` function when you need to add something after the `custom_messages` control. - The currencies list **defaults to PayPal's supported currencies**, so when you extend it, make sure that this list is also supported in the payment method you are using, or override it with the appropriate one. - The `get_custom_message( $id )` returns a custom message that is set in the `Custom Messages` control under the `Additional Settings` section, and will default to the default errors messages that returned from `get_default_error_messages()`. You can override this function in order to extend the default custom messages. Don't forget to extend the `register_settings_section()` and `register_messages_style_section()` functions as well. - You should use `is_sandbox()` to determine if it's on sandbox mode. modules/payments/widgets/paypal-button.php.md 0000666 00000004547 15166361134 0015455 0 ustar 00 # Paypal-Button.php ## Product Knowledge Base: - [PayPal Legacy Button HTML Reference](https://developer.paypal.com/docs/paypal-payments-standard/integration-guide/html-reference-landing/) - [PayPal API Reference](https://developer.paypal.com/docs/api/overview) ## Technical Description: This class handles the PayPal button widget. As of writing those lines, it only supports the **legacy** payments API of PayPal. We planned on adding support for the `Payments API` using the [PHP](https://developer.paypal.com/docs/api/payments/v2/) || [JavaScript](https://developer.paypal.com/docs/checkout/) SDKs but unfortunately both of them where not suitable for our needs. ### JavaScript SDK ( AKA "Smart Buttons" ): - The fast & easy-to-use option, but lack the support of button styling. - Forces you to pass basic argument like `currency` or `locale` as a query parameter to the script ( [See here](https://developer.paypal.com/docs/checkout/reference/customize-sdk/) ). That means you are limited to a single currency type for each page. ### PHP SDK: - You **can** style the button ( well, you use it with AJAX and you are not bounded to PayPal's style, so... ). - PayPal created a nice [Checkout SDK](https://github.com/paypal/Checkout-PHP-SDK) which works well, but luckily for us, it doesn't support anything other than a simple checkout request. Hurray! 🎉 We tried extending the SDK to at least support subscriptions, but creating a subscription in PayPal is complicated for the goal of a simple widget: You need to [create a Product](https://developer.paypal.com/docs/api/catalog-products/v1/#products_create), attach to [a Plan](https://developer.paypal.com/docs/api/subscriptions/v1/#plans_create) and finally pass it to [a Subscription](https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_create). #### They both also don't support donations, so we dropped this idea. ## Attention Needed / Known Issues: - `get_numeric_setting( $key, $min )` retrieves a value by `key` from `get_settings()`, and return it as a numeric value, or defaults to `$min` if it's non-existent or invalid. - `get_errors()` handles basic validations and returns an array of errors. - `get_api_method()` && `render_legacy_form()` are leftovers from the time we tried using the `Payments API` and might be used in the future if PayPal will provide a simpler API.
| ver. 1.4 |
Github
|
.
| PHP 5.4.45 | Generation time: 0.06 |
proxy
|
phpinfo
|
Settings