Completed
Pull Request — master (#18)
by Damian
03:09
created

AkismetSpamProtector   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4
Metric Value
wmc 10
lcom 2
cbo 4
dl 0
loc 125
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A set_api_key() 0 4 1
A get_api_key() 0 17 4
A api() 0 13 2
A getFormField() 0 5 1
A setFieldMapping() 0 4 1
1
<?php
2
3
/**
4
 * Spam protector for Akismet
5
 *
6
 * @author Damian Mooyman
7
 * @package akismet
8
 */
9
class AkismetSpamProtector implements SpamProtector
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
10
{
11
    /**
12
     * Set this to your API key
13
     * 
14
     * @var string
15
     * @config
16
     */
17
    private static $api_key = null;
0 ignored issues
show
Unused Code introduced by
The property $api_key is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
18
19
    /**
20
     * Permission required to bypass check
21
     *
22
     * @var string
23
     * @config
24
     */
25
    private static $bypass_permission = 'ADMIN';
0 ignored issues
show
Unused Code introduced by
The property $bypass_permission is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
26
27
    /**
28
     * Set to try to bypass check for all logged in users
29
     *
30
     * @var boolean
31
     * @config
32
     */
33
    private static $bypass_members = false;
0 ignored issues
show
Unused Code introduced by
The property $bypass_members is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
34
35
    /**
36
     * IMPORTANT: If you are operating in a country (such as Germany) that has content transmission disclosure
37
     * requirements, set this to true in order to require a user prompt prior to submission of user data
38
     * to the Akismet servers
39
     *
40
     * @var boolean
41
     * @config
42
     */
43
    private static $require_confirmation = false;
0 ignored issues
show
Unused Code introduced by
The property $require_confirmation is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
44
45
    /**
46
     * Set to true to disable spam errors, instead saving this field to the dataobject with the spam
47
     * detection as a flag. This will disable validation errors when spam is encountered.
48
     * The flag will be saved to the same field specified by the 'name' option in enableSpamProtection()
49
     *
50
     * @var boolean
51
     * @config
52
     */
53
    private static $save_spam = false;
0 ignored issues
show
Unused Code introduced by
The property $save_spam is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
54
    
55
    /**
56
     * @var array
57
     */
58
    private $fieldMapping = array();
59
    
60
    /**
61
     * Overridden API key
62
     *
63
     * @var string
64
     */
65
    protected static $_api_key = null;
66
67
    public function __construct($options = array())
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
68
    {
69
    }
70
    
71
    /**
72
     * Set the API key
73
     * 
74
     * @param string $key
75
     */
76
    public static function set_api_key($key)
77
    {
78
        self::$_api_key = $key;
79
    }
80
    
81
    /**
82
     * Get the API key
83
     * 
84
     * @return string
85
     */
86
    protected static function get_api_key()
87
    {
88
        if (self::$_api_key) {
89
            return self::$_api_key;
90
        }
91
        
92
        // Check config
93
        $key = Config::inst()->get('AkismetSpamProtector', 'api_key');
94
        if (!empty($key)) {
95
            return $key;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $key; (array|integer|double|string|boolean) is incompatible with the return type documented by AkismetSpamProtector::get_api_key of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
96
        }
97
        
98
        // Check environment
99
        if (defined('SS_AKISMET_API_KEY')) {
100
            return SS_AKISMET_API_KEY;
101
        }
102
    }
103
    
104
    /**
105
     * Retrieves Akismet API object singleton, or null if not configured
106
     * 
107
     * @return AkismetService
108
     */
109
    public static function api()
110
    {
111
        // Get API key and URL
112
        $key = self::get_api_key();
113
        if (empty($key)) {
114
            user_error("AkismetSpamProtector is incorrectly configured. Please specify an API key.", E_USER_WARNING);
115
            return null;
116
        }
117
        $url = Director::protocolAndHost();
118
        
119
        // Generate API object
120
        return Injector::inst()->get('AkismetService', true, array($key, $url));
121
    }
122
    
123
    public function getFormField($name = null, $title = null, $value = null, $form = null, $rightTitle = null)
124
    {
125
        return AkismetField::create($name, $title, $value, $form, $rightTitle)
126
            ->setFieldMapping($this->fieldMapping);
127
    }
128
129
    public function setFieldMapping($fieldMapping)
130
    {
131
        $this->fieldMapping = $fieldMapping;
132
    }
133
}
134