Completed
Push — master ( 4988a4...54f6f8 )
by Jacob
04:02
created

PostController   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 265
Duplicated Lines 4.15 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 23
c 0
b 0
f 0
lcom 1
cbo 2
dl 11
loc 265
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 21 5
A set_head_data() 0 22 1
A get_introduction() 0 1 1
A set_body_data() 0 15 1
A get_post_description() 0 8 1
A get_post_keywords() 0 15 2
C get_series_posts() 0 58 10
A fetch_series_posts() 0 9 2
B get_related_posts() 11 35 5
A get_comment_array() 0 54 4

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
<?
0 ignored issues
show
Security Best Practice introduced by
It is not recommend to use PHP's short opening tag <?, better use <?php, or <?= in case of outputting.

Short opening tags are disabled in PHP’s default configuration. In such a case, all content of this file is output verbatim to the browser without being parsed, or executed.

As a precaution to avoid these problems better use the long opening tag <?php.

Loading history...
2
3
Loader::load('collector', 'waterfall/LogCollector');
4
Loader::load('controller', 'blog/DefaultPageController');
5
6
final class PostController extends DefaultPageController
7
{
8
9
	private static $PAGE_DESCRIPTION_LIMIT = 250;
10
11
	private static $TITLE = "%s | Jacob Emerick's Blog";
12
	private static $AUTHOR = 'Jacob Emerick';
13
	private static $AUTHOR_URL = 'https://home.jacobemerick.com/';
14
15
	private static $POST_LENGTH_SHORT = 100;
16
	private static $POST_LENGTH_LONG = 140;
17
18
	private $post;
19
	private $tags;
20
	private $comment_errors = array();
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $comment_errors 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...
21
22
	public function __construct()
23
	{
24
		parent::__construct();
25
		
26
        global $container;
27
        $repository = new Jacobemerick\Web\Domain\Blog\Post\MysqlPostRepository($container['db_connection_locator']);
28
        $this->post = $repository->findPostByPath(URLDecode::getPiece(2));
29
30
		if($this->post == null)
31
			$this->eject();
32
		
33
		$this->handle_comment_submit(
34
			self::$BLOG_SITE_ID,
35
			$this->post['path'],
36
			Loader::getRootUrl('blog') . $this->post['category'] . '/' . $this->post['path'] . '/',
37
			$this->post['title']);
38
39
        global $container;
40
        $repository = new Jacobemerick\Web\Domain\Blog\Tag\MysqlTagRepository($container['db_connection_locator']);
41
        $this->tags = $repository->getTagsForPost($this->post['id']);
42
	}
43
44
	protected function set_head_data()
45
	{
46
		parent::set_head_data();
47
		
48
		$this->set_title(sprintf(self::$TITLE, $this->post['title']));
49
		$this->set_description($this->get_post_description());
50
		$this->set_keywords($this->get_post_keywords());
51
		$this->set_author(self::$AUTHOR);
52
53
    $photo = Content::instance('FetchFirstPhoto', $this->post['body'])->activate(true);
54
    $photo = preg_match('/^<img src="([a-z-:\.\/]+)" [^>]+>$/', $photo, $matches);
0 ignored issues
show
Unused Code introduced by
$photo is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
55
    $this->set_head('thumbnail', $matches[1]);
56
57
		if (array_key_exists($this->post['id'], self::$DEPRECATED_BLOGS)) {
58
			$log_id = self::$DEPRECATED_BLOGS[$this->post['id']];
59
			$log = LogCollector::getById($log_id);
60
			if (!empty($log)) {
61
				$log_url = Loader::getRootUrl('waterfalls') . "journal/{$log->alias}/";
62
				$this->set_canonical($log_url);
63
			}
64
		}
65
	}
66
67
	protected function get_introduction() {}
68
69
	protected function set_body_data()
70
	{
71
		parent::set_body_data();
72
		
73
		$this->set_body('title', $this->post['title']);
74
		$this->set_body('view', 'Post');
75
		$this->set_body('data', array(
76
			'post' => $this->format_post($this->post, false),
77
			'series_posts' => $this->get_series_posts(),
78
			'related_posts' => $this->get_related_posts(),
79
			'author' => self::$AUTHOR,
80
			'author_url' => self::$AUTHOR_URL,
81
			'comment_array' => $this->get_comment_array("{$this->post['category']}/{$this->post['path']}"),
82
    ));
83
	}
84
85
	protected function get_post_description()
86
	{
87
		$description = $this->post['body'];
88
		$description = strip_tags($description);
89
		$description = Content::instance('SmartTrim', $description)->activate(self::$PAGE_DESCRIPTION_LIMIT);
90
		
91
		return $description;
92
	}
93
94
	protected function get_post_keywords()
95
	{
96
		$keyword_array = array();
97
		$keywords = $this->tags;
98
		
99
		foreach($keywords as $keyword)
100
		{
101
			$keyword_array[] = $keyword['tag'];
102
		}
103
		
104
		$keyword_array[] = 'blog';
105
		$keyword_array[] = 'Jacob Emerick';
106
		
107
		return $keyword_array;
108
	}
109
110
	private function get_series_posts()
111
	{
112
		$series_posts = $this->fetch_series_posts();
113
		if(count($series_posts) < 1)
114
			return array();
115
		
116
		$previous_post = new stdclass();
117
		$next_post = new stdclass();
118
		
119
		$found_current_post = false;
120
		foreach($series_posts as $post_row)
121
		{
122
			if($post_row['post'] == $this->post['id'])
123
			{
124
				$found_current_post = true;
125
				continue;
126
			}
127
			
128
			$post = new stdclass();
129
130
      if (
131
        strpos($post_row['title'], 'Rainy Supe Loop') === 0 ||
132
        strpos($post_row['title'], 'Malapais Loop') === 0 ||
133
        strpos($post_row['title'], 'Mazatzal Peak Loop') === 0 ||
134
        strpos($post_row['title'], 'Dripping Springs Loop') === 0
135
      ) {
136
        $title = $post_row['title'];
137
        $title = explode(':', $title);
138
        $title = array_pop($title);
139
        $title = trim($title);
140
        $post->title = $title;
141
      } else if (strpos($post_row['title'], 'Isle Royale') === 0) {
142
				$title = $post_row['title'];
143
				$title = explode(',', $title);
144
				$title = array_pop($title);
145
				$title = trim($title);
146
				$post->title = $title;
147
			} else {
148
				$post->title = $post_row['title'];
149
			}
150
151
			$post->url = Loader::getRootUrl('blog') . "{$post_row['category']}/{$post_row['path']}/";
152
			
153
			if(!$found_current_post)
154
				$previous_post = $post;
155
			else
156
			{
157
				$next_post = $post;
158
				break;
159
			}
160
		}
161
		
162
		return array(
163
			'title' => $post_row['series_title'],
0 ignored issues
show
Bug introduced by
The variable $post_row seems to be defined by a foreach iteration on line 120. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
164
			'description' => Content::instance('FixInternalLink', $post_row['series_description'])->activate(),
165
			'previous' => $previous_post,
166
			'next' => $next_post);
167
	}
168
169
	private $series_posts;
170
	private function fetch_series_posts()
171
	{
172
      if(!isset($this->series_posts)) {
173
          global $container;
174
          $repository = new Jacobemerick\Web\Domain\Blog\Series\MysqlSeriesRepository($container['db_connection_locator']);
175
          $this->series_posts = $repository->getSeriesForPost($this->post['id']);
176
      }
177
      return $this->series_posts;
178
	}
179
180
	private function get_related_posts()
181
	{
182
		$tag_array = array();
183
		foreach($this->tags as $tag)
184
		{
185
			$tag_array[] = $tag['id'];
186
		}
187
		
188
		$series_posts = $this->fetch_series_posts();
189
		$exclude_post_array = array();
190
		foreach($series_posts as $series_post)
191
		{
192
			$exclude_post_array[] = $series_post['post'];
193
		}
194
195
        global $container;
196
        $repository = new Jacobemerick\Web\Domain\Blog\Post\MysqlPostRepository($container['db_connection_locator']);
197
        $post_result = $repository->getActivePostsByRelatedTags($this->post['id']);
198
199
        $post_array = array();
200
		
201 View Code Duplication
		foreach($post_result as $post_row)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
202
		{
203
			$post = new stdclass();
204
			$post->title = $post_row['title'];
205
			$post->url = Loader::getRootUrl('blog') . "{$post_row['category']}/{$post_row['path']}/";
206
			$post->category = ucwords(str_replace('-', ' ', $post_row['category']));
207
			$post->thumb = Content::instance('FetchFirstPhoto', $post_row['body'])->activate();
208
			$post->body = Content::instance('SmartTrim', $post_row['body'])->activate(($post->thumb !== '') ? self::$POST_LENGTH_SHORT : self::$POST_LENGTH_LONG);
209
			
210
			$post_array[] = $post;
211
		}
212
		
213
		return $post_array;
214
	}
215
216
    protected function get_comment_array($path)
217
    {
218
        global $container;
219
        $repository = new Jacobemerick\Web\Domain\Comment\Comment\ServiceCommentRepository($container['comment_service_api']);
220
        $start = microtime(true);
221
        try {
222
            $comment_response = $repository->getComments(
223
                'blog.jacobemerick.com',
224
                $path,
225
                1,
226
                null,
227
                'date'
228
            );
229
        } catch (Exception $e) {
230
            $container['logger']->warning("CommentService | Path | {$e->getMessage()}");
231
            return;
232
        }
233
 
234
        $elapsed = microtime(true) - $start;
235
        global $container;
236
        $container['logger']->info("CommentService | Path | {$elapsed}");
237
238
        $array = array();
239
        foreach((array) $comment_response as $comment)
240
        {
241
            $body = Content::instance('CleanComment', $comment['body'])->activate();
242
            $body = strip_tags($body);
243
244
            $comment_obj = new stdclass();
245
            $comment_obj->id = $comment['id'];
246
            $comment_obj->name = $comment['commenter']['name'];
247
            $comment_obj->url = $comment['commenter']['website'];
248
            $comment_obj->trusted = true;
249
            $comment_obj->date = $comment['date']->format('M j, \'y');
250
            $comment_obj->body = $body;
251
252
            if ($comment['reply_to']) {
253
                $array[$comment['reply_to']]->replies[$comment['id']] = $comment_obj;
254
                continue;
255
            }
256
257
            $comment_obj->replies = [];
258
            $array[$comment['id']] = $comment_obj;
259
        }
260
261
        // todo figure out commenter obj
262
        // todo figure out how to handle errors or whatever
263
        return [
264
            'comments' => $array,
265
            'commenter' => [],
266
            'errors' => [],
267
            'comment_count' => count($comment_response),
268
        ];
269
    }
270
}
271