Completed
Push — master ( 0a764c...75f0dd )
by Sam
01:58
created

Reports   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 143
Duplicated Lines 14.69 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 4
dl 21
loc 143
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A reports_table_name() 0 4 1
A report_sources_table_name() 0 4 1
A get_template() 0 27 4
B activate() 21 56 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * This file contains only a single class.
4
 *
5
 * @file
6
 * @package Tabulate
7
 */
8
9
namespace WordPress\Tabulate\DB;
10
11
/**
12
 * This class handles everything to do with Reports.
13
 */
14
class Reports {
15
16
	/**
17
	 * The ID of the primary report.
18
	 */
19
	const DEFAULT_REPORT_ID = 1;
20
21
	/**
22
	 * The database.
23
	 *
24
	 * @var \WordPress\Tabulate\DB\Database
25
	 */
26
	protected $db;
27
28
	/**
29
	 * Create a Reports object based on a given Database.
30
	 *
31
	 * @param \WordPress\Tabulate\DB\Database $db The database object.
32
	 */
33
	public function __construct( Database $db ) {
34
		$this->db = $db;
35
	}
36
37
	/**
38
	 * Get the name of the 'reports' database table.
39
	 *
40
	 * @global \wpdb $wpdb
41
	 * @return string
42
	 */
43
	public static function reports_table_name() {
44
		global $wpdb;
45
		return $wpdb->prefix . TABULATE_SLUG . '_reports';
46
	}
47
48
	/**
49
	 * Get the name of the 'report_sources' database table.
50
	 *
51
	 * @global \wpdb $wpdb
52
	 * @return string
53
	 */
54
	public static function report_sources_table_name() {
55
		global $wpdb;
56
		return $wpdb->prefix . TABULATE_SLUG . '_report_sources';
57
	}
58
59
	/**
60
	 * Get a Template instance based on a given report's template string and
61
	 * populated with all of the report's source queries.
62
	 *
63
	 * @param int $report_id The report ID.
64
	 * @return \WordPress\Tabulate\Template
65
	 * @throws Exception If the requested report could not be found.
66
	 */
67
	public function get_template( $report_id ) {
68
		// Find the report.
69
		$reports = $this->db->get_table( self::reports_table_name() );
70
		if ( false === $reports ) {
71
			$msg = "Reports table not found. Please re-activate Tabulate to create it.";
72
			throw new Exception( $msg );
73
		}
74
		$report = $reports->get_record( $report_id );
75
		if ( false === $report ) {
76
			throw new Exception( "Report $report_id not found." );
77
		}
78
		$template = new \WordPress\Tabulate\Template( false, $report->template() );
0 ignored issues
show
Documentation Bug introduced by
The method template does not exist on object<WordPress\Tabulate\DB\Record>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
79
		$template->title = $report->title();
0 ignored issues
show
Documentation Bug introduced by
The method title does not exist on object<WordPress\Tabulate\DB\Record>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
80
		$template->file_extension = $report->file_extension();
0 ignored issues
show
Documentation Bug introduced by
The method file_extension does not exist on object<WordPress\Tabulate\DB\Record>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
81
		$template->mime_type = $report->mime_type();
0 ignored issues
show
Documentation Bug introduced by
The method mime_type does not exist on object<WordPress\Tabulate\DB\Record>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
82
83
		// Populate with source data.
84
		$sql = "SELECT * FROM `" . self::report_sources_table_name() . "` WHERE report = " . $report_id;
85
		$sources = $this->db->get_wpdb()->get_results( $sql );
86
		foreach ( $sources as $source ) {
87
			$data = $this->db->get_wpdb()->get_results( $source->query );
88
			$template->{$source->name} = $data;
89
		}
90
91
		// Return the template.
92
		return $template;
93
	}
94
95
	/**
96
	 * On plugin activation, create the required database tables.
97
	 *
98
	 * @param \wpdb $wpdb The global database object.
99
	 */
100
	public static function activate( \wpdb $wpdb ) {
101
		$wpdb->show_errors();
102
		$db = new Database( $wpdb );
103
104 View Code Duplication
		if ( ! $db->get_table( self::reports_table_name() ) ) {
105
			$sql = "CREATE TABLE IF NOT EXISTS `" . self::reports_table_name() . "` (
106
				`id` INT(4) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
107
				`title` varchar(191) NOT NULL UNIQUE,
108
				`description` text NOT NULL,
109
				`mime_type` varchar(50) NOT NULL DEFAULT 'text/html',
110
				`file_extension` varchar(10) DEFAULT NULL COMMENT 'If defined, this report will be downloaded.',
111
				`template` text NOT NULL COMMENT 'The Twig template used to display this report.'
112
				) ENGINE=InnoDB;";
113
			$wpdb->query( $sql );
114
		}
115
		// Reduce length of title column to floor(767/4) = 191 characters. GH60.
116
		$title_size = $db->get_table( self::reports_table_name() )->get_column( 'title' )->get_size();
117
		if ( $title_size == 200 ) {
118
			$wpdb->query( "ALTER TABLE `" . self::reports_table_name() . "` MODIFY `title` VARCHAR(191) NOT NULL" );
119
		}
120
121 View Code Duplication
		if ( ! $db->get_table( self::report_sources_table_name() ) ) {
122
			$sql = "CREATE TABLE IF NOT EXISTS `" . self::report_sources_table_name() . "` (
123
				`id` INT(5) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
124
				`report` INT(4) unsigned NOT NULL,
125
						FOREIGN KEY (`report`) REFERENCES `" . self::reports_table_name() . "` (`id`),
126
				`name` varchar(50) NOT NULL,
127
				`query` text NOT NULL
128
				) ENGINE=InnoDB;";
129
			$wpdb->query( $sql );
130
		}
131
132
		if ( '0' === $wpdb->get_var( "SELECT COUNT(*) FROM `" . self::reports_table_name() . "`" ) ) {
133
			// Create the default report, to list all reports.
134
			$template_string = "<dl>\n"
135
			. "{% for report in reports %}\n"
136
			. "  <dt><a href='{{ admin_url('admin.php?page=tabulate&controller=reports&id='~report.id) }}'>{{report.title}}</a></dt>\n"
137
			. "  <dd>{{report.description}}</dd>\n"
138
			. "{% endfor %}\n"
139
			. "</dl>";
140
			$sql1 = "INSERT INTO `" . self::reports_table_name() . "` SET"
141
				. " id          = " . self::DEFAULT_REPORT_ID . ", "
142
				. " title       = 'Reports', "
143
				. " description = 'List of all Reports.',"
144
				. " template    = %s;";
145
			$wpdb->query( $wpdb->prepare( $sql1, array( $template_string ) ) );
146
			// And the query for the above report.
147
			$query = "SELECT * FROM " . self::reports_table_name();
148
			$sql2 = "INSERT INTO `" . self::report_sources_table_name() . "` SET "
149
				. " report = " . self::DEFAULT_REPORT_ID . ","
150
				. " name   = 'reports',"
151
				. " query  = %s;";
152
			$wpdb->query( $wpdb->prepare( $sql2, array( $query ) ) );
153
		}
154
155
	}
156
}
157