You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
7.2 KiB
PHTML
272 lines
7.2 KiB
PHTML
7 months ago
|
<?php
|
||
|
/**
|
||
|
* Admin class.
|
||
|
*
|
||
|
* Responsible for WordPress admin integration.
|
||
|
*
|
||
|
* @link https://github.com/googleforcreators/web-stories-wp
|
||
|
*
|
||
|
* @copyright 2020 Google LLC
|
||
|
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Copyright 2020 Google LLC
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
declare(strict_types = 1);
|
||
|
|
||
|
namespace Google\Web_Stories\Admin;
|
||
|
|
||
|
use Google\Web_Stories\Context;
|
||
|
use Google\Web_Stories\Model\Story;
|
||
|
use Google\Web_Stories\Renderer\Story\Image;
|
||
|
use Google\Web_Stories\Service_Base;
|
||
|
use Google\Web_Stories\Settings;
|
||
|
use Google\Web_Stories\Story_Post_Type;
|
||
|
use WP_Post;
|
||
|
|
||
|
/**
|
||
|
* Admin class.
|
||
|
*/
|
||
|
class Admin extends Service_Base {
|
||
|
|
||
|
/**
|
||
|
* Settings instance.
|
||
|
*
|
||
|
* @var Settings Settings instance.
|
||
|
*/
|
||
|
private Settings $settings;
|
||
|
|
||
|
/**
|
||
|
* Context instance.
|
||
|
*
|
||
|
* @var Context Context instance.
|
||
|
*/
|
||
|
private Context $context;
|
||
|
|
||
|
/**
|
||
|
* Single constructor.
|
||
|
*
|
||
|
* @param Settings $settings Settings instance.
|
||
|
* @param Context $context Context instance.
|
||
|
*/
|
||
|
public function __construct( Settings $settings, Context $context ) {
|
||
|
$this->settings = $settings;
|
||
|
$this->context = $context;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initialize admin-related functionality.
|
||
|
*
|
||
|
* @since 1.0.0
|
||
|
*/
|
||
|
public function register(): void {
|
||
|
add_filter( 'admin_body_class', [ $this, 'admin_body_class' ], 99 );
|
||
|
add_filter( 'default_content', [ $this, 'prefill_post_content' ], 10, 2 );
|
||
|
add_filter( 'default_title', [ $this, 'prefill_post_title' ] );
|
||
|
add_filter( 'display_media_states', [ $this, 'media_states' ], 10, 2 );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the action to use for registering the service.
|
||
|
*
|
||
|
* @since 1.6.0
|
||
|
*
|
||
|
* @return string Registration action to use.
|
||
|
*/
|
||
|
public static function get_registration_action(): string {
|
||
|
return 'admin_init';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Filter the list of admin classes.
|
||
|
*
|
||
|
* Makes sure the admin menu is collapsed when accessing
|
||
|
* the dashboard and the editor.
|
||
|
*
|
||
|
* @since 1.0.0
|
||
|
*
|
||
|
* @param string|mixed $class_name Current classes.
|
||
|
* @return string|mixed List of Classes.
|
||
|
*/
|
||
|
public function admin_body_class( $class_name ) {
|
||
|
if ( ! $this->context->is_story_editor() ) {
|
||
|
return $class_name;
|
||
|
}
|
||
|
|
||
|
// Default WordPress posts list table screen and dashboard.
|
||
|
if ( 'post' !== $this->context->get_screen_base() ) {
|
||
|
return $class_name;
|
||
|
}
|
||
|
|
||
|
$class_name .= ' edit-story';
|
||
|
|
||
|
// Overrides regular WordPress behavior by collapsing the admin menu by default.
|
||
|
if ( ! str_contains( $class_name, 'folded' ) ) {
|
||
|
$class_name .= ' folded';
|
||
|
}
|
||
|
|
||
|
return $class_name;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Pre-fills post content with a web-story/embed block.
|
||
|
*
|
||
|
* @since 1.0.0
|
||
|
*
|
||
|
* @param string|mixed $content Default post content.
|
||
|
* @param WP_Post|null $post Post object.
|
||
|
* @return string|mixed Pre-filled post content if applicable, or the default content otherwise.
|
||
|
*/
|
||
|
public function prefill_post_content( $content, ?WP_Post $post ) {
|
||
|
if ( ! $post ) {
|
||
|
return $content;
|
||
|
}
|
||
|
|
||
|
if ( ! isset( $_GET['from-web-story'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||
|
return $content;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Story ID.
|
||
|
*
|
||
|
* @var string $from_web_story
|
||
|
*/
|
||
|
$from_web_story = $_GET['from-web-story']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||
|
|
||
|
$post_id = absint( sanitize_text_field( (string) wp_unslash( $from_web_story ) ) );
|
||
|
|
||
|
if ( ! $post_id || Story_Post_Type::POST_TYPE_SLUG !== get_post_type( $post_id ) ) {
|
||
|
return $content;
|
||
|
}
|
||
|
|
||
|
if ( ! current_user_can( 'read_post', $post_id ) ) {
|
||
|
return $content;
|
||
|
}
|
||
|
|
||
|
$story = new Story();
|
||
|
if ( ! $story->load_from_post( $post_id ) ) {
|
||
|
return $content;
|
||
|
}
|
||
|
|
||
|
if ( ! $story->get_title() ) {
|
||
|
$story->set_title( __( 'Web Story', 'web-stories' ) );
|
||
|
}
|
||
|
|
||
|
$args = [
|
||
|
'align' => 'none',
|
||
|
'height' => 600,
|
||
|
'width' => 360,
|
||
|
];
|
||
|
|
||
|
if ( ! use_block_editor_for_post( $post ) ) {
|
||
|
$content = '[web_stories_embed url="%1$s" title="%2$s" poster="%3$s" width="%4$s" height="%5$s" align="%6$s"]';
|
||
|
|
||
|
return sprintf(
|
||
|
$content,
|
||
|
esc_url( $story->get_url() ),
|
||
|
esc_attr( $story->get_title() ),
|
||
|
esc_url( $story->get_poster_portrait() ),
|
||
|
absint( $args['width'] ),
|
||
|
absint( $args['height'] ),
|
||
|
esc_attr( $args['align'] )
|
||
|
);
|
||
|
}
|
||
|
|
||
|
$story->set_poster_sizes( '' );
|
||
|
$story->set_poster_srcset( '' );
|
||
|
$renderer = new Image( $story );
|
||
|
$html = $renderer->render( $args );
|
||
|
|
||
|
$content = '<!-- wp:web-stories/embed {"blockType":"url","url":"%1$s","title":"%2$s","poster":"%3$s","width":"%4$s","height":"%5$s","align":"%6$s","stories": [%7$s]} -->%8$s<!-- /wp:web-stories/embed -->';
|
||
|
// note $story->get_url should not be escaped here (esc_url()) see https://github.com/GoogleForCreators/web-stories-wp/issues/11371.
|
||
|
return sprintf(
|
||
|
$content,
|
||
|
$story->get_url(),
|
||
|
esc_js( $story->get_title() ),
|
||
|
esc_url( $story->get_poster_portrait() ),
|
||
|
absint( $args['width'] ),
|
||
|
absint( $args['height'] ),
|
||
|
esc_js( $args['align'] ),
|
||
|
absint( $post_id ),
|
||
|
$html
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Pre-fills post title with the story title.
|
||
|
*
|
||
|
* @since 1.0.0
|
||
|
*
|
||
|
* @param string|mixed $title Default post title.
|
||
|
* @return string|mixed Pre-filled post title if applicable, or the default title otherwise.
|
||
|
*/
|
||
|
public function prefill_post_title( $title ) {
|
||
|
if ( ! isset( $_GET['from-web-story'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||
|
return $title;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Story ID.
|
||
|
*
|
||
|
* @var string $from_web_story
|
||
|
*/
|
||
|
$from_web_story = $_GET['from-web-story']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||
|
|
||
|
$post_id = absint( sanitize_text_field( (string) wp_unslash( $from_web_story ) ) );
|
||
|
|
||
|
if ( ! $post_id ) {
|
||
|
return $title;
|
||
|
}
|
||
|
|
||
|
if ( ! current_user_can( 'read_post', $post_id ) ) {
|
||
|
return $title;
|
||
|
}
|
||
|
|
||
|
$post = get_post( $post_id );
|
||
|
|
||
|
if ( ! $post instanceof WP_Post || Story_Post_Type::POST_TYPE_SLUG !== $post->post_type ) {
|
||
|
return $title;
|
||
|
}
|
||
|
|
||
|
// Not using get_the_title() because we need the raw title.
|
||
|
// Otherwise it runs through wptexturize() and the like, which we want to avoid.
|
||
|
return $post->post_title;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds active publisher logo to media state output.
|
||
|
*
|
||
|
* @since 1.23.0
|
||
|
*
|
||
|
* @param mixed $media_states Array of media states.
|
||
|
* @param WP_Post $post Post object.
|
||
|
* @return mixed Filtered media states.
|
||
|
*/
|
||
|
public function media_states( $media_states, WP_Post $post ) {
|
||
|
if ( ! \is_array( $media_states ) ) {
|
||
|
return $media_states;
|
||
|
}
|
||
|
|
||
|
$active_publisher_logo_id = absint( $this->settings->get_setting( $this->settings::SETTING_NAME_ACTIVE_PUBLISHER_LOGO ) );
|
||
|
|
||
|
if ( $post->ID === $active_publisher_logo_id ) {
|
||
|
$media_states[] = __( 'Web Stories Publisher Logo', 'web-stories' );
|
||
|
}
|
||
|
return $media_states;
|
||
|
}
|
||
|
}
|