Completed
Push — milestone/2.0 ( 8a1186...26a446 )
by
unknown
04:33
created

Comment_Meta_Container::set_comment_id()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Carbon_Fields\Container;
4
5
use Carbon_Fields\Datastore\Meta_Datastore;
6
use Carbon_Fields\Datastore\Datastore;
7
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
8
9
/**
10
 * Comment meta container class.
11
 */
12
class Comment_Meta_Container extends Container {
13
	protected $comment_id;
14
15
	/**
16
	 * Create a new container
17
	 *
18
	 * @param string $unique_id Unique id of the container
19
	 * @param string $title title of the container
20
	 * @param string $type Type of the container
21
	 **/
22 View Code Duplication
	public function __construct( $unique_id, $title, $type ) {
23
		parent::__construct( $unique_id, $title, $type );
24
25
		if ( ! $this->get_datastore() ) {
26
			$this->set_datastore( Datastore::make( 'comment_meta' ), $this->has_default_datastore() );
27
		}
28
	}
29
30
	/**
31
	 * Perform instance initialization
32
	 **/
33
	public function init() {
34
		if ( isset( $_GET['c'] ) && $comment_id = absint( $_GET['c'] ) ) { // Input var okay.
35
			$this->set_comment_id( $comment_id );
36
		}
37
38
		add_action( 'admin_init', array( $this, '_attach' ) );
39
		add_action( 'edit_comment', array( $this, '_save' ) );
40
	}
41
42
	/**
43
	 * Checks whether the current request is valid
44
	 *
45
	 * @return bool
46
	 **/
47
	public function is_valid_save() {
48
		return $this->verified_nonce_in_request();
49
	}
50
51
	/**
52
	 * Perform save operation after successful is_valid_save() check.
53
	 * The call is propagated to all fields in the container.
54
	 *
55
	 * @param int $comment_id ID of the comment against which save() is ran
56
	 **/
57
	public function save( $comment_id ) {
58
59
		// Unhook action to guarantee single save
60
		remove_action( 'edit_comment', array( $this, '_save' ) );
61
62
		$this->set_comment_id( $comment_id );
63
64
		foreach ( $this->fields as $field ) {
65
			$field->set_value_from_input();
66
			$field->save();
67
		}
68
	}
69
70
	/**
71
	 * Check container attachment rules against current page request (in admin)
72
	 *
73
	 * @return bool
74
	 **/
75
	public function is_valid_attach_for_request() {
76
		global $pagenow;
77
78
		return ( $pagenow === 'comment.php' );
79
	}
80
81
	/**
82
	 * Check container attachment rules against object id
83
	 *
84
	 * @return bool
85
	 **/
86
	public function is_valid_attach_for_object( $object_id = null ) {
87
		return true;
88
	}
89
90
	/**
91
	 * Add meta box to the comment
92
	 **/
93
	public function attach() {
94
		add_meta_box(
95
			$this->id,
96
			$this->title,
97
			array( $this, 'render' ),
98
			'comment',
99
			'normal',
100
			'high'
101
		);
102
	}
103
104
	/**
105
	 * Output the container markup
106
	 **/
107
	public function render() {
108
		include \Carbon_Fields\DIR . '/templates/Container/comment_meta.php';
109
	}
110
111
	/**
112
	 * Set the comment ID the container will operate with.
113
	 *
114
	 * @param int $comment_id
115
	 **/
116
	public function set_comment_id( $comment_id ) {
117
		$this->comment_id = $comment_id;
118
		$this->get_datastore()->set_id( $comment_id );
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Carbon_Fields\Datastore\Datastore_Interface as the method set_id() does only exist in the following implementations of said interface: Carbon_Fields\Datastore\Comment_Meta_Datastore, Carbon_Fields\Datastore\Meta_Datastore, Carbon_Fields\Datastore\Nav_Menu_Item_Datastore, Carbon_Fields\Datastore\Post_Meta_Datastore, Carbon_Fields\Datastore\Term_Meta_Datastore, Carbon_Fields\Datastore\User_Meta_Datastore.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
119
	}
120
}
121