395 lines
11 KiB
PHP
395 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* Helper functions to work with licenses, permissions and capabilities.
|
|
*
|
|
* @since 1.8.0
|
|
*/
|
|
|
|
/**
|
|
* Determine if the plugin/addon installations are allowed.
|
|
*
|
|
* @since 1.6.2.3
|
|
*
|
|
* @param string $type Should be `plugin` or `addon`.
|
|
*
|
|
* @return bool
|
|
*/
|
|
function wpforms_can_install( $type ): bool {
|
|
|
|
return wpforms_can_do( 'install', $type );
|
|
}
|
|
|
|
/**
|
|
* Determine if the plugin/addon activations are allowed.
|
|
*
|
|
* @since 1.7.3
|
|
*
|
|
* @param string $type Should be `plugin` or `addon`.
|
|
*
|
|
* @return bool
|
|
*/
|
|
function wpforms_can_activate( $type ): bool {
|
|
|
|
return wpforms_can_do( 'activate', $type );
|
|
}
|
|
|
|
/**
|
|
* Determine if the plugin/addon installations/activations are allowed.
|
|
*
|
|
* @since 1.7.3
|
|
*
|
|
* @internal Use wpforms_can_activate() or wpforms_can_install() instead.
|
|
*
|
|
* @param string $what Should be 'activate' or 'install'.
|
|
* @param string $type Should be `plugin` or `addon`.
|
|
*
|
|
* @return bool
|
|
*/
|
|
function wpforms_can_do( $what, $type ): bool {
|
|
|
|
if ( ! in_array( $what, [ 'install', 'activate' ], true ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! in_array( $type, [ 'plugin', 'addon' ], true ) ) {
|
|
return false;
|
|
}
|
|
|
|
$capability = $what . '_plugins';
|
|
|
|
if ( ! current_user_can( $capability ) ) {
|
|
return false;
|
|
}
|
|
|
|
// Determine whether file modifications are allowed and it is activation permissions checking.
|
|
if ( $what === 'install' && ! wp_is_file_mod_allowed( 'wpforms_can_install' ) ) {
|
|
return false;
|
|
}
|
|
|
|
// All plugin checks are done.
|
|
if ( $type === 'plugin' ) {
|
|
return true;
|
|
}
|
|
|
|
// Addons require additional license checks.
|
|
$license = get_option( 'wpforms_license', [] );
|
|
|
|
// Allow addons installation if the license is not expired, enabled and valid.
|
|
return empty( $license['is_expired'] ) && empty( $license['is_disabled'] ) && empty( $license['is_invalid'] );
|
|
}
|
|
|
|
/**
|
|
* Get the current installation license type (always lowercase).
|
|
*
|
|
* @since 1.5.6
|
|
*
|
|
* @return string|false
|
|
*/
|
|
function wpforms_get_license_type() {
|
|
|
|
$type = wpforms_setting( 'type', '', 'wpforms_license' );
|
|
|
|
if ( empty( $type ) || ! wpforms_is_pro() ) {
|
|
return false;
|
|
}
|
|
|
|
return strtolower( $type );
|
|
}
|
|
|
|
/**
|
|
* Get the current installation license key.
|
|
*
|
|
* @since 1.6.2.3
|
|
* @since 1.8.0 The WPFORMS_LICENSE_KEY constant has higher priority than the DB option.
|
|
*
|
|
* @return string
|
|
*/
|
|
function wpforms_get_license_key(): string {
|
|
|
|
// Allow wp-config constant to pass key.
|
|
if ( defined( 'WPFORMS_LICENSE_KEY' ) && WPFORMS_LICENSE_KEY ) {
|
|
return WPFORMS_LICENSE_KEY;
|
|
}
|
|
|
|
return (string) wpforms_setting( 'key', '', 'wpforms_license' );
|
|
}
|
|
|
|
/**
|
|
* Get when WPForms was first installed.
|
|
*
|
|
* @since 1.6.0
|
|
*
|
|
* @param string $type Specific installation type to check for.
|
|
*
|
|
* @return int|false Unix timestamp. False on failure.
|
|
*/
|
|
function wpforms_get_activated_timestamp( $type = '' ) {
|
|
|
|
$activated = (array) get_option( 'wpforms_activated', [] );
|
|
|
|
if ( empty( $activated ) ) {
|
|
return false;
|
|
}
|
|
|
|
// When a passed installation type is empty, then get it from a DB.
|
|
// If it is installed/activated first, it is saved first.
|
|
$type = empty( $type ) ? (string) array_keys( $activated )[0] : $type;
|
|
|
|
if ( ! empty( $activated[ $type ] ) ) {
|
|
return absint( $activated[ $type ] );
|
|
}
|
|
|
|
// Fallback.
|
|
$types = array_diff( [ 'lite', 'pro' ], [ $type ] );
|
|
|
|
foreach ( $types as $_type ) {
|
|
if ( ! empty( $activated[ $_type ] ) ) {
|
|
return absint( $activated[ $_type ] );
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a timestamp when WPForms was upgraded.
|
|
*
|
|
* @since 1.7.5
|
|
*
|
|
* @param string $version Specific plugin version to check for.
|
|
*
|
|
* @return int|false Unix timestamp or migration status. False on failure.
|
|
* Available migration statuses:
|
|
* -2 if migration is failed;
|
|
* -1 if migration is started (in progress);
|
|
* 0 if migration is completed, but no luck to set a timestamp.
|
|
*/
|
|
function wpforms_get_upgraded_timestamp( $version ) {
|
|
|
|
$option_name = wpforms()->is_pro() ? 'wpforms_versions' : 'wpforms_versions_lite';
|
|
$upgrades = (array) get_option( $option_name, [] );
|
|
|
|
if ( ! isset( $upgrades[ $version ] ) ) {
|
|
return false;
|
|
}
|
|
|
|
return (int) $upgrades[ $version ];
|
|
}
|
|
|
|
/**
|
|
* Get the default capability to manage everything for WPForms.
|
|
*
|
|
* @since 1.4.4
|
|
*
|
|
* @return string
|
|
*/
|
|
function wpforms_get_capability_manage_options(): string {
|
|
|
|
/**
|
|
* Filters the default capability to manage everything for WPForms.
|
|
* By default, it is 'manage_options'.
|
|
*
|
|
* @since 1.4.4
|
|
*
|
|
* @param string $capability Default capability to manage everything for WPForms.
|
|
*/
|
|
return (string) apply_filters( 'wpforms_manage_cap', 'manage_options' );
|
|
}
|
|
|
|
/**
|
|
* Check WPForms permissions for currently logged-in user.
|
|
* Both short (e.g. 'view_own_forms') or long (e.g. 'wpforms_view_own_forms') capability names can be used.
|
|
* Only WPForms capabilities get processed.
|
|
*
|
|
* @since 1.4.4
|
|
*
|
|
* @param array|string $caps Capability name(s).
|
|
* @param int|mixed $id ID of the specific object to check against if capability is a "meta" cap.
|
|
* "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc.,
|
|
* are capabilities used by map_meta_cap() to map to other "primitive" capabilities,
|
|
* e.g. 'edit_posts', 'edit_others_posts', etc.
|
|
* Accessed via func_get_args() and passed to WP_User::has_cap(), then map_meta_cap().
|
|
*
|
|
* @return bool
|
|
*/
|
|
function wpforms_current_user_can( $caps = [], $id = 0 ): bool {
|
|
|
|
static $results;
|
|
|
|
$id = (int) $id;
|
|
$caps_str = is_array( $caps ) ? implode( ' ', $caps ) : (string) $caps;
|
|
$hash = md5( $caps_str . $id );
|
|
|
|
// Return a cached result.
|
|
if ( isset( $results[ $hash ] ) ) {
|
|
return $results[ $hash ];
|
|
}
|
|
|
|
$access = wpforms()->obj( 'access' );
|
|
|
|
if ( ! $access || ! method_exists( $access, 'current_user_can' ) ) {
|
|
return false;
|
|
}
|
|
|
|
$user_can = $access->current_user_can( $caps, $id );
|
|
|
|
/**
|
|
* Filters the result of the WPForms permissions check for the currently logged-in user.
|
|
*
|
|
* @since 1.4.4
|
|
*
|
|
* @param bool $user_can Whether the current user has the capability.
|
|
* @param array|string $caps Capability name(s).
|
|
* @param int $id ID of the specific object to check against if capability is a "meta" cap.
|
|
*/
|
|
$results[ $hash ] = apply_filters( 'wpforms_current_user_can', $user_can, $caps, $id );
|
|
|
|
return $results[ $hash ];
|
|
}
|
|
|
|
/**
|
|
* Search for posts editable by the user.
|
|
*
|
|
* @since 1.7.9
|
|
*
|
|
* @param string $search_term Optional search term. Default ''.
|
|
* @param array $args Args {
|
|
* Optional. An array of arguments.
|
|
*
|
|
* @type string $post_type Post type to search for.
|
|
* @type string[] $post_status Post status to search for.
|
|
* @type int $count Number of results to return. Default 20.
|
|
* }
|
|
*
|
|
* @return array
|
|
* @noinspection PhpTernaryExpressionCanBeReducedToShortVersionInspection
|
|
* @noinspection ElvisOperatorCanBeUsedInspection
|
|
*/
|
|
function wpforms_search_posts( $search_term = '', $args = [] ): array {
|
|
|
|
global $wpdb;
|
|
|
|
$default_args = [
|
|
'post_type' => 'page',
|
|
'post_status' => [ 'publish' ],
|
|
'count' => 20,
|
|
];
|
|
$args = wp_parse_args( $args, $default_args );
|
|
|
|
// @todo: add trash access capabilities to MySQL.
|
|
// See edit_post/edit_page case in map_meta_cap().
|
|
$args['post_status'] = array_diff( $args['post_status'], [ 'trash' ] );
|
|
|
|
$user = wp_get_current_user();
|
|
$user_id = $user->ID ?? 0;
|
|
$post_type = get_post_type_object( $args['post_type'] );
|
|
|
|
if ( ! $user || ! $user_id || ! $post_type || $args['count'] <= 0 ) {
|
|
return [];
|
|
}
|
|
|
|
$last_changed = wp_cache_get_last_changed( 'posts' );
|
|
$key = __FUNCTION__ . ":$search_term:$last_changed";
|
|
$cache_posts = wp_cache_get( $key, '', false, $found );
|
|
|
|
if ( $found ) {
|
|
return (array) $cache_posts;
|
|
}
|
|
|
|
$post_title_where = $search_term ? $wpdb->prepare(
|
|
'post_title LIKE %s AND',
|
|
'%' . $wpdb->esc_like( $search_term ) . '%'
|
|
) :
|
|
'';
|
|
|
|
$post_statuses = array_intersect( array_keys( get_post_statuses() ), $args['post_status'] );
|
|
$post_statuses = wpforms_wpdb_prepare_in( $post_statuses );
|
|
$policy_id = (int) get_option( 'wp_page_for_privacy_policy' );
|
|
$can_delete_published_posts = (int) $user->has_cap( $post_type->cap->delete_published_posts );
|
|
$can_delete_posts = (int) $user->has_cap( $post_type->cap->delete_posts );
|
|
$can_delete_others_posts = (int) $user->has_cap( $post_type->cap->delete_others_posts );
|
|
$can_delete_private_posts = (int) $user->has_cap( $post_type->cap->delete_private_posts );
|
|
$can_edit_policy = (int) $user->has_cap( map_meta_cap( 'manage_privacy_options', $user_id )[0] );
|
|
|
|
// For the case when the user is post author.
|
|
$capability_author_where = "post_author = $user_id AND
|
|
( ( post_status IN ( 'publish', 'future' ) AND $can_delete_published_posts ) OR
|
|
( ( post_status NOT IN ( 'publish', 'future', 'trash' ) ) AND $can_delete_posts )
|
|
)";
|
|
|
|
// For the case when accessing someone other's post.
|
|
$capability_other_where = "post_author != $user_id AND
|
|
$can_delete_others_posts AND
|
|
( ( post_status IN ( 'publish', 'future' ) AND $can_delete_published_posts ) OR
|
|
( ( post_status IN ( 'private' ) ) AND $can_delete_private_posts )
|
|
)";
|
|
|
|
// For privacy policy page.
|
|
$capability_policy_where = "ID = $policy_id AND $can_edit_policy";
|
|
|
|
$capability_where = '( ' .
|
|
'(' . $capability_author_where . ') OR ' .
|
|
'(' . $capability_other_where . ') OR ' .
|
|
'(' . $capability_policy_where . ')' .
|
|
' )';
|
|
|
|
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
|
$posts = $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
"SELECT ID, post_title, post_author
|
|
FROM $wpdb->posts
|
|
WHERE $post_title_where
|
|
post_type = %s AND
|
|
post_status IN ( $post_statuses ) AND
|
|
$capability_where
|
|
ORDER BY post_title LIMIT %d",
|
|
$args['post_type'],
|
|
absint( $args['count'] )
|
|
)
|
|
);
|
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
|
|
|
$posts = $posts ? $posts : [];
|
|
$posts = array_map(
|
|
static function ( $post ) {
|
|
$post->post_title = wpforms_get_post_title( $post );
|
|
|
|
unset( $post->post_author );
|
|
|
|
return $post;
|
|
},
|
|
$posts
|
|
);
|
|
|
|
wp_cache_set( $key, $posts );
|
|
|
|
return $posts;
|
|
}
|
|
|
|
/**
|
|
* Search pages by search term and return an array containing
|
|
* `value` and `label` which is the post ID and post title respectively.
|
|
*
|
|
* @since 1.7.9
|
|
*
|
|
* @param string $search_term The search term.
|
|
* @param array $args Optional. An array of arguments.
|
|
*
|
|
* @return array
|
|
*/
|
|
function wpforms_search_pages_for_dropdown( $search_term, $args = [] ): array {
|
|
|
|
$search_results = wpforms_search_posts( $search_term, $args );
|
|
$result_pages = [];
|
|
|
|
// Prepare for ChoicesJS render.
|
|
foreach ( $search_results as $search_result ) {
|
|
$result_pages[] = [
|
|
'value' => absint( $search_result->ID ),
|
|
'label' => esc_html( $search_result->post_title ),
|
|
];
|
|
}
|
|
|
|
return $result_pages;
|
|
}
|