Skip to content

Commit 4ca1d69

Browse files
committed
Merge branch 'release/0.3.0'
2 parents a9dbfa2 + 1cc1eee commit 4ca1d69

68 files changed

Lines changed: 7851 additions & 2026 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.wordpress-org/blueprints/blueprint.json

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
{
22
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
33
"landingPage": "/wp-admin/post.php?post=4&action=edit",
4+
"preferredVersions": {
5+
"php": "8.3",
6+
"wp": "latest"
7+
},
48
"features": {
59
"networking": true
610
},
711
"login": true,
812
"siteOptions": {
9-
"blogname": "Freemius"
13+
"blogname": "Freemius for WordPress"
1014
},
1115
"steps": [
1216
{
@@ -19,12 +23,27 @@
1923
"activate": true
2024
}
2125
},
26+
{
27+
"step": "installTheme",
28+
"themeData": {
29+
"resource": "wordpress.org/themes",
30+
"slug": "ollie"
31+
}
32+
},
2233
{
2334
"step": "importWxr",
2435
"file": {
2536
"resource": "url",
2637
"url": "https://raw.githubusercontent.com/Freemius/freemius-wp-plugin/refs/heads/main/.wordpress-org/blueprints/content.xml"
2738
}
39+
},
40+
{
41+
"step": "runPHP",
42+
"code": "<?php require '/wordpress/wp-load.php'; update_option( 'freemius_settings', array( 'token' => '1234567890' ) );"
43+
},
44+
{
45+
"step": "runPHP",
46+
"code": "<?php require '/wordpress/wp-load.php'; update_option( 'freemius_defaults', array( 'public_key' => 'pk_1efa30140fc34f21e5b89959bb877', 'product_id' => 19794 ) );"
2847
}
2948
]
3049
}

.wordpress-org/blueprints/content.xml

Lines changed: 402 additions & 79 deletions
Large diffs are not rendered by default.

docs/README.md

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,91 @@
11
# Freemius for WordPress
22

3-
The Freemius for WordPress is a toolkit to help people sell WordPress products on their WordPress sites.
3+
The Freemius for WordPress is a toolkit to help people sell products on their WordPress sites.
44

5-
## [Freemius Checkout Button](./button.md)
5+
## General Idea
6+
7+
This plugin helps you quickly set up a sales page for your WordPress product that you sell via Freemius.
8+
9+
## How it works
10+
11+
The plugin uses the Freemius API to fetch the product data and display it in the block editor.
12+
13+
The plugin also allows you to add Freemius Checkout to any button of your WordPress content using the block editor.
14+
15+
## Requirements
16+
17+
- WordPress 6.7+
18+
- Freemius account
19+
- Freemius product
20+
21+
## Installation
22+
23+
1. Install the plugin via the WordPress admin panel.
24+
2. Activate the plugin.
25+
3. Go to the Freemius settings page (Settings => Freemius) and enter your Freemius Token.
26+
4. Go to the "Editor Settings" page and enter `product_id`, `public_key`.
27+
28+
## Checkout Button
29+
30+
The easiest way to enable a checkout button is to create a new page (or edit an existing one) and add a new button block to the content.
31+
32+
33+
https://github.com/user-attachments/assets/c07268f2-0dc1-439a-840c-7e52215016cb
34+
35+
36+
Enable the checkout for this button in the inspector panel.
37+
38+
You can instantly preview the button by clicking the "Preview" button in the inspector panel. Change the properties for this specific button with the settings below.
39+
40+
## Working with Scopes
41+
42+
The plugin allows you to create multiple scopes for your product. Each scope can have different pricing and checkout buttons.
43+
44+
A scope can be enabled on these blocks (or their children):
45+
46+
- Group Block
47+
- Columns Block
48+
- Column Block
49+
- Button Block
50+
51+
<img width="280" height="284" alt="enable_checkout_full" src="https://github.com/user-attachments/assets/52b2e108-f3f2-4fd2-8760-c730a8c48315" />
52+
53+
54+
55+
Each scope inherits the properties of the parent scope. The first scope in the hierarchy will inherit the properties of the "Editor Settings" page.
56+
57+
### Mapping
58+
59+
You can map certain fields from your plans (e.g., "title", "description", "price", etc.) to the content of the blocks.
60+
61+
The following blocks can "receive" data from the scope:
62+
63+
- Paragraph Block
64+
- HeadingBlock
65+
- Button Block
66+
67+
Currently, 5 fields are supported:
68+
69+
- Title
70+
- Description
71+
- Price
72+
- Licenses (1, 2, 3, Unlimited)
73+
- Billing Cycle (Monthly, Yearly, Lifetime)
74+
75+
You can see a purple outline around all blocks with a scope. The dotted outline indicates a mapped field:
76+
77+
<img width="1243" height="703" alt="pricing_with_scopes" src="https://github.com/user-attachments/assets/c84d5c2f-07c0-46df-8ac3-843f2961d493" />
78+
79+
### Scope Modifiers
80+
81+
Modifiers can be used to change the settings of the scope in which they are placed. They always change the scope of the next parent scope.
82+
83+
The scope is enabled by adding the "Freemius Scope" block to the content.
84+
<img width="2439" height="609" alt="modifiers" src="https://github.com/user-attachments/assets/2f9441a1-4fa4-4285-a5e7-8e1f025dfe50" />
85+
86+
You can click on the modifier directly in the editor to change the scope.
87+
88+
https://github.com/user-attachments/assets/6a25e2cb-c169-4d2d-898c-d6a48f90e0c6
689

