define_constants();
$this->includes();
$this->container = Container::get_instance();
$this->init_framework();
if ( UpStream_Debug::is_enabled() ) {
UpStream_Debug::init();
}
$this->init_hooks();
do_action( 'upstream_loaded' );
}
/**
* Hook into actions and filters.
*
* @since 1.0.0
*/
private function init_hooks() {
add_action( 'init', array( $this, 'init' ) );
add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
add_filter( 'plugin_action_links_upstream/upstream.php', array( $this, 'handle_action_links' ) );
add_filter( 'http_request_host_is_external', array( 'UpStream', 'allow_external_update_host' ), 10, 3 );
add_filter( 'quicktags_settings', 'upstream_tinymce_quicktags_settings' );
add_filter( 'tiny_mce_before_init', 'upstream_tinymce_before_init_setup_toolbar' );
add_filter( 'tiny_mce_before_init', 'upstream_tinymce_before_init' );
add_filter( 'teeny_mce_before_init', 'upstream_tinymce_before_init_setup_toolbar' );
add_filter( 'comments_clauses', array( $this, 'filter_comments_on_dashboard' ), 10, 2 );
add_filter( 'views_dashboard', array( 'UpStream_Admin', 'comment_status_links' ), 10, 1 );
add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
if ( is_admin() ) {
add_action( 'admin_init', array( $this->container['reviews'], 'init' ) );
}
global $pagenow;
if ( 'plugins.php' === $pagenow ) {
add_action(
'in_plugin_update_message-' . UPSTREAM_PLUGIN_BASENAME,
array( $this, 'render_additional_update_info' ),
20,
2
);
}
}
/**
* Initialize the Alledia Framework.
*/
private function init_framework() {
$this->container['framework']->init();
}
/**
* Prevent a Client User from accessing any page other than the profile.
*
* @since 1.11.0
*
* @global $pagenow
*/
public function limit_client_users_admin_access() {
global $pagenow;
$profile_age = 'profile.php';
if ( $pagenow !== $profile_age && 'edit.php' !== $pagenow && ! wp_doing_ajax() ) {
wp_safe_redirect( admin_url( $profile_age ) );
exit();
}
}
/**
* Make sure Client Users can only see the Profile menu item.
*
* @since 1.11.0
*
* @global $menu
*/
public function limit_client_users_menu() {
global $menu;
foreach ( $menu as $menu_index => $menu_data ) {
$menu_file = isset( $menu_data[2] ) ? $menu_data[2] : null;
if ( null !== $menu_file ) {
if ( 'profile.php' === $menu_file || 'edit.php?post_type=project' === $menu_file ) {
continue;
}
remove_menu_page( $menu_file );
}
}
}
/**
* Hide some toolbar items from Client Users.
*
* @param \WP_Admin_Bar $wp_admin_bar WordPress admin bar.
*
* @since 1.11.0
*/
public function limit_client_users_toolbar_items( $wp_admin_bar ) {
$user = wp_get_current_user();
$user_roles = (array) $user->roles;
if ( count( array_intersect( $user_roles, array( 'administrator', 'upstream_manager' ) ) ) === 0
&& in_array( 'upstream_client_user', $user_roles, true )
) {
$menu_items = array( 'about', 'comments', 'new-content' );
if ( ! is_admin() ) {
$menu_items = array_merge( $menu_items, array( 'dashboard', 'edit' ) );
}
foreach ( $menu_items as $menu_item ) {
$wp_admin_bar->remove_menu( $menu_item );
}
}
}
/**
* Get container.
*
* @return Container
*/
public function get_container() {
return $this->container;
}
/**
* Define Constants.
*
* @since 1.0.0
*/
private function define_constants() {
$upload_dir = wp_upload_dir();
$this->define( 'UPSTREAM_PLUGIN_DIR', plugin_dir_path( UPSTREAM_PLUGIN_FILE ) );
$this->define( 'UPSTREAM_PLUGIN_URL', plugin_dir_url( UPSTREAM_PLUGIN_FILE ) );
$this->define( 'UPSTREAM_PLUGIN_BASENAME', plugin_basename( UPSTREAM_PLUGIN_FILE ) );
$this->define( 'UPSTREAM_PLUGIN_RELATIVE_PATH', 'upstream' );
include_once __DIR__ . '/includes.php';
}
/**
* Define constant if not already set.
*
* @param string $name Definition name.
* @param string|bool $value Definition value.
*
* @since 1.0.0
*/
private function define( $name, $value ) {
if ( ! defined( $name ) ) {
define( $name, $value );
}
}
/**
* What type of request is this?
* string $type frontend or admin.
*
* @param string $type Request type.
* @return bool
* @since 1.0.0
*/
private function is_request( $type ) {
switch ( $type ) {
case 'admin':
return is_admin();
case 'frontend':
return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' );
}
}
/**
* Include required core files used in admin and on the frontend.
*
* @since 1.0.0
*/
public function includes() {
if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
require_once __DIR__ . '/vendor/autoload.php';
}
include_once __DIR__ . '/includes/class-exception.php';
include_once __DIR__ . '/includes/trait-up-singleton.php';
include_once __DIR__ . '/includes/trait-up-post-metadata.php';
include_once __DIR__ . '/includes/class-struct.php';
include_once __DIR__ . '/includes/class-upstream-debug.php';
include_once __DIR__ . '/includes/class-container.php';
include_once __DIR__ . '/includes/up-install.php';
include_once __DIR__ . '/includes/class-upstream-autoloader.php';
include_once __DIR__ . '/includes/class-upstream-roles.php';
include_once __DIR__ . '/includes/class-upstream-counts.php';
include_once __DIR__ . '/includes/class-upstream-counter.php';
include_once __DIR__ . '/includes/class-upstream-project-activity.php';
include_once __DIR__ . '/includes/up-permalinks.php';
include_once __DIR__ . '/includes/up-general-functions.php';
include_once __DIR__ . '/includes/up-post-types.php';
include_once __DIR__ . '/includes/up-labels.php';
include_once __DIR__ . '/includes/class-milestones.php';
include_once __DIR__ . '/includes/class-milestone.php';
include_once __DIR__ . '/includes/class-factory.php';
include_once __DIR__ . '/includes/up-install.php';
include_once __DIR__ . '/includes/up-filesystem.php';
include_once __DIR__ . '/includes/up-register-nonce-fields.php';
include_once __DIR__ . '/includes/up-wcs-helper.php';
include_once __DIR__ . '/includes/class-license-checker.php';
include_once __DIR__ . '/includes/up-cron-license-checker.php';
$request = wp_unslash( $_REQUEST );
if ( $this->is_request( 'admin' ) ) {
global $pagenow;
$is_multisite = (bool) is_multisite();
$load_cmb2 = false;
$server = wp_unslash( $_SERVER );
if ( $is_multisite ) {
$current_page = isset( $_SERVER['PHP_SELF'] ) ? preg_replace(
'/^\/wp-admin\//i',
'',
sanitize_text_field( $server['PHP_SELF'] )
) : '';
} else {
$current_page = (string) $pagenow;
}
if ( in_array( $current_page, array( 'post.php', 'post-new.php' ), true ) ) {
$post_type = isset( $request['post_type'] ) ? sanitize_text_field( $request['post_type'] ) : null;
if ( empty( $post_type ) ) {
$project_id = isset( $request['post'] ) ? absint( $request['post'] ) : 0;
$post_type = get_post_type( $project_id );
}
if ( ! empty( $post_type ) ) {
$post_types_using_cmb2 = apply_filters( 'upstream:post_types_using_cmb2', array( 'project', 'client' ) );
$load_cmb2 = in_array( $post_type, $post_types_using_cmb2, true );
}
} elseif (
'admin.php' === $current_page
&& isset( $request['page'] )
&& preg_match( '/^upstream_/i', sanitize_text_field( $request['page'] ) )
) {
$load_cmb2 = true;
}
if ( $load_cmb2 ) {
include_once __DIR__ . '/includes/libraries/cmb2/init.php';
include_once __DIR__ . '/includes/libraries/cmb2-grid/Cmb2GridPlugin.php';
}
include_once __DIR__ . '/includes/admin/class-upstream-admin.php';
include_once __DIR__ . '/includes/admin/class-upstream-admin-tasks-page.php';
include_once __DIR__ . '/includes/admin/class-upstream-admin-bugs-page.php';
include_once __DIR__ . '/includes/admin/class-upstream-admin-reviews.php';
}
if ( $this->is_request( 'frontend' ) ) {
include_once __DIR__ . '/includes/frontend/class-upstream-template-loader.php';
include_once __DIR__ . '/includes/frontend/class-upstream-login.php';
include_once __DIR__ . '/includes/frontend/class-upstream-style-output.php';
include_once __DIR__ . '/includes/frontend/up-enqueues.php';
include_once __DIR__ . '/includes/frontend/up-template-functions.php';
include_once __DIR__ . '/includes/frontend/up-table-functions.php';
include_once __DIR__ . '/includes/frontend/class-upstream-view.php';
include_once __DIR__ . '/includes/frontend/class-upstream-ajax.php';
}
include_once __DIR__ . '/includes/up-project-functions.php';
include_once __DIR__ . '/includes/up-client-functions.php';
include_once __DIR__ . '/includes/up-permissions-functions.php';
include_once __DIR__ . '/includes/class-comments-migration.php';
include_once __DIR__ . '/includes/class-comments.php';
include_once __DIR__ . '/includes/class-comment.php';
}
/**
* Init UpStream when WordPress Initialises.
*/
public function init() {
UpStream\Milestones::instantiate();
do_action( 'before_upstream_init' );
$this->project = new UpStream_Project();
$this->project_activity = new UpStream_Project_Activity();
if ( version_compare( PHP_VERSION, '5.5', '<' ) ) {
require_once UPSTREAM_PLUGIN_DIR . 'includes/libraries/password_compat-1.0.4/lib/password.php';
}
\UpStream\Migrations\Comments_Migration::run();
$user = wp_get_current_user();
$user_roles = (array) $user->roles;
if (
count( array_intersect( $user_roles, array( 'administrator', 'upstream_manager' ) ) ) === 0
&& in_array( 'upstream_client_user', $user_roles, true )
) {
add_filter( 'admin_init', array( $this, 'limit_client_users_admin_access' ) );
add_filter( 'admin_head', array( $this, 'limit_client_users_menu' ) );
add_action( 'admin_bar_menu', array( $this, 'limit_client_users_toolbar_items' ), 999 );
}
$edit_other_projects_permission_were_removed = (bool) get_option( 'upstream:role_upstream_users:drop_edit_others_projects' );
if ( ! $edit_other_projects_permission_were_removed ) {
$role = get_role( 'upstream_user' );
if ( $role ) {
$role->remove_cap( 'edit_others_projects' );
}
unset( $role );
update_option( 'upstream:role_upstream_users:drop_edit_others_projects', 1 );
}
UpStream_Options_Projects::create_projects_statuses_ids();
UpStream_Options_Tasks::create_tasks_statuses_ids();
UpStream_Options_Bugs::create_bugs_statuses_ids();
Comments::instantiate();
if ( $this->is_request( 'frontend' ) ) {
UpStream_Ajax::instantiate();
}
do_action( 'upstream_init' );
}
/**
* Load Localisation files.
*/
public function load_plugin_textdomain() {
load_plugin_textdomain( 'upstream', false, UPSTREAM_PLUGIN_RELATIVE_PATH . '/languages/' );
}
/**
* Show row meta on the plugin screen.
*
* @param mixed $links Plugin Row Meta.
* @param mixed $file Plugin Base file.
*
* @return array
*/
public function plugin_row_meta( $links, $file ) {
if ( UPSTREAM_PLUGIN_BASENAME === $file ) {
$row_meta = array(
'docs' => sprintf(
'%s',
esc_url( 'http://upstreamplugin.com/documentation' ),
esc_attr__( 'View Documentation', 'upstream' ),
esc_html__( 'Docs', 'upstream' )
),
'quick-start' => sprintf(
'%s',
esc_url( 'http://upstreamplugin.com/quick-start-guide' ),
esc_attr__( 'View Quick Start Guide', 'upstream' ),
esc_html__( 'Quick Start Guide', 'upstream' )
),
);
return array_merge( $links, $row_meta );
}
return (array) $links;
}
/**
* Callback called to setup the links to display on the plugins page, besides active/deactivate links.
*
* @param array $links The list of links to be displayed.
*
* @return array
* @since 1.11.1
* @static
*/
public static function handle_action_links( $links ) {
$links['settings'] = sprintf(
'%3$s',
esc_url( admin_url( 'admin.php?page=upstream_general' ) ),
esc_attr__( 'Open Settings Page', 'upstream' ),
esc_html__( 'Settings', 'upstream' )
);
return $links;
}
/**
* Ensures the plugins update API's host is whitelisted to WordPress external requests.
*
* @param boolean $is_allowed Is allowed or not.
* @param string $host Host.
* @param string $url Url.
*
* @return boolean
* @since 1.11.1
* @static
*/
public static function allow_external_update_host( $is_allowed, $host, $url ) {
if ( 'upstreamplugin.com' === $host ) {
return true;
}
return $is_allowed;
}
/**
* Render additional update info if needed.
*
* @param array $plugin_data Plugin metadata.
* @param object $response Metadata about the available plugin update.
*
* @since 1.12.5
* @static
*
* @see https://developer.wordpress.org/reference/hooks/in_plugin_update_message-file
*/
public static function render_additional_update_info( $plugin_data, $response ) {
$update_notice_title_html = sprintf(
'%s',
esc_html__( 'Update notice:', 'upstream' )
);
if ( version_compare( UPSTREAM_VERSION, '1.12.5', '<' ) ) {
printf(
esc_html( $update_notice_title_html ) .
// translators: '%1$s: plugin version, %2$s: capability name, %3$s: UpStream User role'.
esc_html__(
'Starting from %1$s %2$s capability was removed from %3$s users role.',
'upstream'
),
'v1.12.5',
'edit_others_projects',
esc_html__( 'UpStream User', 'upstream' )
);
}
}
/**
* Make sure Recent Comments section on admin Dashboard display only comments
* current user is allowed to see from projects he's allowed to access.
*
* @param array $query_args Query clauses.
* @param WP_Comment_Query $query Current query instance.
*
* @return array $queryArgs
* @global $pagenow, $wpdb
*
* @since 1.13.0
* @static
*/
public static function filter_comments_on_dashboard( $query_args, $query ) {
global $pagenow;
if ( is_admin() && 'index.php' === $pagenow && ! upstream_is_user_either_manager_or_admin() ) {
global $wpdb;
$query_args['join'] = 'LEFT JOIN ' . $wpdb->prefix . 'posts AS post ON post.ID = ' . $wpdb->prefix . 'comments.comment_post_ID';
$user = wp_get_current_user();
if ( in_array( 'upstream_user', $user->roles, true ) || in_array( 'upstream_client_user', $user->roles, true ) ) {
$projects = (array) upstream_get_users_projects( $user );
if ( count( $projects ) === 0 ) {
$query_args['where'] = '(post.ID = -1)';
} else {
$query_args['where'] = "(post.post_type = 'project' AND post.ID IN (" . implode( ', ', array_keys( $projects ) ) . '))';
$user_can_moderate_comments = user_can( $user, 'moderate_comments' );
if ( ! $user_can_moderate_comments ) {
$query_args['where'] .= " AND ( comment_approved = '1' )";
} else {
$query_args['where'] .= " AND ( comment_approved = '1' OR comment_approved = '0' )";
}
}
} else {
$query_args['where'] .= " AND (post.post_type != 'project')";
}
}
return $query_args;
}
}
endif;
/**
* Main instance of UpStream.
*
* Returns the main instance of UpStream to prevent the need to use globals.
*
* @return UpStream
* @since 1.0.0
*/
function upstream() {
return UpStream::instance();
}
upstream();
do_action( 'upstream_run' );