Completed
Push — master ( 94c6c2...ff31a4 )
by Jacob
04:23
created

DefaultPageController::get_comments()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 26
rs 8.8571
cc 3
eloc 18
nc 4
nop 0
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
		return CommentCollector::getCommentCountForURL(self::$BLOG_SITE_ID, $post['path']);
86
	}
87
88
	final private function get_tags_for_post($post)
89
	{
90
        global $container;
91
        $repository = new Jacobemerick\Web\Domain\Blog\Tag\MysqlTagRepository($container['db_connection_locator']);
92
        $tag_result = $repository->getTagsForPost($post['id']);
93
94
        $tag_array = array();
95
		foreach($tag_result as $tag)
96
		{
97
			$tag_object = new stdclass();
98
			$tag_object->name = $tag['tag'];
99
			$tag_object->link = Content::instance('URLSafe', "/tag/{$tag['tag']}/")->activate();
100
			$tag_array[] = $tag_object;
101
		}
102
		return $tag_array;
103
	}
104
105
	final private function get_body_for_post($post, $trim)
106
	{
107
		$body = $post['body'];
108
		
109
		if($trim)
110
			$body = Content::instance('SmartTrim', $body)->activate(self::$LENGTH_OF_TRIMMED_POST);
111
		
112
		$body = Content::instance('FixPhoto', $body)->activate(false, 'standard');
113
		$body = Content::instance('MarkupCode', $body)->activate();
114
		
115
		return $body;
116
	}
117
118
	final protected function get_right_side()
119
	{
120
		$side_array = array();
121
		$side_array['tags'] = $this->get_tag_cloud();
122
		$side_array['comments'] = $this->get_comments();
123
		return $side_array;
124
	}
125
126
	final private function get_tag_cloud()
127
	{
128
        global $container;
129
        $repository = new Jacobemerick\Web\Domain\Blog\Tag\MysqlTagRepository($container['db_connection_locator']);
130
        $tag_result = $repository->getTagCloud();
131
		
132
		$maximum_tag_count = $this->get_maximum_tag_count($tag_result);
133
		
134
		$cloud_array = array();
135
		foreach($tag_result as $tag)
136
		{
137
			if($tag['count'] < self::$MINIMUM_TAG_COUNT)
138
				continue;
139
			
140
			$tag_object = new stdclass();
141
			$tag_object->name = $tag['tag'];
142
			$tag_object->link = Content::instance('URLSafe', "/tag/{$tag['tag']}/")->activate();
143
			$tag_object->scalar = floor(($tag['count'] - 1) * (9 / ($maximum_tag_count - self::$MINIMUM_TAG_COUNT)));
144
			$cloud_array[] = $tag_object;
145
		}
146
		
147
		return $cloud_array;
148
	}
149
150
	final private function get_maximum_tag_count($tag_result)
151
	{
152
		$maximum = 1;
153
		
154
		foreach($tag_result as $tag)
155
		{
156
			if($tag['count'] > $maximum)
157
				$maximum = $tag['count'];
158
		}
159
		return $maximum;
160
	}
161
162
	final private function get_comments()
163
	{
164
		$comment_array = CommentCollector::getRecentBlogComments(self::$RECENT_COMMENT_COUNT);
165
		
166
		$array = array();
167
		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...
168
		{
169
			$body = $comment->body;
170
			$body = strip_tags($body);
171
			
172
			$comment_obj = new stdclass();
173
			$comment_obj->description = Content::instance('SmartTrim', $body)->activate(30);
174
			$comment_obj->commenter = $comment->name;
175
			$comment_obj->link = Loader::getRootURL() . "{$comment->category}/{$comment->path}/#comment-{$comment->id}";
176
			$array[] = $comment_obj;
177
		}
178
179
    $comment_service_array = $this->get_comments_from_service();
180
    if ($comment_service_array !== $array) {
181
      global $container;
182
      $container['console']->log('Mismatch between comment service and legacy db');
183
      $container['console']->log($comment_service_array[0]);
184
      $container['console']->log($array[0]);
185
    }
186
		return $array;
187
	}
188
189
    final private function get_comments_from_service()
190
    {
191
        global $config;
192
        $configuration = new Jacobemerick\CommentService\Configuration();
193
        $configuration->setUsername($config->comments->user);
194
        $configuration->setPassword($config->comments->password);
195
        $configuration->addDefaultHeader('Content-Type', 'application/json');
196
        $configuration->setHost($config->comments->host);
197
        $configuration->setCurlTimeout($config->comments->timeout);
198
199
        $client = new Jacobemerick\CommentService\ApiClient($configuration);
200
        $api = new Jacobemerick\CommentService\Api\DefaultApi($client);
201
        $comment_response = $api->getComments(1, self::$RECENT_COMMENT_COUNT, '-date', 'blog.jacobemerick.com');
202
203
        $array = array();
204
        foreach($comment_response as $comment)
205
        {
206
            $body = $comment->getBody();
207
            $body = strip_tags($body);
208
209
            $comment_obj = new stdclass();
210
            $comment_obj->description = Content::instance('SmartTrim', $body)->activate(30);
211
            $comment_obj->commenter = $comment->getCommenter()->getName();
212
            $comment_obj->link = "{$comment->getUrl()}/#comment-{$comment->getId()}";
213
            $array[] = $comment_obj;
214
        }
215
        return $array;
216
    }
217
218
}
219