7-
The Freemius Checkout Button allows you to add Freemius Checkout to any button of your WordPress content using the block editor.
890

9-
![Freemius Checkout](https://raw.githubusercontent.com/Freemius/freemius-wp-plugin/refs/heads/main/docs/assets/checkout.png)
1091

11-
Read more about the Freemius Checkout Button in the [Freemius Checkout Button](./button.md) documentation.

freemius.php

Lines changed: 46 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Description: Freemius Toolkit
88
* Requires at least: 6.6
99
* Requires PHP: 7.4
10-
* Version: 0.2.2
10+
* Version: 0.3.0
1111
* Author: Freemius
1212
* Author URI: https://freemius.com
1313
* License: MIT
@@ -17,164 +17,63 @@
1717
exit; // Exit if accessed directly.
1818
}
1919

20-
require_once __DIR__ . '/vendor/autoload.php';
21-
22-
\add_action( 'enqueue_block_assets', __NAMESPACE__ . '\block_script_styles', 1 );
23-
function block_script_styles() {
24-
25-
if ( ! is_admin() ) {
26-
return;
27-
}
28-
29-
$plugin_dir = \plugin_dir_path( __FILE__ );
30-
$plugin_url = \plugin_dir_url( __FILE__ );
31-
32-
// load from assets.php
33-
$freemius_dependencies = include $plugin_dir . 'build/freemius-button/editor.asset.php';
34-
35-
\wp_enqueue_code_editor( array( 'type' => 'application/javascript' ) );
36-
37-
// Freemius Button Block
38-
\wp_enqueue_script( 'freemius-button', $plugin_url . 'build/freemius-button/editor.js', $freemius_dependencies['dependencies'], $freemius_dependencies['version'], true );
39-
\wp_enqueue_style( 'freemius-button', $plugin_url . 'build/freemius-button/editor.css', array(), $freemius_dependencies['version'] );
40-
41-
// TODO: load this via API in the editor.js
42-
\wp_add_inline_script( 'freemius-button', 'const freemius_button_schema = ' . wp_json_encode( get_schema() ) . '', true );
43-
}
44-
45-
46-
47-
\add_filter( 'render_block_core/button', __NAMESPACE__ . '\render_button', 10, 3 );
48-
function render_button( $block_content, $block, $instance ) {
49-
50-
if ( ! isset( $block['attrs'] ) ) {
51-
return $block_content;
52-
}
53-
if ( ! isset( $block['attrs']['freemius_enabled'] ) || $block['attrs']['freemius_enabled'] === false ) {
54-
return $block_content;
55-
}
56-
57-
// merge the data from the site, the page and the block
58-
$site_data = \get_option( 'freemius_button', array() );
59-
$page_data = \get_post_meta( get_the_ID(), 'freemius_button', true );
60-
$plugin_data = isset( $block['attrs']['freemius'] ) ? $block['attrs']['freemius'] : array();
61-
62-
$data = array_merge( (array) $site_data, (array) $page_data, (array) $plugin_data );
63-
64-
/**
65-
* Filter the data that will be passed to the Freemius checkout.
66-
*
67-
* @param array $data The data that will be passed to the Freemius checkout.
68-
*/
69-
$data = \apply_filters( 'freemius_button_data', $data );
70-
71-
$extra = '';
72-
$extra .= '<script type="application/json" class="freemius-button-data">' . wp_json_encode( $data ) . '</script>';
73-
74-
$plugin_dir = \plugin_dir_path( __FILE__ );
75-
$plugin_url = \plugin_dir_url( __FILE__ );
76-
77-
\wp_enqueue_script( 'freemius-button-checkout', 'https://checkout.freemius.com/js/v1/', array(), 'v1', true );
78-
79-
// load from assets.php
80-
$dependecied = include $plugin_dir . 'build/freemius-button/view.asset.php';
81-
\wp_enqueue_script( 'freemius-button-frontend', $plugin_url . 'build/freemius-button/view.js', $dependecied['dependencies'], $dependecied['version'], true );
82-
\wp_enqueue_style( 'freemius-button-frontend', $plugin_url . 'build/freemius-button/view.css', array(), $dependecied['version'] );
20+
define( 'FREEMIUS_PLUGIN_DIR', __DIR__ );
21+
define( 'FREEMIUS_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
8322

84-
return $extra . $block_content;
85-
}
86-
87-
88-
// register custom post meta to store the button data
89-
\add_action( 'init', __NAMESPACE__ . '\register_post_meta' );
90-
function register_post_meta() {
91-
92-
\register_post_meta(
93-
'', // registered for all post types
94-
'freemius_button',
95-
array(
96-
'single' => true,
97-
'type' => 'object',
98-
'sanitize_callback' => __NAMESPACE__ . '\sanitize_schema',
99-
'default' => array(),
100-
'show_in_rest' => array(
101-
'schema' => array(
102-
'type' => 'object',
103-
'properties' => get_schema(),
104-
'additionalProperties' => false,
105-
106-
),
107-
108-
),
109-
)
110-
);
111-
}
112-
113-
// register a setting to store the button data
114-
\add_action( 'init', __NAMESPACE__ . '\register_my_setting' );
115-
\add_action( 'rest_api_init', __NAMESPACE__ . '\register_my_setting' );
116-
117-
118-
function register_my_setting() {
23+
require_once __DIR__ . '/vendor/autoload.php';
11924

120-
\register_setting(
121-
'options',
122-
'freemius_button',
123-
array(
124-
'single' => true,
125-
'label' => 'Freemius Button',
126-
'type' => 'object',
127-
'sanitize_callback' => __NAMESPACE__ . '\sanitize_schema',
128-
'show_in_rest' => array(
129-
'schema' => array(
130-
'type' => 'object',
131-
'properties' => get_schema(),
132-
'additionalProperties' => false,
25+
// Autoload classes
26+
spl_autoload_register(
27+
function ( $class ) {
28+
// Project-specific namespace prefix
29+
$prefix = 'Freemius\\';
13330

134-
),
31+
// Base directory for the namespace prefix
32+
$base_dir = FREEMIUS_PLUGIN_DIR . '/includes/';
13533

136-
),
137-
)
138-
);
139-
}
34+
// Check if the class uses the namespace prefix
35+
$len = strlen( $prefix );
36+
if ( strncmp( $prefix, $class, $len ) !== 0 ) {
37+
return;
38+
}
14039

40+
// Get the relative class name
41+
$relative_class = substr( $class, $len );
14142

142-
function sanitize_schema( $settings ) {
43+
// Replace namespace separators with directory separators
44+
$file = $base_dir . 'class-freemius-' . strtolower( str_replace( '_', '-', $relative_class ) ) . '.php';
14345

144-
foreach ( $settings as $key => $value ) {
145-
if ( $settings[ $key ] === '' ) {
146-
unset( $settings[ $key ] );
46+
// If the file exists, require it
47+
if ( file_exists( $file ) ) {
48+
require $file;
14749
}
14850
}
149-
150-
return $settings;
51+
);
52+
53+
function init() {
54+
Button::get_instance();
55+
Scope::get_instance();
56+
Settings::get_instance();
57+
Api::get_instance();
58+
Blocks::get_instance();
15159
}
60+
\add_action( 'plugins_loaded', __NAMESPACE__ . '\\init' );
15261

153-
function get_schema() {
154-
155-
$plugin_dir = \plugin_dir_path( __FILE__ );
156-
$schema = include $plugin_dir . 'includes/schema.php';
15762

158-
return $schema;
63+
/**
64+
* Plugin activation hook
65+
*
66+
* @return void
67+
*/
68+
function activate() {
15969
}
70+
register_activation_hook( __FILE__, __NAMESPACE__ . '\\activate' );
16071

161-
\add_filter( 'render_block_core/group', __NAMESPACE__ . '\render_group', 10, 3 );
162-
function render_group( $block_content, $block, $instance ) {
163-
if ( ! isset( $block['attrs']['testEnabled'] ) || ! $block['attrs']['testEnabled'] ) {
164-
return $block_content;
165-
}
166-
167-
$test_text = isset( $block['attrs']['testText'] ) ? $block['attrs']['testText'] : '';
168-
169-
// Add data attributes for styling
170-
$block_content = str_replace(
171-
'class="wp-block-group',
172-
sprintf(
173-
'class="wp-block-group" data-test-enabled="true" data-test-text="%s"',
174-
esc_attr( $test_text )
175-
),
176-
$block_content
177-
);
178-
179-
return $block_content;
72+
/**
73+
* Plugin deactivation hook
74+
*
75+
* @return void
76+
*/
77+
function deactivate() {
18078
}
79+
register_deactivation_hook( __FILE__, __NAMESPACE__ . '\\deactivate' );

0 commit comments

Comments
 (0)