Completed
Push — master ( 5bed8f...b71929 )
by Jacob
04:00
created

DefaultPageController   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 247
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 4
Bugs 0 Features 3
Metric Value
wmc 4
c 4
b 0
f 3
lcom 1
cbo 1
dl 0
loc 247
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A set_body_data() 0 8 2
A set_head_data() 0 14 1
A get_introduction() 0 4 2
A get_introduction_image() 0 17 2
A format_post() 0 16 1
A get_comments_for_post() 0 12 2
A get_comments_for_post_from_service() 0 21 1
A get_tags_for_post() 0 16 2
A get_body_for_post() 0 12 2
A get_right_side() 0 7 1
A get_tag_cloud() 0 23 3
A get_maximum_tag_count() 0 11 3
B get_comments() 0 26 3
B get_comments_from_service() 0 34 2
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', 'comment/CommentCollector');
4
5
Loader::load('controller', '/PageController');
6
Loader::load('utility', 'Content');
7
8
abstract class DefaultPageController extends PageController
9
{
10
11
	private static $RECENT_COMMENT_COUNT = 10;
12
	private static $MINIMUM_TAG_COUNT = 10;
13
	protected static $LENGTH_OF_TRIMMED_POST = 300;
14
15
	protected static $BLOG_SITE_ID = 2;
16
17
	private static $INTRODUCTION_IMAGE_PATTERN = '<img src="/photo/%s/%s-size-%s.jpg" height="%d" width="%d" alt="%s" />';
18
19
	protected function set_head_data()
20
	{
21
    $this->set_head('rss_link', [
22
      'title' => 'Jacob Emerick Blog Feed',
23
      'url' => '/rss.xml'
24
    ]);
25
    $this->set_head('rss_comment_link', [
26
      'title' => 'Jacob Emerick Blog Comment Feed',
27
      'url' => '/rss-comments.xml'
28
    ]);
29
		
30
		$this->add_css('normalize');
31
		$this->add_css('blog');
32
	}
33
34
	protected function get_introduction()
35
	{
36
		return;
37
	}
38
39
	protected function get_introduction_image($id)
40
	{
41
		Loader::load('collector', 'image/PhotoCollector');
42
		$photo_result = PhotoCollector::getRow($id);
43
		
44
		if($photo_result == null)
45
			return;
46
		
47
		$name = $photo_result->name;
48
		$category = $photo_result->category;
49
		$size = 'medium';
50
		$height = 375;
51
		$width = 500;
52
		$description = $photo_result->description;
53
		
54
		return sprintf(self::$INTRODUCTION_IMAGE_PATTERN, $category, $name, $size, $height, $width, $description);
55
	}
56
57
	protected function set_body_data()
58
	{
59
		$this->set_body('introduction', $this->get_introduction());
60
		$this->set_body('right_side', $this->get_right_side());
61
		$this->set_body('activity_array', $this->get_recent_activity());
62
		
63
		$this->set_body_view('Page');
64
	}
65
66
	final protected function format_post($post, $trim = false)
67
	{
68
		$post_object = new stdclass();
69
		
70
		$post_object->title = $post['title'];
71
		$post_object->path = "/{$post['category']}/{$post['path']}/";
72
		$post_object->category = ucwords(str_replace('-', ' ', $post['category']));
73
		$post_object->category_link = "/{$post['category']}/";
74
		$post_object->comment_count = $this->get_comments_for_post($post);
75
		$post_object->tags = $this->get_tags_for_post($post);
76
		$post_object->image = Content::instance('FetchFirstPhoto', $post['body'])->activate(false, 'small');
77
		$post_object->body = $this->get_body_for_post($post, $trim);
78
		$post_object->date = $this->get_parsed_date($post['date']);
79
80
		return $post_object;
81
	}
82
83
	final private function get_comments_for_post($post)
84
	{
85
		$count = CommentCollector::getCommentCountForURL(self::$BLOG_SITE_ID, $post['path']);
86
    $count_from_service = $this->get_comments_for_post_from_service($post);
87
88
    if ($count != $count_from_service) {
89
        global $container;
90
        $container['console']->log('Mismatch between comment service and legacy db');
91
        $container['console']->log("{$count}, {$count_from_service} in service");
92
    }
93
    return $count;
94
	}
95
96
    final private function get_comments_for_post_from_service($post)
97
    {
98
        global $config;
99
        $configuration = new Jacobemerick\CommentService\Configuration();
100
        $configuration->setUsername($config->comments->user);
101
        $configuration->setPassword($config->comments->password);
102
        $configuration->addDefaultHeader('Content-Type', 'application/json');
103
        $configuration->setHost($config->comments->host);
104
        $configuration->setCurlTimeout($config->comments->timeout);
105
106
        $client = new Jacobemerick\CommentService\ApiClient($configuration);
107
        $api = new Jacobemerick\CommentService\Api\DefaultApi($client);
108
109
        $start = microtime(true);
110
        $comment_response = $api->getComments(null, null, null, 'blog.jacobemerick.com', "{$post['category']}/{$post['path']}");
111
        $elapsed = microtime(true) - $start;
112
        global $container;
113
        $container['logger']->info("CommentService | Comment Count | {$elapsed}");
114
115
        return count($comment_response);
116
    }
117
118
	final private function get_tags_for_post($post)
119
	{
120
        global $container;
121
        $repository = new Jacobemerick\Web\Domain\Blog\Tag\MysqlTagRepository($container['db_connection_locator']);
122
        $tag_result = $repository->getTagsForPost($post['id']);
123
124
        $tag_array = array();
125
		foreach($tag_result as $tag)
126
		{
127
			$tag_object = new stdclass();
128
			$tag_object->name = $tag['tag'];
129
			$tag_object->link = Content::instance('URLSafe', "/tag/{$tag['tag']}/")->activate();
130
			$tag_array[] = $tag_object;
131
		}
132
		return $tag_array;
133
	}
134
135
	final private function get_body_for_post($post, $trim)
136
	{
137
		$body = $post['body'];
138
		
139
		if($trim)
140
			$body = Content::instance('SmartTrim', $body)->activate(self::$LENGTH_OF_TRIMMED_POST);
141
		
142
		$body = Content::instance('FixPhoto', $body)->activate(false, 'standard');
143
		$body = Content::instance('MarkupCode', $body)->activate();
144
		
145
		return $body;
146
	}
147
148
	final protected function get_right_side()
149
	{
150
		$side_array = array();
151
		$side_array['tags'] = $this->get_tag_cloud();
152
		$side_array['comments'] = $this->get_comments();
153
		return $side_array;
154
	}
155
156
	final private function get_tag_cloud()
157
	{
158
        global $container;
159
        $repository = new Jacobemerick\Web\Domain\Blog\Tag\MysqlTagRepository($container['db_connection_locator']);
160
        $tag_result = $repository->getTagCloud();
161
		
162
		$maximum_tag_count = $this->get_maximum_tag_count($tag_result);
163
		
164
		$cloud_array = array();
165
		foreach($tag_result as $tag)
166
		{
167
			if($tag['count'] < self::$MINIMUM_TAG_COUNT)
168
				continue;
169
			
170
			$tag_object = new stdclass();
171
			$tag_object->name = $tag['tag'];
172
			$tag_object->link = Content::instance('URLSafe', "/tag/{$tag['tag']}/")->activate();
173
			$tag_object->scalar = floor(($tag['count'] - 1) * (9 / ($maximum_tag_count - self::$MINIMUM_TAG_COUNT)));
174
			$cloud_array[] = $tag_object;
175
		}
176
		
177
		return $cloud_array;
178
	}
179
180
	final private function get_maximum_tag_count($tag_result)
181
	{
182
		$maximum = 1;
183
		
184
		foreach($tag_result as $tag)
185
		{
186
			if($tag['count'] > $maximum)
187
				$maximum = $tag['count'];
188
		}
189
		return $maximum;
190
	}
191
192
	final private function get_comments()
193
	{
194
		$comment_array = CommentCollector::getRecentBlogComments(self::$RECENT_COMMENT_COUNT);
195
		
196
		$array = array();
197
		foreach($comment_array as $comment)
0 ignored issues
show
Bug introduced by
The expression $comment_array of type array|false is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
198
		{
199
			$body = $comment->body;
200
			$body = strip_tags($body);
201
			
202
			$comment_obj = new stdclass();
203
			$comment_obj->description = Content::instance('SmartTrim', $body)->activate(30);
204
			$comment_obj->commenter = $comment->name;
205
			$comment_obj->link = Loader::getRootURL() . "{$comment->category}/{$comment->path}/#comment-{$comment->id}";
206
			$array[] = $comment_obj;
207
		}
208
209
    $comment_service_array = $this->get_comments_from_service();
210
    if ($comment_service_array !== $array) {
211
      global $container;
212
      $container['console']->log('Mismatch between comment service and legacy db');
213
      $container['console']->log($comment_service_array[0]);
214
      $container['console']->log($array[0]);
215
    }
216
		return $array;
217
	}
218
219
    final private function get_comments_from_service()
220
    {
221
        global $config;
222
        $configuration = new Jacobemerick\CommentService\Configuration();
223
        $configuration->setUsername($config->comments->user);
224
        $configuration->setPassword($config->comments->password);
225
        $configuration->addDefaultHeader('Content-Type', 'application/json');
226
        $configuration->setHost($config->comments->host);
227
        $configuration->setCurlTimeout($config->comments->timeout);
228
229
        $client = new Jacobemerick\CommentService\ApiClient($configuration);
230
        $api = new Jacobemerick\CommentService\Api\DefaultApi($client);
231
232
        $start = microtime(true);
233
        $comment_response = $api->getComments(1, self::$RECENT_COMMENT_COUNT, '-date', 'blog.jacobemerick.com');
234
        $elapsed = microtime(true) - $start;
235
        global $container;
236
        $container['logger']->info("CommentService | Sidebar | {$elapsed}");
237
238
        $array = array();
239
        foreach($comment_response as $comment)
240
        {
241
            $body = $comment->getBody();
242
            $body = Content::instance('CleanComment', $body)->activate();
243
            $body = strip_tags($body);
244
245
            $comment_obj = new stdclass();
246
            $comment_obj->description = Content::instance('SmartTrim', $body)->activate(30);
247
            $comment_obj->commenter = $comment->getCommenter()->getName();
248
            $comment_obj->link = "{$comment->getUrl()}/#comment-{$comment->getId()}";
249
            $array[] = $comment_obj;
250
        }
251
        return $array;
252
    }
253
254
}
255