Completed
Push — 1.5 ( 293f07...bc7cd6 )
by Rafał
13:04
created

renderLinkImpressionCount()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 93

Duplication

Lines 3
Ratio 3.23 %

Importance

Changes 0
Metric Value
dl 3
loc 93
rs 8.1527
c 0
b 0
f 0
cc 2
nc 2
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Core Bundle.
7
 *
8
 * Copyright 2017 Sourcefabric z.u. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2017 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\CoreBundle\Twig;
18
19
use SWP\Bundle\CoreBundle\Model\ArticleInterface;
20
use SWP\Component\TemplatesSystem\Gimme\Meta\Meta;
21
use Twig\Extension\AbstractExtension;
22
use Twig\TwigFunction;
23
24
class ArticleEventsExtension extends AbstractExtension
25
{
26
    protected $analyticsHost;
27
28
    public function __construct(string $analyticsHost = null)
29
    {
30
        $this->analyticsHost = $analyticsHost;
31
    }
32
33
    /**
34
     * @return TwigFunction[]
35
     */
36
    public function getFunctions()
37
    {
38
        return [
39
            new TwigFunction('countPageView', [$this, 'renderPageViewCount'], ['is_safe' => ['html']]),
40
            new TwigFunction('countArticlesImpressions', [$this, 'renderLinkImpressionCount'], ['is_safe' => ['html']]),
41
        ];
42
    }
43
44
    /**
45
     * @param Meta $meta
0 ignored issues
show
Bug introduced by
There is no parameter named $meta. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
46
     *
47
     * @return string|void
48
     */
49
    public function renderLinkImpressionCount()
50
    {
51
        $jsTemplate = <<<'EOT'
52
<script type="text/javascript">
53
function isInCurrentViewport(el) {
54
    const rect = el.getBoundingClientRect();
55
56
    return (
57
        rect.top >= 0 &&
58
        rect.left >= 0 &&
59
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
60
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
61
    );
62
}
63
64
65
let arr = [], links = [], processedLinks = [], l = document.links;
66
const hostname = window.location.hostname;
67
var iterator = 0;
68
var breakpoint = 200;
69
70
var process = function process() {
71
  links = [];
72
  arr = [];
73
  // filter out section pages
74
  for(let i=0; i<l.length; i++) {
75
      const parts = l[i].pathname.split('/');
76
      if (parts.length > 2 && isInCurrentViewport(l[i]) && processedLinks.indexOf(l[i].href) === -1) {
77
          links.push(l[i]);
78
      }
79
  }
80
  // filter out links with data-article, add article id
81
  for(let i=0; i<links.length; i++) {
82
      const attr = links[i].dataset['article'];
83
      // if attribute not in array
84
      if(typeof attr !== 'undefined' && arr.indexOf(attr) === -1 && isInCurrentViewport(links[i]) && processedLinks.indexOf(links[i].href) === -1){
85
          arr.push(attr); 
86
          links.splice(i, 1);
87
      }
88
  }
89
  
90
  // filter out links different than current domain
91
  for(let i=0; i<links.length; i++){
92
      if(arr.indexOf(links[i].href) === -1 && links[i].href.indexOf(hostname) !== -1){
93
          arr.push(links[i].href);
94
      }
95
  }
96
97
  processedLinks = unique(processedLinks.concat(arr));
98
  
99
  if (arr.length > 0) {
100
      let xhr = new XMLHttpRequest();
101
      let read_date = new Date();
102
      let request_randomizer = "&" + read_date.getTime() + Math.random();
103
      xhr.open('POST', '/_swp_analytics?type=impression'+request_randomizer);
104
      xhr.setRequestHeader("Content-Type", "application/json");
105
      xhr.send(JSON.stringify(arr));
106
  }
107
}
108
109
var countImpressions = function countImpressions() {
110
    let scrollDown = document.body.scrollTop || document.documentElement.scrollTop;
111
    if (scrollDown >= breakpoint) {
112
       process();
113
       breakpoint += 200;
114
       iterator++;
115
    }
116
}
117
118
var unique = function unique(array) {
119
    let a = array.concat();
120
    for(let i=0; i<a.length; ++i) {
121
        for(let j=i+1; j<a.length; ++j) {
122
            if(a[i] === a[j])
123
                a.splice(j--, 1);
124
        }
125
    }
126
127
    return a;
128
}
129
130
window.onscroll = function() {countImpressions()};
131
process();
132
133
</script>
134
EOT;
135
136 View Code Duplication
        if (null !== $this->analyticsHost) {
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...
137
            $jsTemplate = str_replace('/_swp_analytics', $this->analyticsHost.'/_swp_analytics', $jsTemplate);
138
        }
139
140
        return $jsTemplate;
141
    }
142
143
    /**
144
     * @param Meta $meta
145
     *
146
     * @return string|void
147
     */
148
    public function renderPageViewCount(Meta $meta = null)
149
    {
150
        if (null === $meta) {
151
            return;
152
        }
153
154
        $jsTemplate = <<<'EOT'
155
<script type="text/javascript">
156
var xhr = new XMLHttpRequest();
157
var read_date = new Date();
158
var request_randomizer = "&" + read_date.getTime() + Math.random();
159
xhr.open('GET', '/_swp_analytics?articleId=%s'+request_randomizer+'&ref='+document.referrer);
160
xhr.send();
161
</script>
162
EOT;
163
        $article = $meta->getValues();
164
        if (!$article instanceof ArticleInterface) {
165
            return;
166
        }
167
168 View Code Duplication
        if (null !== $this->analyticsHost) {
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...
169
            $jsTemplate = str_replace('/_swp_analytics', $this->analyticsHost.'/_swp_analytics', $jsTemplate);
170
        }
171
172
        return sprintf($jsTemplate, $article->getId());
173
    }
174
}
175