├── .gitignore
├── Adapter
├── Geolocator
│ ├── GeolocatorAdapter.php
│ └── GeolocatorAdapterInterface.php
└── Storage
│ ├── StorageAdapter.php
│ └── StorageAdapterInterface.php
├── Builder
└── FileStatsBuilder.php
├── Command
├── AbstractCommand.php
├── StatsConverterCommand.php
└── ViewcounterCleanupCommand.php
├── Compute
└── StatsComputer.php
├── Counter
├── AbstractViewCounter.php
└── ViewCounter.php
├── DependencyInjection
├── Compiler
│ └── ViewcounterPass.php
├── Configuration.php
└── TchoulomViewCounterExtension.php
├── Document
└── Stats
│ └── MongoDB
│ ├── AuditTrait.php
│ ├── City.php
│ ├── Continent.php
│ ├── Country.php
│ ├── Day.php
│ ├── Hour.php
│ ├── Minute.php
│ ├── Month.php
│ ├── NumberTrait.php
│ ├── Page.php
│ ├── PageContinent.php
│ ├── PageCountry.php
│ ├── Region.php
│ ├── Second.php
│ ├── ViewTrait.php
│ ├── Week.php
│ └── Year.php
├── ETL
└── StatsConverter.php
├── Entity
├── ViewCounter.php
└── ViewCounterInterface.php
├── Exception
├── ExceptionInterface.php
├── IOException.php
├── IOExceptionInterface.php
└── RuntimeException.php
├── Finder
└── FileStatsFinder.php
├── Geolocation
├── City.php
├── Country.php
└── Region.php
├── LICENSE
├── Manager
├── CounterManager.php
└── StatsManager.php
├── Model
├── StatisticsNodeConfig.php
├── ViewCountable.php
├── ViewcounterConfig.php
└── ViewcounterNodeConfig.php
├── README.md
├── Repository
├── AbstractRepository.php
├── CounterRepository.php
├── DocumentRepositoryInterface.php
├── RepositoryInterface.php
└── Stats
│ └── MongoDB
│ ├── CityRepository.php
│ ├── ContinentRepository.php
│ ├── CountryRepository.php
│ ├── DayRepository.php
│ ├── HourRepository.php
│ ├── MinuteRepository.php
│ ├── MongoDBStatsRepository.php
│ ├── MonthRepository.php
│ ├── PageContinentRepository.php
│ ├── PageCountryRepository.php
│ ├── PageRepository.php
│ ├── RegionRepository.php
│ ├── SecondRepository.php
│ ├── WeekRepository.php
│ └── YearRepository.php
├── Resources
├── config
│ ├── command.yml
│ ├── geolocation.yml
│ ├── repository.yml
│ ├── statistics.yml
│ ├── storage.yml
│ └── viewcounter.yml
└── doc
│ ├── images
│ ├── geolocation-data-washington.png
│ ├── geolocation-data.png
│ ├── geolocation-view-date.png
│ ├── monthly-views-2018.png
│ ├── statistical-data-2018.png
│ └── statistical-data-first-week-january-2018.png
│ └── readme
│ ├── geolocation.md
│ ├── graph-google-charts.md
│ ├── installation.md
│ ├── statistics-computer.md
│ ├── statistics-finder.md
│ ├── tools-command-cleanup.md
│ ├── tools-command-stats-converter.md
│ └── usage-step-1-5.md
├── Statistics
├── Date.php
├── Day.php
├── Hour.php
├── HourTrait.php
├── Minute.php
├── MinuteTrait.php
├── Month.php
├── Page.php
├── Second.php
├── SecondTrait.php
├── ViewDateTrait.php
├── Week.php
└── Year.php
├── Storage
├── Database
│ └── MongoDB
│ │ ├── DocumentStorageInterface.php
│ │ └── MongoDBStorage.php
└── Filesystem
│ ├── FilesystemStorage.php
│ └── FilesystemStorageInterface.php
├── TchoulomViewCounterBundle.php
├── Tests
├── BaseTest.php
├── Counter
│ ├── AbstractViewCounterTest.php
│ └── ViewCounterTest.php
├── DependencyInjection
│ └── TchoulomViewCounterExtensionTest.php
└── Entity
│ └── ViewCounterTest.php
├── Util
├── Date.php
└── ReflectionExtractor.php
├── composer.json
└── phpunit.xml.dist
/.gitignore:
--------------------------------------------------------------------------------
1 | # IDE
2 | /.idea
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Adapter/Geolocator/GeolocatorAdapter.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Adapter\Geolocator;
16 |
17 | use Tchoulom\ViewCounterBundle\Exception\RuntimeException;
18 | use Tchoulom\ViewCounterBundle\Util\ReflectionExtractor;
19 |
20 | /**
21 | * Class GeolocatorAdapter
22 | */
23 | class GeolocatorAdapter implements GeolocatorAdapterInterface
24 | {
25 | /**
26 | * The given Geolocator service.
27 | * This service must implements the "GeolocatorAdapterInterface".
28 | *
29 | * @var GeolocatorAdapterInterface|null
30 | */
31 | protected $geolocator;
32 |
33 | /**
34 | * The criteria is not supported message.
35 | *
36 | * @var string
37 | */
38 | protected const GEOLOCATOR_NOT_SUPPORTED_MSG = '%s service must implement the "Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapterInterface".';
39 |
40 | /**
41 | * GeolocatorAdapter constructor.
42 | *
43 | * @param GeolocatorAdapterInterface|null $geolocator The given Geolocator service
44 | */
45 | public function __construct(?GeolocatorAdapterInterface $geolocator)
46 | {
47 | if (!$this->supports($geolocator)) {
48 | throw new RuntimeException(sprintf(self::GEOLOCATOR_NOT_SUPPORTED_MSG,
49 | ReflectionExtractor::getFullClassName($geolocator)));
50 | }
51 |
52 | $this->geolocator = $geolocator;
53 | }
54 |
55 | /**
56 | * Gets the Geolocator service.
57 | *
58 | * @return GeolocatorAdapterInterface|null The Geolocator service
59 | */
60 | public function getGeolocator(): ?GeolocatorAdapterInterface
61 | {
62 | return $this->geolocator;
63 | }
64 |
65 | /**
66 | * The record returned.
67 | *
68 | * @return mixed The record
69 | */
70 | public function getRecord()
71 | {
72 | return $this->geolocator->getRecord();
73 | }
74 |
75 | /**
76 | * Gets the continent name.
77 | *
78 | * @return string The continent name
79 | */
80 | public function getContinent(): string
81 | {
82 | return $this->geolocator->getContinent();
83 | }
84 |
85 | /**
86 | * Gets the country name.
87 | *
88 | * @return string The country name
89 | */
90 | public function getCountry(): string
91 | {
92 | return $this->geolocator->getCountry();
93 | }
94 |
95 | /**
96 | * Gets the region name.
97 | *
98 | * @return string The region name
99 | */
100 | public function getRegion(): string
101 | {
102 | return $this->geolocator->getRegion();
103 | }
104 |
105 | /**
106 | * Gets the city name.
107 | *
108 | * @return string The city name
109 | */
110 | public function getCity(): string
111 | {
112 | return $this->geolocator->getCity();
113 | }
114 |
115 | /**
116 | * Allows to check if we can geolocate.
117 | *
118 | * @return bool Can use the Geolocator service?
119 | */
120 | public function canGeolocate(): bool
121 | {
122 | return $this->getGeolocator() instanceof GeolocatorAdapterInterface;
123 | }
124 |
125 | /**
126 | * Checks if the given Geolocator service is supported.
127 | *
128 | * @param GeolocatorAdapterInterface|null $geolocator The given Geolocator service.
129 | *
130 | * @return bool Is the given Geolocator service supported?
131 | */
132 | public function supports(?GeolocatorAdapterInterface $geolocator): bool
133 | {
134 | // The case where the Geolocator geolocator_id is not used in the project.
135 | if (null === $geolocator) {
136 | return true;
137 | }
138 |
139 | return $geolocator instanceof GeolocatorAdapterInterface;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/Adapter/Geolocator/GeolocatorAdapterInterface.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Adapter\Storage;
16 |
17 | /**
18 | * Class StorageAdapter
19 | */
20 | class StorageAdapter implements StorageAdapterInterface
21 | {
22 | /**
23 | * @var StorageAdapterInterface The storage service.
24 | */
25 | protected $storer;
26 |
27 | /**
28 | * StorageAdapter constructor.
29 | *
30 | * @param StorageAdapterInterface $storer The storage service.
31 | */
32 | public function __construct(StorageAdapterInterface $storer)
33 | {
34 | $this->storer = $storer;
35 | }
36 |
37 | /**
38 | * Saves the statistics.
39 | *
40 | * @param $stats
41 | */
42 | public function save($stats)
43 | {
44 | $this->storer->save($stats);
45 | }
46 |
47 | /**
48 | * Loads the contents.
49 | *
50 | * @return mixed
51 | */
52 | public function loadContents()
53 | {
54 | return $this->storer->loadContents();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Adapter/Storage/StorageAdapterInterface.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Adapter\Storage;
16 |
17 |
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 | use Tchoulom\ViewCounterBundle\Model\ViewCountable;
20 |
21 | /**
22 | * Interface StorageAdapterInterface
23 | *
24 | * @package Tchoulom\ViewCounterBundle\Adapter\Storage
25 | */
26 | interface StorageAdapterInterface
27 | {
28 | /**
29 | * Saves the statistics.
30 | *
31 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
32 | */
33 | public function save(ViewCounterInterface $viewcounter);
34 | }
35 |
--------------------------------------------------------------------------------
/Builder/FileStatsBuilder.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Builder;
16 |
17 | use Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapterInterface;
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 | use Tchoulom\ViewCounterBundle\Model\ViewCountable;
20 | use Tchoulom\ViewCounterBundle\Statistics\Page;
21 | use Tchoulom\ViewCounterBundle\Util\ReflectionExtractor;
22 |
23 | /**
24 | * Class FileStatsBuilder
25 | *
26 | * Builds the file statistics.
27 | */
28 | class FileStatsBuilder
29 | {
30 | /**
31 | * The contents.
32 | *
33 | * @var array
34 | */
35 | protected $contents;
36 |
37 | /**
38 | * The given class.
39 | *
40 | * @var string
41 | */
42 | protected $class;
43 |
44 | /**
45 | * The page.
46 | *
47 | * @var Page
48 | */
49 | protected $page;
50 |
51 | /**
52 | * The stats.
53 | *
54 | * @var array
55 | */
56 | protected $stats = [];
57 |
58 | /**
59 | * The Geolocator.
60 | *
61 | * @var GeolocatorAdapterInterface
62 | */
63 | protected $geolocator;
64 |
65 | /**
66 | * FileStatsBuilder constructor.
67 | *
68 | * @param GeolocatorAdapterInterface $geolocator
69 | */
70 | public function __construct(GeolocatorAdapterInterface $geolocator)
71 | {
72 | $this->geolocator = $geolocator;
73 | }
74 |
75 | /**
76 | * Gets the contents.
77 | *
78 | * @return array
79 | */
80 | public function getContents(): array
81 | {
82 | return $this->contents;
83 | }
84 |
85 | /**
86 | * Sets the contents.
87 | *
88 | * @param array $contents
89 | *
90 | * @return self
91 | */
92 | public function setContents(array $contents): self
93 | {
94 | $this->contents = $contents;
95 |
96 | return $this;
97 | }
98 |
99 | /**
100 | * Gets the class name.
101 | *
102 | * @return string
103 | */
104 | public function getClass()
105 | {
106 | return $this->class;
107 | }
108 |
109 | /**
110 | * Sets the class name.
111 | *
112 | * @param string $class
113 | *
114 | * @return self
115 | */
116 | public function setClass(string $class): self
117 | {
118 | $this->class = $class;
119 |
120 | return $this;
121 | }
122 |
123 | /**
124 | * Gets the page.
125 | *
126 | * @return Page
127 | */
128 | public function getPage(): Page
129 | {
130 | return $this->page;
131 | }
132 |
133 | /**
134 | * Sets the page.
135 | *
136 | * @param Page $page
137 | *
138 | * @return self
139 | */
140 | public function setPage(Page $page): self
141 | {
142 | $this->page = $page;
143 |
144 | return $this;
145 | }
146 |
147 | /**
148 | * Gets the stats.
149 | *
150 | * @return array
151 | */
152 | public function getStats(): array
153 | {
154 | return $this->stats;
155 | }
156 |
157 | /**
158 | * Sets the stats.
159 | *
160 | * @param array $stats
161 | *
162 | * @return self
163 | */
164 | public function setStats(array $stats): self
165 | {
166 | $this->stats = $stats;
167 |
168 | return $this;
169 | }
170 |
171 | /**
172 | * Builds the stats.
173 | *
174 | * @param array $contents The contents.
175 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
176 | *
177 | * @return self
178 | */
179 | public function build(array $contents, ViewCounterInterface $viewcounter): self
180 | {
181 | $page = $viewcounter->getPage();
182 | $this->contents = $contents;
183 | $this->class = ReflectionExtractor::getClassNamePluralized($page);
184 | $this->stats = $this->buildPage($page, $viewcounter);
185 |
186 | return $this;
187 | }
188 |
189 | /**
190 | * Builds the page.
191 | *
192 | * @param ViewCountable $pageRef The page ref.
193 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
194 | *
195 | * @return array
196 | */
197 | public function buildPage(ViewCountable $pageRef, ViewCounterInterface $viewcounter): array
198 | {
199 | $pageId = $pageRef->getId();
200 |
201 | if (isset($this->contents[$this->class][$pageId])) {
202 | $page = $this->contents[$this->class][$pageId];
203 | } else {
204 | $page = new Page($pageId);
205 | }
206 |
207 | $page->buildYear($viewcounter);
208 | if ($this->geolocator->canGeolocate()) {
209 | $page->buildCountry($this->geolocator, $viewcounter);
210 | }
211 |
212 | $this->contents[$this->class][$pageId] = $page;
213 | $this->page = $page;
214 |
215 | return $this->contents;
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/Command/ViewcounterCleanupCommand.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Command;
16 |
17 | use Symfony\Component\Console\Input\InputArgument;
18 | use Symfony\Component\Console\Input\InputOption;
19 |
20 | /**
21 | * The Viewcounter cleanup Command.
22 | *
23 | * Class CleanupViewcounterCommand
24 | */
25 | class ViewcounterCleanupCommand extends AbstractCommand
26 | {
27 | /**
28 | * @var string confirmation before cleanup.
29 | */
30 | protected const CLEANUP_CONFIRMED = 'yes';
31 |
32 | /**
33 | * @var bool determines if the given value is correct
34 | */
35 | protected $check = true;
36 |
37 | /**
38 | * @var string The cleanup message.
39 | */
40 | protected const CLEANUP_MSG = 'Cleanup the viewcounter data';
41 |
42 | /**
43 | * @var string Deleting viewcounter message.
44 | */
45 | protected const DELETING_VIEWCOUNTER_DATA_MSG = 'Deleting viewcounter data...';
46 |
47 | /**
48 | * {@inheritdoc}
49 | */
50 | protected function configure()
51 | {
52 | $this
53 | ->setName('tchoulom:viewcounter:cleanup')
54 | ->setDescription(
55 | 'Deletes viewcounter data from the database according to the given criteria.'
56 | )
57 | ->setDefinition(array(
58 | new InputOption(
59 | 'min', null, InputOption::VALUE_OPTIONAL,
60 | "The option 'min' allows to remove viewcounters entities where view date greater than or equals the given value (Example: 1s).
61 | If only this option is set, then the viewcounters records meeting this criteria will be deleted.
62 | "
63 | ),
64 | new InputOption(
65 | 'max', null, InputOption::VALUE_OPTIONAL,
66 | "The option 'max' allows to remove viewcounters entities where view date less than or equals the given value (Example: 7m).
67 | If only this option is set, then the viewcounters records meeting this criteria will be deleted.
68 | "
69 | ),
70 | new InputOption(
71 | self::AUTO_APPROVE, null, InputOption::VALUE_OPTIONAL,
72 | "The argument 'auto-approve' allows interactive questions to be approved automatically.
73 | If the 'auto-approve' option is equal to true, interactive questions will be automatically approved.
74 | If the 'auto-approve' option is equal to false, interactive questions will not be automatically approved.
75 | By default the value of the 'auto-approve' option is equal to false.
76 | "
77 | ),
78 | ))
79 | ->setHelp('
80 | bin/console tchoulom:viewcounter:cleanup --min=3y
81 |
82 | Deletes viewcounter data from the database according to the given criteria.
83 |
84 | Examples of date interval:
85 |
86 | "s" => "second"
87 | "m" => "minute"
88 | "h" => "hour"
89 | "d" => "day"
90 | "w" => "week"
91 | "M" => "month"
92 | "y" => "year"
93 |
94 | bin/console tchoulom:viewcounter:cleanup --auto-approve=true
95 |
96 |
97 | ' . self::SEE_DOCUMENTATION_MSG . ''
98 | );
99 | }
100 |
101 | /**
102 | * Executes the cleanup Command.
103 | *
104 | * @return int Does the command end with success or failure?
105 | *
106 | * @throws \Exception
107 | */
108 | protected function doExecute(): int
109 | {
110 | return $this->cleanup();
111 | }
112 |
113 | /**
114 | * Handles cleanup viewcounter data.
115 | *
116 | * @return int Does the command end with success or failure?
117 | *
118 | * @throws \Exception
119 | */
120 | protected function cleanup(): int
121 | {
122 | $this->io->title(self::CLEANUP_MSG);
123 |
124 | $min = $this->input->getOption('min');
125 | $max = $this->input->getOption('max');
126 |
127 | if (null !== $min && false === $this->checkDuration($min)) {
128 | $this->io->error(sprintf(self::CRITERIA_NOT_SUPPORTED_MSG, "'$min'"));
129 | $this->check = false;
130 | }
131 | if (null !== $max && false === $this->checkDuration($max)) {
132 | $this->io->error(sprintf(self::CRITERIA_NOT_SUPPORTED_MSG, "'$max'"));
133 | $this->check = false;
134 | }
135 |
136 | if (false === $this->check) {
137 | $this->io->writeln('');
138 | $this->io->note(self::SEE_DOCUMENTATION_MSG);
139 | $this->io->writeln('');
140 | $this->io->comment(self::NO_CHANGE_MADE_MSG);
141 |
142 | return self::FAILURE;
143 | }
144 |
145 | $confirmCleanup = $this->tryAutoApprove(self::ASK_QUESTION_MSG);
146 |
147 | if (self::CLEANUP_CONFIRMED === $confirmCleanup) {
148 | $this->io->writeln(self::DELETING_VIEWCOUNTER_DATA_MSG);
149 |
150 | $min = (null === $min) ? $min : $this->subtractDuration($min);
151 | $max = (null === $max) ? $max : $this->subtractDuration($max);
152 |
153 | $rowsDeleted = $this->counterManager->cleanup($min, $max);
154 | $this->writeRowsDeletedResponse($rowsDeleted);
155 |
156 | return self::SUCCESS;
157 | } else {
158 | $this->io->writeln('' . self::NO_CHANGE_MADE_MSG . '');
159 |
160 | return self::SUCCESS;
161 | }
162 |
163 | $this->io->error(self::ERROR_OCCURRED_MSG);
164 | $this->io->writeln('' . self::NO_CHANGE_MADE_MSG . '');
165 |
166 | return self::FAILURE;
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/Compute/StatsComputer.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Compute;
16 |
17 | /**
18 | * Class StatsComputer
19 | */
20 | class StatsComputer
21 | {
22 | /**
23 | * Computes the min value of the statistics.
24 | *
25 | * @param array $stats
26 | *
27 | * @return array|mixed|null
28 | */
29 | public function computeMinValue(array $stats)
30 | {
31 | if (empty($stats)) {
32 | return null;
33 | }
34 |
35 | array_multisort(array_map(function ($element) {
36 | return $element[1];
37 | }, $stats), SORT_ASC, $stats);
38 |
39 | $minValues = [];
40 | $min = $stats[0];
41 | foreach ($stats as $statsPoint) {
42 | if ($statsPoint[1] > $min[1]) {
43 | break;
44 | }
45 |
46 | $minValues[] = $statsPoint;
47 | }
48 |
49 | if (count($minValues) == 1) {
50 | $minValues = $min;
51 | }
52 |
53 | return $minValues;
54 | }
55 |
56 | /**
57 | * Computes the max value of the statistics.
58 | *
59 | * @param array $stats
60 | *
61 | * @return array|mixed|null
62 | */
63 | public function computeMaxValue(array $stats)
64 | {
65 | if (empty($stats)) {
66 | return null;
67 | }
68 |
69 | array_multisort(array_map(function ($element) {
70 | return $element[1];
71 | }, $stats), SORT_DESC, $stats);
72 |
73 | $maxValues = [];
74 | $max = $stats[0];
75 | foreach ($stats as $statsPoint) {
76 | if ($statsPoint[1] < $max[1]) {
77 | break;
78 | }
79 |
80 | $maxValues[] = $statsPoint;
81 | }
82 |
83 | if (count($maxValues) == 1) {
84 | $maxValues = $max;
85 | }
86 |
87 | return $maxValues;
88 | }
89 |
90 | /**
91 | * Computes the average of the statistics.
92 | * The average is the sum of the values of the statistical series divided by the number of values.
93 | *
94 | * @param array $stats
95 | *
96 | * @return float|int|null
97 | */
98 | public function computeAverage(array $stats)
99 | {
100 | if (empty($stats)) {
101 | return null;
102 | }
103 |
104 | $statsValues = array_map(function ($statsPoint) {
105 | return $statsPoint[1];
106 | }, $stats);
107 |
108 | $average = array_sum($statsValues) / count($statsValues);
109 |
110 | return $average;
111 | }
112 |
113 | /**
114 | * Computes the range of the statistics.
115 | * The range is the difference between the highest number and the lowest number.
116 | *
117 | * @param array $stats
118 | *
119 | * @return mixed|null
120 | */
121 | public function computeRange(array $stats)
122 | {
123 | if (empty($stats)) {
124 | return null;
125 | }
126 |
127 | $statsValues = array_map(function ($statsPoint) {
128 | return $statsPoint[1];
129 | }, $stats);
130 |
131 | $max = max($statsValues);
132 | $min = min($statsValues);
133 | $range = $max - $min;
134 |
135 | return $range;
136 | }
137 |
138 | /**
139 | * Computes the mode of the statistics.
140 | * The mode is the number that is in the array the most times.
141 | *
142 | * @param array $stats
143 | *
144 | * @return mixed|null
145 | */
146 | public function computeMode(array $stats)
147 | {
148 | if (empty($stats)) {
149 | return null;
150 | }
151 |
152 | $statsValues = array_map(function ($statsPoint) {
153 | return $statsPoint[1];
154 | }, $stats);
155 |
156 | $statsValuesCount = array_count_values($statsValues);
157 | $mode = array_search(max($statsValuesCount), $statsValuesCount);
158 |
159 | return $mode;
160 | }
161 |
162 | /**
163 | * Computes the median of the statistics.
164 | * The median is the middle value after the numbers are sorted smallest to largest.
165 | *
166 | * @param array $stats
167 | *
168 | * @return float|int|null
169 | */
170 | public function computeMedian(array $stats)
171 | {
172 | if (empty($stats)) {
173 | return null;
174 | }
175 |
176 | $statsValues = array_map(function ($statsPoint) {
177 | return $statsPoint[1];
178 | }, $stats);
179 |
180 | sort($statsValues);
181 |
182 | $statsValuesCount = count($statsValues);
183 | $statsValuesMaxKey = $statsValuesCount - 1;
184 |
185 | if (0 == $statsValuesCount % 2) {
186 | $medianKey1 = $statsValuesMaxKey / 2;
187 | $medianKey2 = $medianKey1 + 1;
188 |
189 | $median1 = $statsValues[$medianKey1];
190 | $median2 = $statsValues[$medianKey2];
191 | $median = ($median1 + $median2) / 2;
192 | } else {
193 | $medianKey = $statsValuesMaxKey / 2;
194 | $median = $statsValues[$medianKey];
195 | }
196 |
197 | return $median;
198 | }
199 |
200 | /**
201 | * Count the number of values in the statistical series.
202 | *
203 | * @param array $stats
204 | *
205 | * @return int
206 | */
207 | public function count(array $stats)
208 | {
209 | return count($stats);
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/DependencyInjection/Compiler/ViewcounterPass.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\DependencyInjection\Compiler;
16 |
17 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
18 | use Symfony\Component\DependencyInjection\ContainerBuilder;
19 | use Symfony\Component\DependencyInjection\Definition;
20 | use Tchoulom\ViewCounterBundle\TchoulomViewCounterBundle;
21 |
22 | /**
23 | * Class ViewcounterPass.
24 | */
25 | class ViewcounterPass implements CompilerPassInterface
26 | {
27 | /**
28 | * @param ContainerBuilder $container
29 | */
30 | public function process(ContainerBuilder $container)
31 | {
32 | $configs = $container->getExtensionConfig('tchoulom_view_counter');
33 |
34 | $viewcounterNode = $configs[0]['view_counter'];
35 | $statsNode = $configs[0]['statistics'];
36 | $storageNode = $configs[0]['storage'] ?? null;
37 | $geolocationNode = $configs[0]['geolocation'] ?? null;
38 |
39 | $viewcounterNodeDefinition = $container->getDefinition('tchoulom.viewcounter_node_config');
40 | $statisticsNodeDefinition = $container->getDefinition('tchoulom.statistics_node_config');
41 |
42 | $viewcounterNodeDefinition->replaceArgument(0, $viewcounterNode);
43 | $statisticsNodeDefinition->replaceArgument(0, $statsNode);
44 |
45 | if (isset($storageNode['engine'])) {
46 | $storerDefinition = $this->getStorageEngineDefinition($container, $storageNode['engine']);
47 |
48 | $storageAdapterDefinition = $container->getDefinition('tchoulom.viewcounter.storage_adapter');
49 | $storageAdapterDefinition->replaceArgument(0, $storerDefinition);
50 |
51 | $statsConverterDefinition = $container->getDefinition('tchoulom.viewcounter.stats_converter');
52 | $statsConverterDefinition->replaceArgument(0, $storerDefinition);
53 |
54 | if (TchoulomViewCounterBundle::MONGODB_STORAGE_ENGINE_NAME === $storageNode['engine']) {
55 | $doctrineMongoDBODMDefinition = $container->getDefinition('doctrine_mongodb.odm.default_document_manager');
56 | $mongoDBStorageDefinition = $container->getDefinition('tchoulom.viewcounter.mongodb_storage');
57 | $mongoDBStorageDefinition->replaceArgument(0, $doctrineMongoDBODMDefinition);
58 | }
59 | }
60 |
61 | if (isset($geolocationNode['geolocator_id'])) {
62 | $geolocatorAdapterDefinition = $container->getDefinition('tchoulom.viewcounter.geolocator_adapter');
63 | $geolocatorDefinition = $container->getDefinition($geolocationNode['geolocator_id']);
64 | $geolocatorAdapterDefinition->replaceArgument(0, $geolocatorDefinition);
65 | }
66 | }
67 |
68 | /**
69 | * Gets the storage engine definition.
70 | *
71 | * @param ContainerBuilder $container The container.
72 | * @param string $storageEngine The storage engine.
73 | *
74 | * @return Definition
75 | */
76 | public function getStorageEngineDefinition(ContainerBuilder $container, string $storageEngine): Definition
77 | {
78 | if (in_array($storageEngine, ['filesystem', 'mongodb'])) {
79 | return $container->getDefinition('tchoulom.viewcounter.' . $storageEngine . '_storage');
80 | }
81 |
82 | return $container->getDefinition($storageEngine);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/DependencyInjection/Configuration.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\DependencyInjection;
16 |
17 | use Symfony\Component\Config\Definition\Builder\TreeBuilder;
18 | use Symfony\Component\Config\Definition\ConfigurationInterface;
19 | use Tchoulom\ViewCounterBundle\TchoulomViewCounterBundle;
20 |
21 | /**
22 | * This is the class that validates and merges configuration from your app/config files.
23 | *
24 | * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/configuration.html}
25 | */
26 | class Configuration implements ConfigurationInterface
27 | {
28 | /**
29 | * {@inheritdoc}
30 | */
31 | public function getConfigTreeBuilder(): TreeBuilder
32 | {
33 | $treeBuilder = new TreeBuilder('tchoulom_view_counter');
34 | $supportedInterval = implode(', ', TchoulomViewCounterBundle::SUPPORTED_STRATEGY);
35 |
36 | $treeBuilder->getRootNode()
37 | ->children()
38 | ->arrayNode('view_counter')
39 | ->isRequired()->info('Allows to define the Viewcounter information.')
40 | ->children()
41 | ->scalarNode('view_strategy')->defaultValue('daily_view')->info('Defines the view strategy.')
42 | ->validate()
43 | ->ifNotInArray(TchoulomViewCounterBundle::SUPPORTED_STRATEGY)
44 | ->thenInvalid('Invalid view strategy name %s. You must choose one of the following values: '. $supportedInterval)
45 | ->end()
46 | ->end()
47 | ->end()
48 | ->end()
49 | ->arrayNode('statistics')
50 | ->children()
51 | ->booleanNode('enabled')->isRequired()->defaultValue(false)->info('Defines whether to use statistics.')->end()
52 | ->scalarNode('stats_file_name')->isRequired()->info('Defines the name of the statistics file.')->end()
53 | ->scalarNode('stats_file_extension')->isRequired()->info('Defines the extension of the statistics file.')->end()
54 | ->end()
55 | ->end()
56 | ->arrayNode('storage')
57 | ->children()
58 | ->scalarNode('engine')->info('Allows to define the Storage engine name.')->end()
59 | ->end()
60 | ->end()
61 | ->arrayNode('geolocation')
62 | ->children()
63 | ->scalarNode('geolocator_id')->info('Allows to define the Geolocation service identifier.')
64 | ->end()
65 | ->end()
66 | ->end()
67 | ->end();
68 |
69 | return $treeBuilder;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/DependencyInjection/TchoulomViewCounterExtension.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\DependencyInjection;
16 |
17 | use Symfony\Component\DependencyInjection\ContainerBuilder;
18 | use Symfony\Component\Config\FileLocator;
19 | use Symfony\Component\HttpKernel\DependencyInjection\Extension;
20 | use Symfony\Component\DependencyInjection\Loader;
21 |
22 | /**
23 | * This is the class that loads and manages your bundle configuration.
24 | *
25 | * @link http://symfony.com/doc/current/cookbook/bundles/extension.html
26 | */
27 | class TchoulomViewCounterExtension extends Extension
28 | {
29 | /**
30 | * {@inheritdoc}
31 | */
32 | public function load(array $configs, ContainerBuilder $container)
33 | {
34 | $configuration = new Configuration();
35 |
36 | $config = $this->processConfiguration($configuration, $configs);
37 |
38 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
39 |
40 | $loader->load('viewcounter.yml');
41 | $loader->load('storage.yml');
42 | $loader->load('statistics.yml');
43 | $loader->load('command.yml');
44 | $loader->load('geolocation.yml');
45 | $loader->load('repository.yml');
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/AuditTrait.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use DateTime;
18 | use DateTimeInterface;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | /**
22 | * Trait AuditTrait
23 | */
24 | trait AuditTrait
25 | {
26 | #[MongoDB\Field(type: 'date', name: 'created_at')]
27 | protected $createdAt;
28 |
29 | #[MongoDB\Field(type: 'date', name: 'updated_at')]
30 | protected $updatedAt;
31 |
32 | #[MongoDB\PrePersist]
33 | public function onPrePersist(): void
34 | {
35 | $this->createdAt = new DateTime();
36 | }
37 |
38 | #[MongoDB\PreUpdate]
39 | public function onPreUpdate(): void
40 | {
41 | $this->updatedAt = new DateTime();
42 | }
43 |
44 | /**
45 | * @return DateTimeInterface
46 | */
47 | public function getCreatedAt(): DateTimeInterface
48 | {
49 | return $this->createdAt;
50 | }
51 |
52 | /**
53 | * @return DateTimeInterface
54 | */
55 | public function getUpdatedAt(): DateTimeInterface
56 | {
57 | return $this->updatedAt;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/City.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * (c) Ernest TCHOULOM
11 | *
12 | * For the full copyright and license information, please view the LICENSE
13 | * file that was distributed with this source code.
14 | */
15 |
16 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
17 |
18 | use Doctrine\Common\Collections\ArrayCollection;
19 | use Doctrine\Common\Collections\Collection;
20 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
21 |
22 | #[MongoDB\Document(collection: 'city', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\CityRepository')]
23 | #[MongoDB\HasLifecycleCallbacks]
24 | class City
25 | {
26 | use ViewTrait;
27 | use AuditTrait;
28 |
29 | #[MongoDB\Id]
30 | private $id;
31 |
32 | #[MongoDB\Field(type: 'string')]
33 | protected $name;
34 |
35 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Region', name: 'region_id', inversedBy: 'cities')]
36 | protected $region;
37 |
38 | /**
39 | * Gets Id.
40 | *
41 | * @return int
42 | */
43 | public function getId(): int
44 | {
45 | return $this->id;
46 | }
47 |
48 | /**
49 | * Gets Name.
50 | *
51 | * @return string
52 | */
53 | public function getName(): string
54 | {
55 | return $this->name;
56 | }
57 |
58 | /**
59 | * Sets Name.
60 | *
61 | * @param string $name
62 | *
63 | * @return self
64 | */
65 | public function setName(string $name): self
66 | {
67 | $this->name = $name;
68 |
69 | return $this;
70 | }
71 |
72 | /**
73 | * Gets Region.
74 | *
75 | * @return Region
76 | */
77 | public function getRegion(): Region
78 | {
79 | return $this->region;
80 | }
81 |
82 | /**
83 | * Sets Region.
84 | *
85 | * @param Region $region
86 | *
87 | * @return self
88 | */
89 | public function setRegion(Region $region): self
90 | {
91 | $this->region = $region;
92 |
93 | return $this;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Continent.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'continent', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\ContinentRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Continent
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\Field(type: 'string')]
32 | protected $name;
33 |
34 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\PageContinent', mappedBy: 'continent')]
35 | protected $pageContinents;
36 |
37 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Country', mappedBy: 'continent', cascade: ['persist', 'remove'])]
38 | protected $countries;
39 |
40 | /**
41 | * Page constructor.
42 | */
43 | public function __construct()
44 | {
45 | $this->pageContinents = new ArrayCollection();
46 | $this->countries = new ArrayCollection();
47 | }
48 |
49 | /**
50 | * Gets Id.
51 | *
52 | * @return int
53 | */
54 | public function getId(): int
55 | {
56 | return $this->id;
57 | }
58 |
59 | /**
60 | * Gets Name.
61 | *
62 | * @return string
63 | */
64 | public function getName(): string
65 | {
66 | return $this->name;
67 | }
68 |
69 | /**
70 | * Sets Name.
71 | *
72 | * @param string $name
73 | *
74 | * @return self
75 | */
76 | public function setName(string $name): self
77 | {
78 | $this->name = $name;
79 |
80 | return $this;
81 | }
82 |
83 | /**
84 | * Gets PageContinents.
85 | *
86 | * @return Collection|Country[]
87 | */
88 | public function getPageContinents(): Collection
89 | {
90 | return $this->pageContinents;
91 | }
92 |
93 | /**
94 | * Add Page.
95 | *
96 | * @param Page $page The page.
97 | *
98 | * @return self
99 | */
100 | public function addPageContinent(Page $page): self
101 | {
102 | if (!$this->pageContinents->contains($page)) {
103 | $this->pageContinents[] = $page;
104 | // not needed for persistence, just keeping both sides in sync
105 | // $page->addPageContinent($this);
106 | }
107 |
108 | return $this;
109 | }
110 |
111 | /**
112 | * Remove Page.
113 | *
114 | * @param Page $page The page.
115 | *
116 | * @return self
117 | */
118 | public function removePageContinent(Page $page): self
119 | {
120 | if ($this->pageContinents->contains($page)) {
121 | $this->pageContinents->removeElement($page);
122 | // not needed for persistence, just keeping both sides in sync
123 | // $page->removePageContinent($this);
124 | }
125 |
126 | return $this;
127 | }
128 |
129 | /**
130 | * Gets Countries.
131 | *
132 | * @return Collection|Country[]
133 | */
134 | public function getCountries(): Collection
135 | {
136 | return $this->countries;
137 | }
138 |
139 | /**
140 | * Add Country.
141 | *
142 | * @param Country $country
143 | *
144 | * @return self
145 | */
146 | public function addCountry(Country $country): self
147 | {
148 | if (!$this->countries->contains($country)) {
149 | $this->countries[] = $country;
150 | $country->setContinent($this);
151 | }
152 |
153 | return $this;
154 | }
155 |
156 | /**
157 | * Remove Country.
158 | *
159 | * @param Country $country
160 | *
161 | * @return self
162 | */
163 | public function removeCountry(Country $country): self
164 | {
165 | if ($this->countries->contains($country)) {
166 | $this->countries->removeElement($country);
167 | }
168 |
169 | return $this;
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Country.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'country', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\CountryRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Country
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\Field(type: 'string')]
32 | protected $name;
33 |
34 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\PageCountry', mappedBy: 'country')]
35 | protected $pageCountries;
36 |
37 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Continent', name: 'continent_id', inversedBy: 'countries')]
38 | protected $continent;
39 |
40 | /**
41 | * Country constructor.
42 | */
43 | public function __construct()
44 | {
45 | $this->pageCountries = new ArrayCollection();
46 | }
47 |
48 | /**
49 | * Gets Id.
50 | *
51 | * @return int
52 | */
53 | public function getId(): int
54 | {
55 | return $this->id;
56 | }
57 |
58 | /**
59 | * Gets Name.
60 | *
61 | * @return string
62 | */
63 | public function getName(): string
64 | {
65 | return $this->name;
66 | }
67 |
68 | /**
69 | * Sets Name.
70 | *
71 | * @param string $name
72 | *
73 | * @return self
74 | */
75 | public function setName(string $name): self
76 | {
77 | $this->name = $name;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * Gets pageCountries.
84 | *
85 | * @return Collection|PageCountry[]
86 | */
87 | public function getPageCountries(): Collection
88 | {
89 | return $this->pageCountries;
90 | }
91 |
92 | /**
93 | * Add Page.
94 | *
95 | * @param Page $page The page.
96 | *
97 | * @return self
98 | */
99 | public function addPageCountry(Page $page): self
100 | {
101 | if (!$this->pageCountries->contains($page)) {
102 | $this->pageCountries[] = $page;
103 | // not needed for persistence, just keeping both sides in sync
104 | // $page->addPageCountry($this);
105 | }
106 |
107 | return $this;
108 | }
109 |
110 | /**
111 | * Remove Page.
112 | *
113 | * @param Page $page The page.
114 | *
115 | * @return self
116 | */
117 | public function removePageCountry(Page $page): self
118 | {
119 | if ($this->pageCountries->contains($page)) {
120 | $this->pageCountries->removeElement($page);
121 | // not needed for persistence, just keeping both sides in sync
122 | // $page->removePageCountry($this);
123 | }
124 |
125 | return $this;
126 | }
127 |
128 | /**
129 | * Gets Continent.
130 | *
131 | * @return Continent The continent.
132 | */
133 | public function getContinent(): Continent
134 | {
135 | return $this->continent;
136 | }
137 |
138 | /**
139 | * Sets the continent.
140 | *
141 | * @param Continent $continent The continent.
142 | *
143 | * @return self
144 | */
145 | public function setContinent(Continent $continent): self
146 | {
147 | $this->continent = $continent;
148 |
149 | return $this;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Day.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'day', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\DayRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Day
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\Field(type: 'string')]
32 | protected $name;
33 |
34 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Week', name: 'week_id', inversedBy: 'days')]
35 | protected $week;
36 |
37 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Hour', mappedBy: 'day', cascade: ['persist', 'remove'])]
38 | protected $hours;
39 |
40 | /**
41 | * Day constructor.
42 | */
43 | public function __construct()
44 | {
45 | $this->hours = new ArrayCollection();
46 | }
47 |
48 | /**
49 | * Gets Id.
50 | *
51 | * @return int
52 | */
53 | public function getId(): int
54 | {
55 | return $this->id;
56 | }
57 |
58 | /**
59 | * Gets Name.
60 | *
61 | * @return string
62 | */
63 | public function getName(): string
64 | {
65 | return $this->name;
66 | }
67 |
68 | /**
69 | * Sets Name.
70 | *
71 | * @param string $name
72 | *
73 | * @return self
74 | */
75 | public function setName(string $name): self
76 | {
77 | $this->name = $name;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * Gets Week.
84 | *
85 | * @return Week
86 | */
87 | public function getWeek(): Week
88 | {
89 | return $this->week;
90 | }
91 |
92 | /**
93 | * Sets Week.
94 | *
95 | * @param Week $week
96 | *
97 | * @return self
98 | */
99 | public function setWeek(Week $week): self
100 | {
101 | $this->week = $week;
102 |
103 | return $this;
104 | }
105 |
106 | /**
107 | * Gets Hours.
108 | *
109 | * @return Collection|Hour[]
110 | */
111 | public function getHours(): Collection
112 | {
113 | return $this->hours;
114 | }
115 |
116 | /**
117 | * Add Hour.
118 | *
119 | * @param Hour $hour
120 | *
121 | * @return self
122 | */
123 | public function addHour(Hour $hour): self
124 | {
125 | if (!$this->hours->contains($hour)) {
126 | $this->hours[] = $hour;
127 | $hour->setDay($this);
128 | }
129 |
130 | return $this;
131 | }
132 |
133 | /**
134 | * Remove Hour.
135 | *
136 | * @param Hour $hour
137 | *
138 | * @return self
139 | */
140 | public function removeHour(Hour $hour): self
141 | {
142 | if ($this->hours->contains($hour)) {
143 | $this->hours->removeElement($hour);
144 | }
145 |
146 | return $this;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Hour.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'hour', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\HourRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Hour
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\Field(type: 'string')]
32 | protected $name;
33 |
34 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Day', name: 'day_id', inversedBy: 'hours')]
35 | protected $day;
36 |
37 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Minute', mappedBy: 'hour', cascade: ['persist', 'remove'])]
38 | protected $minutes;
39 |
40 | /**
41 | * Hour constructor.
42 | */
43 | public function __construct()
44 | {
45 | $this->minutes = new ArrayCollection();
46 | }
47 |
48 | /**
49 | * Gets Id.
50 | *
51 | * @return int
52 | */
53 | public function getId(): int
54 | {
55 | return $this->id;
56 | }
57 |
58 | /**
59 | * Gets Name.
60 | *
61 | * @return string
62 | */
63 | public function getName(): string
64 | {
65 | return $this->name;
66 | }
67 |
68 | /**
69 | * Sets Name.
70 | *
71 | * @param string $name
72 | *
73 | * @return self
74 | */
75 | public function setName(string $name): self
76 | {
77 | $this->name = $name;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * Gets Day.
84 | *
85 | * @return Day
86 | */
87 | public function getDay(): Day
88 | {
89 | return $this->day;
90 | }
91 |
92 | /**
93 | * Sets Day.
94 | *
95 | * @param Day $day
96 | *
97 | * @return self
98 | */
99 | public function setDay(Day $day): self
100 | {
101 | $this->day = $day;
102 |
103 | return $this;
104 | }
105 |
106 | /**
107 | * Gets Minutes.
108 | *
109 | * @return Collection|Minute[]
110 | */
111 | public function getMinutes(): Collection
112 | {
113 | return $this->minutes;
114 | }
115 |
116 | /**
117 | * Add Minute.
118 | *
119 | * @param Minute $minute
120 | *
121 | * @return self
122 | */
123 | public function addMinute(Minute $minute): self
124 | {
125 | if (!$this->minutes->contains($minute)) {
126 | $this->minutes[] = $minute;
127 | $minute->setHour($this);
128 | }
129 |
130 | return $this;
131 | }
132 |
133 | /**
134 | * Remove Minute.
135 | *
136 | * @param Minute $minute
137 | *
138 | * @return self
139 | */
140 | public function removeMinute(Minute $minute): self
141 | {
142 | if ($this->minutes->contains($minute)) {
143 | $this->minutes->removeElement($minute);
144 | }
145 |
146 | return $this;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Minute.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'minute', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\MinuteRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Minute
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\Field(type: 'string')]
32 | protected $name;
33 |
34 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Hour', name: 'hour_id', inversedBy: 'minutes')]
35 | protected $hour;
36 |
37 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Second', mappedBy: 'minute', cascade: ['persist', 'remove'])]
38 | protected $seconds;
39 |
40 | /**
41 | * Minute constructor.
42 | */
43 | public function __construct()
44 | {
45 | $this->seconds = new ArrayCollection();
46 | }
47 |
48 | /**
49 | * Gets Id.
50 | *
51 | * @return int
52 | */
53 | public function getId(): int
54 | {
55 | return $this->id;
56 | }
57 |
58 | /**
59 | * Gets Name.
60 | *
61 | * @return string
62 | */
63 | public function getName(): string
64 | {
65 | return $this->name;
66 | }
67 |
68 | /**
69 | * Sets Name.
70 | *
71 | * @param string $name
72 | *
73 | * @return self
74 | */
75 | public function setName(string $name): self
76 | {
77 | $this->name = $name;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * Gets Hour.
84 | *
85 | * @return Hour
86 | */
87 | public function getHour(): Hour
88 | {
89 | return $this->hour;
90 | }
91 |
92 | /**
93 | * Sets Hour.
94 | *
95 | * @param Hour $hour
96 | *
97 | * @return self
98 | */
99 | public function setHour(Hour $hour): self
100 | {
101 | $this->hour = $hour;
102 |
103 | return $this;
104 | }
105 |
106 | /**
107 | * Gets Seconds.
108 | *
109 | * @return Collection|Second[]
110 | */
111 | public function getSeconds(): Collection
112 | {
113 | return $this->seconds;
114 | }
115 |
116 | /**
117 | * Add Second.
118 | *
119 | * @param Second $second
120 | *
121 | * @return self
122 | */
123 | public function addSecond(Second $second): self
124 | {
125 | if (!$this->seconds->contains($second)) {
126 | $this->seconds[] = $second;
127 | $second->setMinute($this);
128 | }
129 |
130 | return $this;
131 | }
132 |
133 | /**
134 | * Remove Second.
135 | *
136 | * @param Second $second
137 | *
138 | * @return self
139 | */
140 | public function removeSecond(Second $second): self
141 | {
142 | if ($this->seconds->contains($second)) {
143 | $this->seconds->removeElement($second);
144 | }
145 |
146 | return $this;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Month.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'month', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\MonthRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Month
24 | {
25 | use NumberTrait;
26 | use ViewTrait;
27 | use AuditTrait;
28 |
29 | #[MongoDB\Id]
30 | private $id;
31 |
32 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Year', name: 'year_id', inversedBy: 'months')]
33 | protected $year;
34 |
35 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Week', mappedBy: 'month', cascade: ['persist', 'remove'])]
36 | protected $weeks;
37 |
38 | /**
39 | * Month constructor.
40 | */
41 | public function __construct()
42 | {
43 | $this->weeks = new ArrayCollection();
44 | }
45 |
46 | /**
47 | * Gets Id.
48 | *
49 | * @return int
50 | */
51 | public function getId(): int
52 | {
53 | return $this->id;
54 | }
55 |
56 | /**
57 | * Gets Year.
58 | *
59 | * @return Year
60 | */
61 | public function getYear(): Year
62 | {
63 | return $this->year;
64 | }
65 |
66 | /**
67 | * Sets Year.
68 | *
69 | * @param Year $year
70 | *
71 | * @return self
72 | */
73 | public function setYear(Year $year): self
74 | {
75 | $this->year = $year;
76 |
77 | return $this;
78 | }
79 |
80 | /**
81 | * Gets Weeks.
82 | *
83 | * @return Collection|Week[]
84 | */
85 | public function getWeeks(): Collection
86 | {
87 | return $this->weeks;
88 | }
89 |
90 | /**
91 | * Add Week.
92 | *
93 | * @param Week $week
94 | *
95 | * @return self
96 | */
97 | public function addWeek(Week $week): self
98 | {
99 | if (!$this->weeks->contains($week)) {
100 | $this->weeks[] = $week;
101 | $week->setMonth($this);
102 | }
103 |
104 | return $this;
105 | }
106 |
107 | /**
108 | * Remove Week.
109 | *
110 | * @param Week $week
111 | *
112 | * @return self
113 | */
114 | public function removeWeek(Week $week): self
115 | {
116 | if ($this->weeks->contains($week)) {
117 | $this->weeks->removeElement($week);
118 | }
119 |
120 | return $this;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/NumberTrait.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
18 |
19 | /**
20 | * Trait NumberTrait
21 | */
22 | trait NumberTrait
23 | {
24 | #[MongoDB\Field(type: 'integer')]
25 | protected $number;
26 |
27 | /**
28 | * Gets Number.
29 | *
30 | * @return int
31 | */
32 | public function getNumber(): int
33 | {
34 | return $this->number;
35 | }
36 |
37 | /**
38 | * Sets Number.
39 | *
40 | * @param int $number
41 | *
42 | * @return self
43 | */
44 | public function setNumber(int $number): self
45 | {
46 | $this->number = $number;
47 |
48 | return $this;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/PageContinent.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'pageContinent', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\PageContinentRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class PageContinent
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Page', name: 'page_id', inversedBy: 'pageContinents', nullable: false)]
32 | protected $page;
33 |
34 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Continent', name: 'continent_id', inversedBy: 'pageContinents', nullable: false)]
35 | protected $continent;
36 |
37 | /**
38 | * Gets Id.
39 | *
40 | * @return int
41 | */
42 | public function getId(): int
43 | {
44 | return $this->id;
45 | }
46 |
47 | /**
48 | * Gets the page.
49 | *
50 | * @return Page The page.
51 | */
52 | public function getPage(): Page
53 | {
54 | return $this->page;
55 | }
56 |
57 | /**
58 | * Sets the page.
59 | *
60 | * @param Page $page The page.
61 | *
62 | * @return self
63 | */
64 | public function setPage(Page $page): self
65 | {
66 | $this->page = $page;
67 |
68 | return $this;
69 | }
70 |
71 | /**
72 | * Gets the continent.
73 | *
74 | * @return Continent The continent.
75 | */
76 | public function getContinent(): Continent
77 | {
78 | return $this->continent;
79 | }
80 |
81 | /**
82 | * Sets the continent.
83 | *
84 | * @param Continent $continent The continent.
85 | *
86 | * @return self
87 | */
88 | public function setContinent(Continent $continent): self
89 | {
90 | $this->continent = $continent;
91 |
92 | return $this;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/PageCountry.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'PageCountry', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\PageCountryRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class PageCountry
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Page', name: 'page_id', inversedBy: 'pageCountries', nullable: false)]
32 | protected $page;
33 |
34 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Country', name: 'country_id', inversedBy: 'pageCountries', nullable: false)]
35 | protected $country;
36 |
37 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Region', mappedBy: 'country', cascade: ['persist', 'remove'])]
38 | protected $regions;
39 |
40 | /**
41 | * Country constructor.
42 | */
43 | public function __construct()
44 | {
45 | $this->regions = new ArrayCollection();
46 | }
47 |
48 | /**
49 | * Gets Id.
50 | *
51 | * @return int
52 | */
53 | public function getId(): int
54 | {
55 | return $this->id;
56 | }
57 |
58 | /**
59 | * Gets the page.
60 | *
61 | * @return Page The page.
62 | */
63 | public function getPage(): Page
64 | {
65 | return $this->page;
66 | }
67 |
68 | /**
69 | * Sets the page.
70 | *
71 | * @param Page $page The page.
72 | *
73 | * @return self
74 | */
75 | public function setPage(Page $page): self
76 | {
77 | $this->page = $page;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * Gets the country.
84 | *
85 | * @return Country The country.
86 | */
87 | public function getCountry(): Country
88 | {
89 | return $this->country;
90 | }
91 |
92 | /**
93 | * Sets the country.
94 | *
95 | * @param Country $country The country.
96 | *
97 | * @return self
98 | */
99 | public function setCountry(Country $country): self
100 | {
101 | $this->country = $country;
102 |
103 | return $this;
104 | }
105 |
106 | /**
107 | * Gets Regions.
108 | *
109 | * @return Collection|Region[]
110 | */
111 | public function getRegions(): Collection
112 | {
113 | return $this->regions;
114 | }
115 |
116 | /**
117 | * Add Region.
118 | *
119 | * @param Region $region
120 | *
121 | * @return self
122 | */
123 | public function addRegion(Region $region): self
124 | {
125 | if (!$this->regions->contains($region)) {
126 | $this->regions[] = $region;
127 | $region->setCountry($this);
128 | }
129 |
130 | return $this;
131 | }
132 |
133 | /**
134 | * Remove Region.
135 | *
136 | * @param Region $region
137 | *
138 | * @return self
139 | */
140 | public function removeRegion(Region $region): self
141 | {
142 | if ($this->regions->contains($region)) {
143 | $this->regions->removeElement($region);
144 | }
145 |
146 | return $this;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Region.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'region', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\RegionRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Region
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\Field(type: 'string')]
32 | protected $name;
33 |
34 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\PageCountry', name: 'page_country_id', inversedBy: 'regions')]
35 | protected $pageCountry;
36 |
37 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\City', mappedBy: 'region', cascade: ['persist', 'remove'])]
38 | protected $cities;
39 |
40 | /**
41 | * Region constructor.
42 | */
43 | public function __construct()
44 | {
45 | $this->cities = new ArrayCollection();
46 | }
47 |
48 | /**
49 | * Gets Id.
50 | *
51 | * @return int
52 | */
53 | public function getId(): int
54 | {
55 | return $this->id;
56 | }
57 |
58 | /**
59 | * Gets Name.
60 | *
61 | * @return string
62 | */
63 | public function getName(): string
64 | {
65 | return $this->name;
66 | }
67 |
68 | /**
69 | * Sets Name.
70 | *
71 | * @param string $name
72 | *
73 | * @return self
74 | */
75 | public function setName(string $name): self
76 | {
77 | $this->name = $name;
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * Gets PageCountry.
84 | *
85 | * @return PageCountry
86 | */
87 | public function getPageCountry(): PageCountry
88 | {
89 | return $this->pageCountry;
90 | }
91 |
92 | /**
93 | * Sets PageCountry.
94 | *
95 | * @param PageCountry $pageCountry
96 | *
97 | * @return self
98 | */
99 | public function setPageCountry(PageCountry $pageCountry): self
100 | {
101 | $this->pageCountry = $pageCountry;
102 |
103 | return $this;
104 | }
105 |
106 | /**
107 | * Gets Cities.
108 | *
109 | * @return Collection|City[]
110 | */
111 | public function getCities(): Collection
112 | {
113 | return $this->cities;
114 | }
115 |
116 | /**
117 | * Add City.
118 | *
119 | * @param City $city
120 | *
121 | * @return self
122 | */
123 | public function addCity(City $city): self
124 | {
125 | if (!$this->cities->contains($city)) {
126 | $this->cities[] = $city;
127 | $city->setRegion($this);
128 | }
129 |
130 | return $this;
131 | }
132 |
133 | /**
134 | * Remove City.
135 | *
136 | * @param City $city
137 | *
138 | * @return self
139 | */
140 | public function removeCity(City $city): self
141 | {
142 | if ($this->cities->contains($city)) {
143 | $this->cities->removeElement($city);
144 | }
145 |
146 | return $this;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Second.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'second', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\SecondRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Second
24 | {
25 | use ViewTrait;
26 | use AuditTrait;
27 |
28 | #[MongoDB\Id]
29 | private $id;
30 |
31 | #[MongoDB\Field(type: 'string')]
32 | protected $name;
33 |
34 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Minute', name: 'minute_id', inversedBy: 'seconds')]
35 | protected $minute;
36 |
37 | /**
38 | * Gets Id.
39 | *
40 | * @return int
41 | */
42 | public function getId(): int
43 | {
44 | return $this->id;
45 | }
46 |
47 | /**
48 | * Gets Name.
49 | *
50 | * @return string
51 | */
52 | public function getName(): string
53 | {
54 | return $this->name;
55 | }
56 |
57 | /**
58 | * Sets Name.
59 | *
60 | * @param string $name
61 | *
62 | * @return self
63 | */
64 | public function setName(string $name): self
65 | {
66 | $this->name = $name;
67 |
68 | return $this;
69 | }
70 |
71 | /**
72 | * Gets Minute.
73 | *
74 | * @return Minute
75 | */
76 | public function getMinute(): Minute
77 | {
78 | return $this->minute;
79 | }
80 |
81 | /**
82 | * Sets Minute.
83 | *
84 | * @param Minute $minute
85 | *
86 | * @return self
87 | */
88 | public function setMinute(Minute $minute): self
89 | {
90 | $this->minute = $minute;
91 |
92 | return $this;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/ViewTrait.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
18 |
19 | /**
20 | * Trait ViewTrait
21 | *
22 | * @package Tchoulom\ViewCounterBundle\Document\Stats\MongoDB
23 | */
24 | trait ViewTrait
25 | {
26 | #[MongoDB\Field(type: 'integer')]
27 | protected $views = 0;
28 |
29 | /**
30 | * Gets Views.
31 | *
32 | * @return int
33 | */
34 | public function getViews(): int
35 | {
36 | return $this->views;
37 | }
38 |
39 | /**
40 | * Sets views.
41 | *
42 | * @param int $views
43 | *
44 | * @return self
45 | */
46 | public function setViews(int $views): self
47 | {
48 | $this->views = $views;
49 |
50 | return $this;
51 | }
52 |
53 | /**
54 | * Increase the views.
55 | *
56 | * @return self
57 | */
58 | public function increaseViews(): self
59 | {
60 | $this->setViews(++$this->views);
61 |
62 | return $this;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Week.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'week', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\WeekRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Week
24 | {
25 | use NumberTrait;
26 | use ViewTrait;
27 | use AuditTrait;
28 |
29 | #[MongoDB\Id]
30 | private $id;
31 |
32 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Month', name: 'month_id', inversedBy: 'weeks')]
33 | protected $month;
34 |
35 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Day', mappedBy: 'week', cascade: ['persist', 'remove'])]
36 | protected $days;
37 |
38 | /**
39 | * Week constructor.
40 | */
41 | public function __construct()
42 | {
43 | $this->days = new ArrayCollection();
44 | }
45 |
46 | /**
47 | * Gets Id.
48 | *
49 | * @return int
50 | */
51 | public function getId(): int
52 | {
53 | return $this->id;
54 | }
55 |
56 | /**
57 | * Gets Month.
58 | *
59 | * @return Month
60 | */
61 | public function getMonth(): Month
62 | {
63 | return $this->month;
64 | }
65 |
66 | /**
67 | * Sets Month.
68 | *
69 | * @param Month $month
70 | *
71 | * @return self
72 | */
73 | public function setMonth(Month $month): self
74 | {
75 | $this->month = $month;
76 |
77 | return $this;
78 | }
79 |
80 | /**
81 | * Gets Days.
82 | *
83 | * @return Collection|Day[]
84 | */
85 | public function getDays(): Collection
86 | {
87 | return $this->days;
88 | }
89 |
90 | /**
91 | * Add Day.
92 | *
93 | * @param Day $day
94 | *
95 | * @return self
96 | */
97 | public function addDay(Day $day): self
98 | {
99 | if (!$this->days->contains($day)) {
100 | $this->days[] = $day;
101 | $day->setWeek($this);
102 | }
103 |
104 | return $this;
105 | }
106 |
107 | /**
108 | * Remove Day.
109 | *
110 | * @param Day $day
111 | *
112 | * @return self
113 | */
114 | public function removeDay(Day $day): self
115 | {
116 | if ($this->days->contains($day)) {
117 | $this->days->removeElement($day);
118 | }
119 |
120 | return $this;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/Document/Stats/MongoDB/Year.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Document\Stats\MongoDB;
16 |
17 | use Doctrine\Common\Collections\ArrayCollection;
18 | use Doctrine\Common\Collections\Collection;
19 | use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
20 |
21 | #[MongoDB\Document(collection: 'year', repositoryClass: 'Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB\YearRepository')]
22 | #[MongoDB\HasLifecycleCallbacks]
23 | class Year
24 | {
25 | use NumberTrait;
26 | use ViewTrait;
27 | use AuditTrait;
28 |
29 | #[MongoDB\Id]
30 | private $id;
31 |
32 | #[MongoDB\ReferenceOne(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Page', name: 'page_id', inversedBy: 'years')]
33 | protected $page;
34 |
35 | #[MongoDb\ReferenceMany(targetDocument: 'Tchoulom\ViewCounterBundle\Document\Stats\MongoDB\Month', mappedBy: 'year', cascade: ['persist', 'remove'])]
36 | protected $months;
37 |
38 | /**
39 | * Year constructor.
40 | */
41 | public function __construct()
42 | {
43 | $this->months = new ArrayCollection();
44 | }
45 |
46 | /**
47 | * Gets Id.
48 | *
49 | * @return int
50 | */
51 | public function getId(): int
52 | {
53 | return $this->id;
54 | }
55 |
56 | /**
57 | * Gets Page.
58 | *
59 | * @return Page
60 | */
61 | public function getPage(): Page
62 | {
63 | return $this->page;
64 | }
65 |
66 | /**
67 | * Sets Page.
68 | *
69 | * @param Page $page
70 | *
71 | * @return self
72 | */
73 | public function setPage(Page $page): self
74 | {
75 | $this->page = $page;
76 |
77 | return $this;
78 | }
79 |
80 | /**
81 | * Gets Months.
82 | *
83 | * @return Collection|Month[]
84 | */
85 | public function getMonths(): Collection
86 | {
87 | return $this->months;
88 | }
89 |
90 | /**
91 | * Add Month.
92 | *
93 | * @param Month $month
94 | *
95 | * @return self
96 | */
97 | public function addMonth(Month $month): self
98 | {
99 | if (!$this->months->contains($month)) {
100 | $this->months[] = $month;
101 | $month->setYear($this);
102 | }
103 |
104 | return $this;
105 | }
106 |
107 | /**
108 | * Remove Month.
109 | *
110 | * @param Month $month
111 | *
112 | * @return self
113 | */
114 | public function removeMonth(Month $month): self
115 | {
116 | if ($this->months->contains($month)) {
117 | $this->months->removeElement($month);
118 | }
119 |
120 | return $this;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ETL/StatsConverter.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\ETL;
16 |
17 | use Tchoulom\ViewCounterBundle\Adapter\Storage\StorageAdapterInterface;
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 |
20 | /**
21 | * Class StatsConverter
22 | *
23 | * Converts ViewCounter entities to statistical data.
24 | */
25 | class StatsConverter
26 | {
27 | /**
28 | * The StorageAdapter service.
29 | *
30 | * @var StorageAdapterInterface
31 | */
32 | protected $storageAdapter;
33 |
34 | /**
35 | * StatsConverter constructor.
36 | *
37 | * @param StorageAdapterInterface $storageAdapter
38 | */
39 | public function __construct(StorageAdapterInterface $storageAdapter)
40 | {
41 | $this->storageAdapter = $storageAdapter;
42 | }
43 |
44 | /**
45 | * Converts ViewCounter entities to statistical data.
46 | *
47 | * @param ViewCounterInterface $viewcounter The viewcounter entity to be converted into statistical data.
48 | *
49 | * @throws \ReflectionException
50 | */
51 | public function convert(ViewCounterInterface $viewcounter)
52 | {
53 | $this->storageAdapter->save($viewcounter);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Entity/ViewCounter.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Entity;
16 |
17 | use DateTimeInterface;
18 | use Doctrine\ORM\Mapping as ORM;
19 | use Doctrine\ORM\Mapping\MappedSuperclass;
20 | use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
21 | use Tchoulom\ViewCounterBundle\Model\ViewCountable;
22 |
23 | /**
24 | * ViewCounter Entity
25 | *
26 | * @ORM\MappedSuperclass
27 | * @ORM\HasLifecycleCallbacks
28 | */
29 | #[ORM\MappedSuperclass]
30 | #[ORM\HasLifecycleCallbacks]
31 | abstract class ViewCounter implements ViewCounterInterface
32 | {
33 | /**
34 | * @ORM\Id
35 | * @ORM\Column(type="integer")
36 | * @ORM\GeneratedValue(strategy="AUTO")
37 | */
38 | #[ORM\Id]
39 | #[ORM\Column(type: 'integer')]
40 | #[ORM\GeneratedValue(strategy: 'AUTO')]
41 | protected $id;
42 |
43 | /**
44 | * @var text $ip
45 | *
46 | * @ORM\Column(name="ip", type="text", nullable=false)
47 | */
48 | #[ORM\Column(name: 'ip', type: 'text', nullable: false)]
49 | protected $ip;
50 |
51 | /**
52 | * @var DateTimeInterface
53 | *
54 | * @ORM\Column(name="view_date", type="datetime", nullable=false)
55 | */
56 | #[ORM\Column(name: 'view_date', type: 'datetime', nullable: false)]
57 | protected $viewDate;
58 |
59 | /**
60 | * The property name.
61 | *
62 | * @var string
63 | */
64 | protected $property;
65 |
66 | /**
67 | * Gets the ID
68 | *
69 | * @return integer
70 | */
71 | public function getId()
72 | {
73 | return $this->id;
74 | }
75 |
76 | /**
77 | * Gets the IP
78 | *
79 | * @return text
80 | */
81 | public function getIp()
82 | {
83 | return $this->ip;
84 | }
85 |
86 | /**
87 | * Sets viewDate
88 | *
89 | * @param $ip
90 | *
91 | * @return self
92 | */
93 | public function setIp($ip)
94 | {
95 | $this->ip = $ip;
96 |
97 | return $this;
98 | }
99 |
100 | /**
101 | * Gets viewDate
102 | *
103 | * @return DateTimeInterface
104 | */
105 | public function getViewDate()
106 | {
107 | return $this->viewDate;
108 | }
109 |
110 | /**
111 | * Sets viewDate
112 | *
113 | * @param DateTimeInterface $viewDate
114 | *
115 | * @return self
116 | */
117 | public function setViewDate(DateTimeInterface $viewDate)
118 | {
119 | $this->viewDate = $viewDate;
120 |
121 | return $this;
122 | }
123 |
124 | /**
125 | * Sets the property name.
126 | *
127 | * @param string $property
128 | *
129 | * @return self
130 | */
131 | public function setProperty(string $property): self
132 | {
133 | $this->property = $property;
134 |
135 | return $this;
136 | }
137 |
138 | /**
139 | * Gets the property name.
140 | *
141 | * @return string
142 | */
143 | public function getProperty(): string
144 | {
145 | return $this->property;
146 | }
147 |
148 | /**
149 | * Sets the page.
150 | *
151 | * @param ViewCountable $page
152 | * @param string $property
153 | *
154 | * @return self
155 | */
156 | public function setPage(ViewCountable $page): self
157 | {
158 | $property = $this->getProperty();
159 | $setPage = 'set' . ucfirst($property);
160 | $this->$setPage($page);
161 |
162 | return $this;
163 | }
164 |
165 | /**
166 | * Gets the page.
167 | *
168 | * @return ViewCountable|null
169 | */
170 | public function getPage(): ?ViewCountable
171 | {
172 | $property = $this->getProperty();
173 | $getPage = 'get' . ucfirst($property);
174 | $page = $this->$getPage();
175 |
176 | return $page;
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/Entity/ViewCounterInterface.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Exception;
16 |
17 | /**
18 | * Interface ExceptionInterface
19 | */
20 | interface ExceptionInterface
21 | {
22 | }
23 |
--------------------------------------------------------------------------------
/Exception/IOException.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Exception;
16 |
17 | /**
18 | * Class IOException
19 | */
20 | class IOException extends RuntimeException implements IOExceptionInterface
21 | {
22 | /**
23 | * The path
24 | */
25 | private $path;
26 |
27 | /**
28 | * IOException constructor.
29 | *
30 | * @param string $message
31 | * @param int $code
32 | * @param \Exception|null $previous
33 | * @param null $path
34 | */
35 | public function __construct($message, $code = 0, \Exception $previous = null, $path = null)
36 | {
37 | $this->path = $path;
38 |
39 | parent::__construct($message, $code, $previous);
40 | }
41 |
42 | /**
43 | * {@inheritdoc}
44 | */
45 | public function getPath()
46 | {
47 | return $this->path;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Exception/IOExceptionInterface.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Exception;
16 |
17 | /**
18 | * Interface IOExceptionInterface
19 | */
20 | interface IOExceptionInterface extends ExceptionInterface
21 | {
22 | /**
23 | * Returns the path for the exception.
24 | *
25 | * @return string The path for the exception
26 | */
27 | public function getPath();
28 | }
29 |
--------------------------------------------------------------------------------
/Exception/RuntimeException.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Exception;
16 |
17 | /**
18 | * Class RuntimeException
19 | */
20 | class RuntimeException extends \RuntimeException implements ExceptionInterface
21 | {
22 | }
23 |
--------------------------------------------------------------------------------
/Geolocation/City.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Geolocation;
16 |
17 | use Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapterInterface;
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 | use Tchoulom\ViewCounterBundle\Statistics\ViewDateTrait;
20 | use Tchoulom\ViewCounterBundle\Util\Date;
21 |
22 | /**
23 | * Class City
24 | */
25 | class City
26 | {
27 | /**
28 | * The city name.
29 | *
30 | * @var string
31 | */
32 | protected $name;
33 |
34 | /**
35 | * The total of views.
36 | *
37 | * @var int
38 | */
39 | protected $total = 0;
40 |
41 | /**
42 | * The viewcounter entity.
43 | *
44 | * @var ViewCounterInterface
45 | */
46 | protected $viewcounter;
47 |
48 | use ViewDateTrait;
49 |
50 | /**
51 | * Gets the city name.
52 | *
53 | * @return string
54 | */
55 | public function getName(): string
56 | {
57 | return $this->name;
58 | }
59 |
60 | /**
61 | * Sets the city name.
62 | *
63 | * @param string $name
64 | *
65 | * @return self
66 | */
67 | public function setName(string $name): self
68 | {
69 | $this->name = $name;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * Gets the total of views.
76 | *
77 | * @return int
78 | */
79 | public function getTotal(): int
80 | {
81 | return $this->total;
82 | }
83 |
84 | /**
85 | * Sets the total of views.
86 | *
87 | * @param int $total
88 | *
89 | * @return self
90 | */
91 | public function setTotal(int $total): self
92 | {
93 | $this->total = $total;
94 |
95 | return $this;
96 | }
97 |
98 | /**
99 | * Builds the city.
100 | *
101 | * @param GeolocatorAdapterInterface $geolocator The geolocator.
102 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
103 | *
104 | * @return self
105 | */
106 | public function build(GeolocatorAdapterInterface $geolocator, ViewCounterInterface $viewcounter): self
107 | {
108 | $this->total++;
109 | $this->viewcounter = $viewcounter;
110 | $this->buildViewDate();
111 | $this->name = $geolocator->getCity();
112 |
113 | return $this;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/Geolocation/Country.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Geolocation;
16 |
17 | use Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapterInterface;
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 | use Tchoulom\ViewCounterBundle\Statistics\ViewDateTrait;
20 | use Tchoulom\ViewCounterBundle\Util\Date;
21 | use Tchoulom\ViewCounterBundle\Statistics\Date as ViewDate;
22 |
23 | /**
24 | * Class Country
25 | */
26 | class Country
27 | {
28 | /**
29 | * The region name.
30 | *
31 | * @var string
32 | */
33 | protected $name;
34 |
35 | /**
36 | * The total of views.
37 | *
38 | * @var int
39 | */
40 | protected $total = 0;
41 |
42 | /**
43 | * The continent name.
44 | *
45 | * @var string
46 | */
47 | protected $continent;
48 |
49 | /**
50 | * The country regions.
51 | *
52 | * @var Region[]
53 | */
54 | protected $regions = [];
55 |
56 | /**
57 | * The viewcounter entity.
58 | *
59 | * @var ViewCounterInterface
60 | */
61 | protected $viewcounter;
62 |
63 | use ViewDateTrait;
64 |
65 | /**
66 | * Gets the country name.
67 | *
68 | * @return string
69 | */
70 | public function getName(): string
71 | {
72 | return $this->name;
73 | }
74 |
75 | /**
76 | * Sets the country name.
77 | *
78 | * @param string $name
79 | *
80 | * @return self
81 | */
82 | public function setName(string $name): self
83 | {
84 | $this->name = $name;
85 |
86 | return $this;
87 | }
88 |
89 | /**
90 | * Gets the total of views.
91 | *
92 | * @return int
93 | */
94 | public function getTotal(): int
95 | {
96 | return $this->total;
97 | }
98 |
99 | /**
100 | * Sets the total of views.
101 | *
102 | * @param int $total
103 | *
104 | * @return self
105 | */
106 | public function setTotal(int $total): self
107 | {
108 | $this->total = $total;
109 |
110 | return $this;
111 | }
112 |
113 | /**
114 | * Gets the continent name.
115 | *
116 | * @return string
117 | */
118 | public function getContinent(): string
119 | {
120 | return $this->continent;
121 | }
122 |
123 | /**
124 | * Sets the continent name.
125 | *
126 | * @param string $continent
127 | *
128 | * @return self
129 | */
130 | public function setContinent(string $continent): self
131 | {
132 | $this->continent = $continent;
133 |
134 | return $this;
135 | }
136 |
137 | /**
138 | * Gets the regions.
139 | *
140 | * @return Region[]
141 | */
142 | public function getRegions(): array
143 | {
144 | return $this->regions;
145 | }
146 |
147 | /**
148 | * Builds the country.
149 | *
150 | * @param GeolocatorAdapterInterface $geolocator The geolocator.
151 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
152 | *
153 | * @return self
154 | */
155 | public function build(GeolocatorAdapterInterface $geolocator, ViewCounterInterface $viewcounter): self
156 | {
157 | $this->total++;
158 | $this->name = $geolocator->getCountry();
159 | $this->viewcounter = $viewcounter;
160 | $this->buildViewDate();
161 | $this->continent = $geolocator->getContinent();
162 | $regionName = $geolocator->getRegion();
163 |
164 | if (isset($this->regions[$regionName])) {
165 | $region = $this->regions[$regionName];
166 | } else {
167 | $region = new Region();
168 | }
169 |
170 | $this->regions[$regionName] = $region->build($geolocator, $viewcounter);
171 |
172 | return $this;
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/Geolocation/Region.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Geolocation;
16 |
17 | use Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapterInterface;
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 | use Tchoulom\ViewCounterBundle\Statistics\ViewDateTrait;
20 | use Tchoulom\ViewCounterBundle\Util\Date;
21 |
22 | /**
23 | * Class Region
24 | */
25 | class Region
26 | {
27 | /**
28 | * The region name.
29 | *
30 | * @var string
31 | */
32 | protected $name;
33 |
34 | /**
35 | * The total of views.
36 | *
37 | * @var int
38 | */
39 | protected $total = 0;
40 |
41 | /**
42 | * The region cities.
43 | *
44 | * @var City[]
45 | */
46 | protected $cities = [];
47 |
48 | /**
49 | * The viewcounter entity.
50 | *
51 | * @var ViewCounterInterface
52 | */
53 | protected $viewcounter;
54 |
55 | use ViewDateTrait;
56 |
57 | /**
58 | * Gets the region name.
59 | *
60 | * @return string
61 | */
62 | public function getName(): string
63 | {
64 | return $this->name;
65 | }
66 |
67 | /**
68 | * Sets the region name.
69 | *
70 | * @param string $name
71 | *
72 | * @return self
73 | */
74 | public function setName(string $name): self
75 | {
76 | $this->name = $name;
77 |
78 | return $this;
79 | }
80 |
81 | /**
82 | * Gets the total of views.
83 | *
84 | * @return int
85 | */
86 | public function getTotal(): int
87 | {
88 | return $this->total;
89 | }
90 |
91 | /**
92 | * Sets the total of views.
93 | *
94 | * @param int $total
95 | *
96 | * @return self
97 | */
98 | public function setTotal(int $total): self
99 | {
100 | $this->total = $total;
101 |
102 | return $this;
103 | }
104 |
105 | /**
106 | * Gets the cities.
107 | *
108 | * @return City[]
109 | */
110 | public function getCities(): array
111 | {
112 | return $this->cities;
113 | }
114 |
115 | /**
116 | * Builds the region.
117 | *
118 | * @param GeolocatorAdapterInterface $geolocator The geolocator.
119 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
120 | *
121 | * @return self
122 | */
123 | public function build(GeolocatorAdapterInterface $geolocator, ViewCounterInterface $viewcounter): self
124 | {
125 | $this->total++;
126 | $this->viewcounter = $viewcounter;
127 | $this->buildViewDate();
128 | $this->name = $geolocator->getRegion();
129 | $cityName = $geolocator->getCity();
130 |
131 | if (isset($this->cities[$cityName])) {
132 | $city = $this->cities[$cityName];
133 | } else {
134 | $city = new City();
135 | }
136 |
137 | $this->cities[$cityName] = $city->build($geolocator, $viewcounter);
138 |
139 | return $this;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017-2018 Ernest TCHOULOM
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Manager/CounterManager.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Manager;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 | use Tchoulom\ViewCounterBundle\Repository\RepositoryInterface;
19 |
20 |
21 | /**
22 | * Class CounterManager
23 | */
24 | class CounterManager
25 | {
26 | /**
27 | * @var RepositoryInterface
28 | */
29 | protected $counterRepository;
30 |
31 | /**
32 | * @var RepositoryInterface
33 | */
34 | protected $metadata;
35 |
36 | /**
37 | * CounterManager constructor.
38 | * @param RepositoryInterface $counterRepository
39 | */
40 | public function __construct(RepositoryInterface $counterRepository)
41 | {
42 | $this->counterRepository = $counterRepository;
43 | }
44 |
45 | /**
46 | * Saves the object.
47 | *
48 | * @param $object
49 | */
50 | public function save($object)
51 | {
52 | $this->counterRepository->save($object);
53 | }
54 |
55 | /**
56 | * Finds One By.
57 | *
58 | * @param array $criteria
59 | * @param null $orderBy
60 | * @param null $limit
61 | * @param null $offset
62 | *
63 | * @return mixed
64 | */
65 | public function findOneBy(array $criteria, $orderBy = null, $limit = null, $offset = null)
66 | {
67 | $result = $this->counterRepository->findOneBy($criteria, $orderBy, $limit, $offset);
68 |
69 | return $result;
70 | }
71 |
72 | /**
73 | * Loads Metadata.
74 | *
75 | * @param $object
76 | *
77 | * @return $this
78 | */
79 | public function loadMetadata($object)
80 | {
81 | $this->metadata = $this->counterRepository->loadMetadata($object);
82 |
83 | return $this;
84 | }
85 |
86 | /**
87 | * Gets the property.
88 | *
89 | * @return mixed
90 | */
91 | public function getProperty()
92 | {
93 | return $this->counterRepository->getProperty();
94 | }
95 |
96 | public function getMappings()
97 | {
98 | return $this->counterRepository->getMappings();
99 | }
100 |
101 | /**
102 | * Gets the Class.
103 | *
104 | * @return mixed
105 | */
106 | public function getClass()
107 | {
108 | return $this->counterRepository->getClass();
109 | }
110 |
111 | /**
112 | * Cleanup the viewcounter data.
113 | *
114 | * @param \DateTimeInterface|null $min The min view date
115 | * @param \DateTimeInterface|null $max the max view date
116 | *
117 | * @return int The number of rows deleted.
118 | */
119 | public function cleanup(\DateTimeInterface $min = null, \DateTimeInterface $max = null): int
120 | {
121 | return $this->counterRepository->cleanup($min, $max);
122 | }
123 |
124 | /**
125 | * Loads the ViewCounter data.
126 | *
127 | * @return ViewCounterInterface[]
128 | */
129 | public function loadViewCounterData()
130 | {
131 | return $this->counterRepository->loadViewCounterData();
132 | }
133 |
134 | /**
135 | * Sets the property.
136 | *
137 | * @param ViewCounterInterface $viewcounter
138 | *
139 | * @return ViewCounterInterface
140 | */
141 | public function setProperty(ViewCounterInterface $viewcounter): ViewCounterInterface
142 | {
143 | $this->loadMetadata($viewcounter);
144 |
145 | foreach ($this->getMappings() as $mapping) {
146 | $property = $mapping['fieldName'];
147 | $viewcounter->setProperty($property);
148 | if ($viewcounter->getPage() !== null) {
149 | $viewcounter->setProperty($property);
150 | break;
151 | }
152 | }
153 |
154 | return $viewcounter;
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/Manager/StatsManager.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Manager;
16 |
17 | use Tchoulom\ViewCounterBundle\Adapter\Storage\StorageAdapterInterface;
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 | use \ReflectionException;
20 |
21 | /**
22 | * Class StatsManager is used to manage statistics.
23 | */
24 | class StatsManager
25 | {
26 | /**
27 | * The StorageAdapter service.
28 | *
29 | * @var StorageAdapterInterface
30 | */
31 | protected $storageAdapter;
32 |
33 | /**
34 | * Statistics constructor.
35 | *
36 | * @param StorageAdapterInterface $storageAdapter
37 | */
38 | public function __construct(StorageAdapterInterface $storageAdapter)
39 | {
40 | $this->storageAdapter = $storageAdapter;
41 | }
42 |
43 | /**
44 | * Registers the statistics of the page.
45 | *
46 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
47 | *
48 | * @throws ReflectionException
49 | */
50 | public function register(ViewCounterInterface $viewcounter): void
51 | {
52 | $this->storageAdapter->save($viewcounter);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Model/StatisticsNodeConfig.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Model;
16 |
17 | /**
18 | * Class StatisticsNodeConfig
19 | */
20 | class StatisticsNodeConfig
21 | {
22 | /**
23 | * @var bool Is statistics enabled?.
24 | */
25 | protected $isStatsEnabled;
26 |
27 | /**
28 | * @var ?string The name of the statistics file.
29 | */
30 | protected $statsFileName;
31 |
32 | /**
33 | * @var ?string The extension of the statistics file.
34 | */
35 | protected $statsFileExtension;
36 |
37 | /**
38 | * StatisticsNodeConfig constructor.
39 | *
40 | * @param array $statsNode
41 | */
42 | public function __construct(array $statsNode)
43 | {
44 | $this->isStatsEnabled = $statsNode['enabled'];
45 | $this->statsFileName = $statsNode['stats_file_name'];
46 | $this->statsFileExtension = $statsNode['stats_file_extension'];
47 | }
48 |
49 | /**
50 | * Gets the enabled boolean value.
51 | *
52 | * @return bool Is stats enabled ?
53 | */
54 | public function isStatsEnabled(): bool
55 | {
56 | return $this->isStatsEnabled;
57 | }
58 |
59 | /**
60 | * Sets the enabled value.
61 | *
62 | * @param bool $isStatsEnabled
63 | *
64 | * @return self
65 | */
66 | public function setIsStatsEnabled(bool $isStatsEnabled): self
67 | {
68 | $this->isStatsEnabled = $isStatsEnabled;
69 |
70 | return $this;
71 | }
72 |
73 | /**
74 | * Gets the stats file name.
75 | *
76 | * @return string|null
77 | */
78 | public function getStatsFileName(): ?string
79 | {
80 | return $this->statsFileName;
81 | }
82 |
83 | /**
84 | * Sets the stats file name.
85 | *
86 | * @param string $statsFileName
87 | *
88 | * @return self
89 | */
90 | public function setStatsFileName(string $statsFileName): self
91 | {
92 | $this->statsFileName = $statsFileName;
93 |
94 | return $this;
95 | }
96 |
97 | /**
98 | * Gets the stats file extension.
99 | *
100 | * @return string|null
101 | */
102 | public function getStatsFileExtension(): ?string
103 | {
104 | return $this->statsFileExtension;
105 | }
106 |
107 | /**
108 | * Sets the stats file extension.
109 | *
110 | * @param string $statsFileExtension
111 | *
112 | * @return self
113 | */
114 | public function setStatsFileExtension(string $statsFileExtension): self
115 | {
116 | $this->statsFileExtension = $statsFileExtension;
117 |
118 | return $this;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/Model/ViewCountable.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Model;
16 |
17 | /**
18 | * Interface ViewCountable
19 | */
20 | interface ViewCountable
21 | {
22 | /**
23 | * Gets id
24 | *
25 | * @return integer
26 | */
27 | public function getId();
28 |
29 | /**
30 | * Get $views
31 | *
32 | * @return integer
33 | */
34 | public function getViews();
35 |
36 | /**
37 | * Set $views
38 | *
39 | * @param integer $views
40 | *
41 | * @return $this
42 | */
43 | public function setViews($views);
44 | }
--------------------------------------------------------------------------------
/Model/ViewcounterConfig.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Model;
16 |
17 | /**
18 | * Class ViewcounterConfig
19 | */
20 | class ViewcounterConfig
21 | {
22 | /**
23 | * @var ViewcounterNodeConfig
24 | */
25 | protected $viewcounterNodeConfig;
26 |
27 | /**
28 | * @var StatisticsNodeConfig
29 | */
30 | protected $statisticsNodeConfig;
31 |
32 | /**
33 | * ViewcounterConfig constructor.
34 | *
35 | * @param ViewcounterNodeConfig $viewcounterNodeConfig
36 | * @param StatisticsNodeConfig $statisticsNodeConfig
37 | */
38 | public function __construct(ViewcounterNodeConfig $viewcounterNodeConfig, StatisticsNodeConfig $statisticsNodeConfig)
39 | {
40 | $this->viewcounterNodeConfig = $viewcounterNodeConfig;
41 | $this->statisticsNodeConfig = $statisticsNodeConfig;
42 | }
43 |
44 | /**
45 | * Gets the viewcounter node configuration.
46 | *
47 | * @return ViewcounterNodeConfig
48 | */
49 | public function getViewcounterNodeConfig()
50 | {
51 | return $this->viewcounterNodeConfig;
52 | }
53 |
54 | /**
55 | * Sets the viewcounter node configuration.
56 | *
57 | * @param ViewcounterNodeConfig $viewcounterNodeConfig
58 | *
59 | * @return ViewcounterConfig
60 | */
61 | public function setViewcounterNodeConfig($viewcounterNodeConfig)
62 | {
63 | $this->viewcounterNodeConfig = $viewcounterNodeConfig;
64 |
65 | return $this;
66 | }
67 |
68 | /**
69 | * Gets the statistics node configuration.
70 | *
71 | * @return StatisticsNodeConfig
72 | */
73 | public function getStatisticsNodeConfig()
74 | {
75 | return $this->statisticsNodeConfig;
76 | }
77 |
78 | /**
79 | * Sets the statistics node configuration.
80 | *
81 | * @param StatisticsNodeConfig $statisticsNodeConfig
82 | *
83 | * @return ViewcounterConfig
84 | */
85 | public function setStatisticsNodeConfig($statisticsNodeConfig)
86 | {
87 | $this->statisticsNodeConfig = $statisticsNodeConfig;
88 |
89 | return $this;
90 | }
91 | }
--------------------------------------------------------------------------------
/Model/ViewcounterNodeConfig.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Model;
16 |
17 | /**
18 | * Class ViewcounterNodeConfig
19 | */
20 | class ViewcounterNodeConfig
21 | {
22 | /**
23 | * @var mixed The view strategy
24 | */
25 | protected $viewStrategy;
26 |
27 | /**
28 | * ViewcounterNodeConfig constructor.
29 | *
30 | * @param array $viewcounterNode
31 | */
32 | public function __construct(array $viewcounterNode)
33 | {
34 | $this->viewStrategy = $viewcounterNode['view_strategy'];
35 | }
36 |
37 | /**
38 | * Gets the view strategy.
39 | *
40 | * @return mixed
41 | */
42 | public function getViewStrategy()
43 | {
44 | return $this->viewStrategy;
45 | }
46 |
47 | /**
48 | * Sets the view strategy.
49 | *
50 | * @param $viewStrategy
51 | *
52 | * @return $this
53 | */
54 | public function setViewStrategy($viewStrategy)
55 | {
56 | $this->viewStrategy = $viewStrategy;
57 |
58 | return $this;
59 | }
60 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | The View Counter Bundle
2 | ========================
3 |
4 | Welcome to the "**TchoulomViewCounterBundle**".
5 |
6 | This bundle is used to count the number of views of web pages (the viewership).
7 |
8 | This bundle can also be used to draw a graphical representation of statistical data of the web pages.
9 |
10 |
11 |
12 | **Table of contents**
13 |
14 | - [Features include](#features-include)
15 | - [Documentation](#documentation)
16 | - [Installation](Resources/doc/readme/installation.md#installation)
17 | - [Step 1: Download TchoulomViewCounterBundle using composer](Resources/doc/readme/installation.md#step-1-download-tchoulomviewcounterbundle-using-composer)
18 | - [Step 2: Enable the Bundle](Resources/doc/readme/installation.md#step-2-enable-the-bundle)
19 | - [Usage](Resources/doc/readme/usage-step-1-5.md#usage)
20 | - [Step 1: Interface and Property](Resources/doc/readme/usage-step-1-5.md#step-1-interface-and-property)
21 | - [Step 2: ViewCounter](Resources/doc/readme/usage-step-1-5.md#step-2-viewcounter)
22 | - [Step 3: Configuration](Resources/doc/readme/usage-step-1-5.md#step-3-configuration)
23 | - [The "view_counter"](Resources/doc/readme/usage-step-1-5.md#the-view_counter)
24 | - [The "statistics"](Resources/doc/readme/usage-step-1-5.md#the-statistics)
25 | - [Step 4: The Controller](Resources/doc/readme/usage-step-1-5.md#step-4-the-controller)
26 | - [Method 1](Resources/doc/readme/usage-step-1-5.md#method-1)
27 | - [Method 2](Resources/doc/readme/usage-step-1-5.md#method-2)
28 | - [Step 5: The View](Resources/doc/readme/usage-step-1-5.md#step-5-the-view)
29 | - [Step 6: The Geolocation](Resources/doc/readme/geolocation.md#step-6-the-geolocation)
30 | - [Step 7: Use of statistical data](Resources/doc/readme/statistics-finder.md#step-7-use-of-statistical-data)
31 | - [The *FileStatsFinder* service](Resources/doc/readme/statistics-finder.md#the-filestatsfinder-service)
32 | - [Get the *yearly* statistics](Resources/doc/readme/statistics-finder.md#get-the-yearly-statistics)
33 | - [Get the *monthly* statistics](Resources/doc/readme/statistics-finder.md#get-the-monthly-statistics)
34 | - [Get the *weekly* statistics](Resources/doc/readme/statistics-finder.md#get-the-weekly-statistics)
35 | - [Get the *daily* statistics](Resources/doc/readme/statistics-finder.md#get-the-daily-statistics)
36 | - [Get the *hourly* statistics](Resources/doc/readme/statistics-finder.md#get-the-hourly-statistics)
37 | - [Get the statistics *per minute*](Resources/doc/readme/statistics-finder.md#get-the-statistics-per-minute)
38 | - [Get the statistics *per second*](Resources/doc/readme/statistics-finder.md#get-the-statistics-per-second)
39 | - [Search for geolocation data](Resources/doc/readme/statistics-finder.md#search-for-geolocation-data)
40 | - [Build a graph with "Google Charts"](Resources/doc/readme/graph-google-charts.md#build-a-graph-with-google-charts)
41 | - [The *StatsComputer* service](Resources/doc/readme/statistics-computer.md#the-statscomputer-service)
42 | - [Calculates the *min value*](Resources/doc/readme/statistics-computer.md#calculates-the-min-value)
43 | - [Calculates the *max value*](Resources/doc/readme/statistics-computer.md#calculates-the-max-value)
44 | - [Calculates the *average*](Resources/doc/readme/statistics-computer.md#calculates-the-average)
45 | - [Calculates the *range*](Resources/doc/readme/statistics-computer.md#calculates-the-range)
46 | - [Calculates the *mode*](Resources/doc/readme/statistics-computer.md#calculates-the-mode)
47 | - [Calculates the *median*](Resources/doc/readme/statistics-computer.md#calculates-the-median)
48 | - [Count the number of values in the statistical series](Resources/doc/readme/statistics-computer.md#count-the-number-of-values-in-the-statistical-series)
49 | - [Tools](Resources/doc/readme/tools-command-cleanup.md#tools)
50 | - [Command](Resources/doc/readme/tools-command-cleanup.md#command)
51 | - [Cleanup ViewCounter data](Resources/doc/readme/tools-command-cleanup.md#cleanup-viewcounter-data)
52 | - [Converts ViewCounter entities to statistical data](Resources/doc/readme/tools-command-stats-converter.md#converts-viewcounter-entities-to-statistical-data)
53 | - [Original Credits](#original-credits)
54 | - [License](#license)
55 |
56 | # Features include
57 |
58 | - Viewcounter
59 | - Statistics
60 | - Geolocation
61 |
62 | # Documentation
63 |
64 | [The ViewCounter documentation](https://github.com/tchoulom/ViewCounterBundle)
65 |
66 | # Original Credits
67 |
68 | Created by Ernest TCHOULOM
69 |
70 | # License
71 |
72 | This bundle is released under the MIT license. See the complete license in the
73 | bundle:
74 |
75 | ```text
76 | LICENSE
77 | ```
78 |
79 | Enjoy!
80 |
--------------------------------------------------------------------------------
/Repository/AbstractRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository;
16 |
17 | use Doctrine\ORM\EntityManagerInterface;
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounter as BaseViewCounter;
19 |
20 | /**
21 | * Class AbstractRepository.
22 | */
23 | abstract class AbstractRepository implements RepositoryInterface
24 | {
25 | /**
26 | * The EntityManager
27 | *
28 | * @var EntityManagerInterface
29 | */
30 | protected $em;
31 |
32 | /**
33 | * The metadata.
34 | */
35 | protected $metadata;
36 |
37 | /**
38 | * AbstractPersister constructor.
39 | *
40 | * @param EntityManagerInterface $em
41 | */
42 | public function __construct(EntityManagerInterface $em)
43 | {
44 | $this->em = $em;
45 | }
46 |
47 | /**
48 | * Saves the object.
49 | *
50 | * @param $object
51 | *
52 | * @return mixed
53 | */
54 | abstract public function save($object);
55 |
56 | /**
57 | * Finds One By.
58 | *
59 | * @param array $criteria
60 | * @param null $orderBy
61 | * @param null $limit
62 | * @param null $offset
63 | *
64 | * @return mixed
65 | */
66 | abstract public function findOneBy(array $criteria, $orderBy = null, $limit = null, $offset = null);
67 |
68 | /**
69 | * Gets the EntityManager.
70 | *
71 | * @return mixed
72 | */
73 | public function getEntityManager()
74 | {
75 | return $this->em;
76 | }
77 |
78 | /**
79 | * Loads the Metadata.
80 | *
81 | * @param $object
82 | *
83 | * @return $this
84 | */
85 | public function loadMetadata($object)
86 | {
87 | $this->metadata = $this->getEntityManager()->getClassMetadata(get_class($object));
88 |
89 | return $this;
90 | }
91 |
92 | /**
93 | * Gets the Metadata.
94 | *
95 | * @return mixed
96 | */
97 | public function getMetadata()
98 | {
99 | return $this->metadata;
100 | }
101 |
102 | /**
103 | * Gets Mappings.
104 | *
105 | * @return mixed
106 | */
107 | public function getMappings()
108 | {
109 | return $this->getMetadata()->getAssociationMappings();
110 | }
111 |
112 | /**
113 | * Gets the property.
114 | *
115 | * @return mixed
116 | */
117 | public function getProperty()
118 | {
119 | return $this->getMappings()['viewCounters']['mappedBy'];
120 | }
121 |
122 | /**
123 | * Gets the class.
124 | *
125 | * @return mixed
126 | */
127 | public function getClass()
128 | {
129 | return $this->getMappings()['viewCounters']['targetEntity'];
130 | }
131 |
132 | /**
133 | * Gets the class Repository.
134 | *
135 | * @return mixed
136 | */
137 | public function getClassRepository()
138 | {
139 | $class = $this->getClass();
140 |
141 | return $this->getEntityManager()->getRepository($class);
142 | }
143 |
144 | /**
145 | * Loads the ViewCounter Class.
146 | *
147 | * @return string|null The viewcounter class
148 | */
149 | public function loadViewCounterClass(): ?string
150 | {
151 | $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
152 | foreach ($metadatas as $metadata) {
153 | if ($metadata->getReflectionClass()->getParentClass() instanceof \ReflectionClass
154 | && BaseViewCounter::class === $metadata->getReflectionClass()->getParentClass()->getName()
155 | ) {
156 | return $metadata->getReflectionClass()->getName();
157 | }
158 | }
159 |
160 | return null;
161 | }
162 |
163 | /**
164 | * Loads the entity identifier.
165 | *
166 | * @param string $entityName The entity name
167 | *
168 | * @return string|null The entity identifier
169 | */
170 | public function loadEntityIdentifier(string $entityName): ?string
171 | {
172 | $metadatas = $this->em->getMetadataFactory()->getAllMetadata();
173 | foreach ($metadatas as $metadata) {
174 | if ($metadata->getName() === $metadata->namespace . '\\' . ucfirst($entityName)) {
175 | if (isset($metadata->getIdentifier()[0])) {
176 | return $metadata->getIdentifier()[0];
177 | }
178 | }
179 | }
180 |
181 | return null;
182 | }
183 | }
--------------------------------------------------------------------------------
/Repository/CounterRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 | use Tchoulom\ViewCounterBundle\Exception\RuntimeException;
19 |
20 | /**
21 | * Class CounterRepository
22 | */
23 | class CounterRepository extends AbstractRepository
24 | {
25 | /**
26 | * @var string Viewcounter class not found message.
27 | */
28 | protected const VIEWCOUNTER_CLASS_NOT_FOUND_MSG = 'No ViewCounter class to process.';
29 |
30 | /**
31 | * Saves the object.
32 | *
33 | * @param $object
34 | *
35 | * @return mixed
36 | * @throws \Exception
37 | */
38 | public function save($object)
39 | {
40 | try {
41 | $this->em->persist($object);
42 | $this->em->flush();
43 | } catch (\Exception $e) {
44 | throw $e;
45 | }
46 |
47 | return $object;
48 | }
49 |
50 | /**
51 | * Finds One By.
52 | *
53 | * @param array $criteria
54 | * @param null $orderBy
55 | * @param null $limit
56 | * @param null $offset
57 | *
58 | * @return mixed
59 | */
60 | public function findOneBy(array $criteria, $orderBy = null, $limit = null, $offset = null)
61 | {
62 | $result = $this->getClassRepository()->findOneBy($criteria, $orderBy, $limit, $offset);
63 |
64 | return $result;
65 | }
66 |
67 | /**
68 | * Cleanup the viewcounter data.
69 | *
70 | * @param \DateTimeInterface|null $min
71 | * @param \DateTimeInterface|null $max
72 | *
73 | * @return int The number of rows deleted.
74 | */
75 | public function cleanup(\DateTimeInterface $min = null, \DateTimeInterface $max = null): int
76 | {
77 | $viewcounterClass = $this->loadViewCounterClass();
78 |
79 | if (null == $viewcounterClass) {
80 | throw new RuntimeException(self::VIEWCOUNTER_CLASS_NOT_FOUND_MSG);
81 | }
82 |
83 | $queryBuilder = $this->em->createQueryBuilder();
84 | $queryBuilder->delete($viewcounterClass, 'v');
85 | $where = false;
86 |
87 | if ($min instanceof \DateTimeInterface) {
88 | $andWhere = true === $where ? 'andWhere' : 'where';
89 | $where = true;
90 | $queryBuilder->$andWhere('v.viewDate >= :min')
91 | ->setParameter('min', $min);
92 | }
93 | if ($max instanceof \DateTimeInterface) {
94 | $andWhere = true === $where ? 'andWhere' : 'where';
95 | $queryBuilder->$andWhere('v.viewDate <= :max')
96 | ->setParameter('max', $max);
97 | }
98 |
99 | return $queryBuilder->getQuery()->execute();
100 | }
101 |
102 | /**
103 | * Loads the ViewCounter data.
104 | *
105 | * @return ViewCounterInterface[]
106 | */
107 | public function loadViewCounterData()
108 | {
109 | $viewcounterClass = $this->loadViewCounterClass();
110 |
111 | return $this->getEntityManager()->getRepository($viewcounterClass)->findAll();
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/Repository/DocumentRepositoryInterface.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository;
16 |
17 |
18 | /**
19 | * Interface DocumentRepositoryInterface
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository
22 | */
23 | interface DocumentRepositoryInterface
24 | {
25 | }
--------------------------------------------------------------------------------
/Repository/RepositoryInterface.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 | /**
18 | * Class CityRepository
19 | *
20 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
21 | */
22 | class CityRepository extends MongoDBStatsRepository
23 | {
24 | }
25 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/ContinentRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 |
18 | /**
19 | * Class ContinentRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class ContinentRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/CountryRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 |
18 | /**
19 | * Class CountryRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class CountryRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/DayRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 | /**
18 | * Class DayRepository
19 | *
20 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
21 | */
22 | class DayRepository extends MongoDBStatsRepository
23 | {
24 | }
25 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/HourRepository.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * (c) Ernest TCHOULOM
11 | *
12 | * For the full copyright and license information, please view the LICENSE
13 | * file that was distributed with this source code.
14 | */
15 |
16 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
17 |
18 | /**
19 | * Class HourRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class HourRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/MinuteRepository.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * (c) Ernest TCHOULOM
11 | *
12 | * For the full copyright and license information, please view the LICENSE
13 | * file that was distributed with this source code.
14 | */
15 |
16 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
17 |
18 | /**
19 | * Class MinuteRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class MinuteRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/MongoDBStatsRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 | use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
18 | use Tchoulom\ViewCounterBundle\Repository\DocumentRepositoryInterface;
19 |
20 | /**
21 | * Class MongoDBStatsRepository
22 | *
23 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
24 | */
25 | class MongoDBStatsRepository extends DocumentRepository implements DocumentRepositoryInterface
26 | {
27 | }
28 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/MonthRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 | /**
18 | * Class MonthRepository
19 | *
20 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
21 | */
22 | class MonthRepository extends MongoDBStatsRepository
23 | {
24 | }
25 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/PageContinentRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 |
18 | /**
19 | * Class PageContinentRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class PageContinentRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/PageCountryRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 |
18 | /**
19 | * Class PageCountryRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class PageCountryRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/PageRepository.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * (c) Ernest TCHOULOM
11 | *
12 | * For the full copyright and license information, please view the LICENSE
13 | * file that was distributed with this source code.
14 | */
15 |
16 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
17 |
18 | /**
19 | * Class PageRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class PageRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/RegionRepository.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
16 |
17 | /**
18 | * Class RegionRepository
19 | *
20 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
21 | */
22 | class RegionRepository extends MongoDBStatsRepository
23 | {
24 | }
25 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/SecondRepository.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * (c) Ernest TCHOULOM
11 | *
12 | * For the full copyright and license information, please view the LICENSE
13 | * file that was distributed with this source code.
14 | */
15 |
16 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
17 |
18 | /**
19 | * Class SecondRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class SecondRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/WeekRepository.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * (c) Ernest TCHOULOM
11 | *
12 | * For the full copyright and license information, please view the LICENSE
13 | * file that was distributed with this source code.
14 | */
15 |
16 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
17 |
18 | /**
19 | * Class WeekRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class WeekRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Repository/Stats/MongoDB/YearRepository.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * (c) Ernest TCHOULOM
11 | *
12 | * For the full copyright and license information, please view the LICENSE
13 | * file that was distributed with this source code.
14 | */
15 |
16 | namespace Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB;
17 |
18 | /**
19 | * Class YearRepository
20 | *
21 | * @package Tchoulom\ViewCounterBundle\Repository\Stats\MongoDB
22 | */
23 | class YearRepository extends MongoDBStatsRepository
24 | {
25 | }
26 |
--------------------------------------------------------------------------------
/Resources/config/command.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | tchoulom.viewcounter.command.base.class: Tchoulom\ViewCounterBundle\Command\AbstractCommand
3 | tchoulom.viewcounter.cleanup.command.class: Tchoulom\ViewCounterBundle\Command\ViewcounterCleanupCommand
4 | tchoulom.viewcounter.stats_converter.command.class: Tchoulom\ViewCounterBundle\Command\StatsConverterCommand
5 |
6 | services:
7 |
8 | # Abstract Command
9 | tchoulom.viewcounter.command.base:
10 | class: '%tchoulom.viewcounter.command.base.class%'
11 | abstract: true
12 | public: true
13 | arguments:
14 | - '@tchoulom.viewcounter.manager'
15 | - '@tchoulom.viewcounter.stats_manager'
16 |
17 | # CleanupViewcounterCommand
18 | tchoulom.viewcounter.cleanup.command:
19 | class: '%tchoulom.viewcounter.cleanup.command.class%'
20 | parent: tchoulom.viewcounter.command.base
21 | public: true
22 | tags:
23 | - { name: console.command }
24 |
25 | # StatsConverterCommand
26 | tchoulom.viewcounter.stats_converter.command:
27 | class: '%tchoulom.viewcounter.stats_converter.command.class%'
28 | parent: tchoulom.viewcounter.command.base
29 | public: true
30 | arguments:
31 | - '@tchoulom.viewcounter.stats_converter'
32 | tags:
33 | - { name: console.command }
34 |
35 | # aliases needed for services (Symfony version 4, 5)
36 | Tchoulom\ViewCounterBundle\Command\AbstractCommand: '@tchoulom.viewcounter.command.base'
37 | Tchoulom\ViewCounterBundle\Command\ViewcounterCleanupCommand: '@tchoulom.viewcounter.cleanup.command'
38 | Tchoulom\ViewCounterBundle\Command\StatsConverterCommand: '@tchoulom.viewcounter.stats_converter.command'
39 |
--------------------------------------------------------------------------------
/Resources/config/geolocation.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | tchoulom.viewcounter.geolocator_adapter.class: Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapter
3 |
4 | services:
5 |
6 | # GeoLocAdapter
7 | tchoulom.viewcounter.geolocator_adapter:
8 | class: '%tchoulom.viewcounter.geolocator_adapter.class%'
9 | public: true
10 | arguments: [~]
11 |
12 | # aliases needed for services (Symfony version 4, 5)
13 | Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapter: '@tchoulom.viewcounter.geolocator_adapter'
14 |
--------------------------------------------------------------------------------
/Resources/config/repository.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | tchoulom.viewcounter.repository.base.class: Tchoulom\ViewCounterBundle\Repository\AbstractRepository
3 | tchoulom.viewcounter.repository.class: Tchoulom\ViewCounterBundle\Repository\CounterRepository
4 |
5 | services:
6 | # ORM
7 | tchoulom.viewcounter.repository.base:
8 | class: '%tchoulom.viewcounter.repository.base.class%'
9 | abstract: true
10 | public: true
11 | arguments:
12 | - '@doctrine.orm.entity_manager'
13 |
14 | tchoulom.viewcounter.repository:
15 | class: '%tchoulom.viewcounter.repository.class%'
16 | public: true
17 | parent: tchoulom.viewcounter.repository.base
18 |
19 | # aliases needed for services (Symfony version 4, 5)
20 | Tchoulom\ViewCounterBundle\Repository\AbstractRepository: '@tchoulom.viewcounter.repository.base'
21 | Tchoulom\ViewCounterBundle\Repository\CounterRepository: '@tchoulom.viewcounter.repository'
22 |
--------------------------------------------------------------------------------
/Resources/config/statistics.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | tchoulom.viewcounter.stats_manager.class: Tchoulom\ViewCounterBundle\Manager\StatsManager
3 | tchoulom.viewcounter.file_stats_builder.class: Tchoulom\ViewCounterBundle\Builder\FileStatsBuilder
4 | tchoulom.viewcounter.file_stats_finder.class: Tchoulom\ViewCounterBundle\Finder\FileStatsFinder
5 | tchoulom.viewcounter.stats_computer.class: Tchoulom\ViewCounterBundle\Compute\StatsComputer
6 | tchoulom.viewcounter.stats_converter.class: Tchoulom\ViewCounterBundle\ETL\StatsConverter
7 |
8 | services:
9 | # Statistics
10 | tchoulom.viewcounter.stats_manager:
11 | class: '%tchoulom.viewcounter.stats_manager.class%'
12 | public: true
13 | arguments:
14 | - '@tchoulom.viewcounter.storage_adapter'
15 | - '@tchoulom.viewcounter.file_stats_builder'
16 |
17 | # FileStatsBuilder
18 | tchoulom.viewcounter.file_stats_builder:
19 | class: '%tchoulom.viewcounter.file_stats_builder.class%'
20 | public: true
21 | arguments: ['@tchoulom.viewcounter.geolocator_adapter']
22 |
23 | # FileStatsFinder
24 | tchoulom.viewcounter.file_stats_finder:
25 | class: '%tchoulom.viewcounter.file_stats_finder.class%'
26 | public: true
27 | arguments: ['@tchoulom.viewcounter.filesystem_storage']
28 |
29 | # StatsComputer
30 | tchoulom.viewcounter.stats_computer:
31 | class: '%tchoulom.viewcounter.stats_computer.class%'
32 | public: true
33 |
34 | # StatsConverter
35 | tchoulom.viewcounter.stats_converter:
36 | class: '%tchoulom.viewcounter.stats_converter.class%'
37 | public: true
38 | arguments:
39 | - '@tchoulom.viewcounter.filesystem_storage'
40 |
41 | # aliases needed for services (Symfony version 4, 5)
42 | Tchoulom\ViewCounterBundle\Manager\StatsManager: '@tchoulom.viewcounter.stats_manager'
43 | Tchoulom\ViewCounterBundle\Builder\FileStatsBuilder: '@tchoulom.viewcounter.file_stats_builder'
44 | Tchoulom\ViewCounterBundle\Finder\FileStatsFinder: '@tchoulom.viewcounter.file_stats_finder'
45 | Tchoulom\ViewCounterBundle\Compute\StatsComputer: '@tchoulom.viewcounter.stats_computer'
46 | Tchoulom\ViewCounterBundle\ETL\StatsConverter: '@tchoulom.viewcounter.stats_converter'
47 |
--------------------------------------------------------------------------------
/Resources/config/storage.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | tchoulom.viewcounter.storage_adapter.class: Tchoulom\ViewCounterBundle\Adapter\Storage\StorageAdapter
3 | tchoulom.viewcounter.filesystem_storage.class: Tchoulom\ViewCounterBundle\Storage\Filesystem\FilesystemStorage
4 | tchoulom.viewcounter.mongodb_storage.class: Tchoulom\ViewCounterBundle\Storage\Database\MongoDB\MongoDBStorage
5 |
6 | services:
7 | # Storage Adapter
8 | tchoulom.viewcounter.storage_adapter:
9 | class: '%tchoulom.viewcounter.storage_adapter.class%'
10 | public: true
11 | arguments:
12 | - '@tchoulom.viewcounter.filesystem_storage'
13 |
14 | # FilesystemStorage
15 | tchoulom.viewcounter.filesystem_storage:
16 | class: '%tchoulom.viewcounter.filesystem_storage.class%'
17 | public: true
18 | arguments:
19 | - '%kernel.project_dir%'
20 | - '@tchoulom.viewcounter_config'
21 | - '@tchoulom.viewcounter.file_stats_builder'
22 |
23 | # MongoDBStorage
24 | tchoulom.viewcounter.mongodb_storage:
25 | class: '%tchoulom.viewcounter.mongodb_storage.class%'
26 | public: true
27 | arguments:
28 | - ~
29 | - '@tchoulom.viewcounter.geolocator_adapter'
30 |
31 | # aliases needed for services (Symfony version 4, 5)
32 | Tchoulom\ViewCounterBundle\Adapter\FileStorageAdapter: '@tchoulom.viewcounter.storage_adapter'
33 | Tchoulom\ViewCounterBundle\Storage\Filesystem\FilesystemStorage: '@tchoulom.viewcounter.filesystem_storage'
34 | Tchoulom\ViewCounterBundle\Storage\Database\MongoDB\MongoDBStorage: '@tchoulom.viewcounter.mongodb_storage'
35 |
--------------------------------------------------------------------------------
/Resources/config/viewcounter.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | tchoulom.viewcounter.base.class: Tchoulom\ViewCounterBundle\Counter\AbstractViewCounter
3 | tchoulom.viewcounter.class: Tchoulom\ViewCounterBundle\Counter\ViewCounter
4 | tchoulom.viewcounter.manager.class: Tchoulom\ViewCounterBundle\Manager\CounterManager
5 | tchoulom.viewcounter_config.class: Tchoulom\ViewCounterBundle\Model\ViewcounterConfig
6 | tchoulom.viewcounter_node_config.class: Tchoulom\ViewCounterBundle\Model\ViewcounterNodeConfig
7 | tchoulom.statistics_node_config.class: Tchoulom\ViewCounterBundle\Model\StatisticsNodeConfig
8 |
9 | services:
10 | # Counter
11 | tchoulom.viewcounter.base:
12 | class: '%tchoulom.viewcounter.base.class%'
13 | abstract: true
14 | public: true
15 | arguments:
16 | - '@tchoulom.viewcounter.manager'
17 | - '@request_stack'
18 | - '@tchoulom.viewcounter_config'
19 | calls:
20 | - [setStatsManager, ['@tchoulom.viewcounter.stats_manager']]
21 |
22 | tchoulom.viewcounter:
23 | class: '%tchoulom.viewcounter.class%'
24 | public: true
25 | parent: tchoulom.viewcounter.base
26 |
27 | # Manager
28 | tchoulom.viewcounter.manager:
29 | class: '%tchoulom.viewcounter.manager.class%'
30 | public: true
31 | arguments:
32 | - '@tchoulom.viewcounter.repository'
33 |
34 | # Viewcounter configuration
35 | tchoulom.viewcounter_config:
36 | class: '%tchoulom.viewcounter_config.class%'
37 | public: true
38 | arguments:
39 | - '@tchoulom.viewcounter_node_config'
40 | - '@tchoulom.statistics_node_config'
41 |
42 | # Viewcounter node configuration
43 | tchoulom.viewcounter_node_config:
44 | class: '%tchoulom.viewcounter_node_config.class%'
45 | public: true
46 | arguments: [~]
47 |
48 | # Statistics node configuration
49 | tchoulom.statistics_node_config:
50 | class: '%tchoulom.statistics_node_config.class%'
51 | public: true
52 | arguments: [~]
53 |
54 | # aliases needed for services (Symfony version 4, 5)
55 | Tchoulom\ViewCounterBundle\Counter\AbstractViewCounter: '@tchoulom.viewcounter.base'
56 | Tchoulom\ViewCounterBundle\Counter\ViewCounter: '@tchoulom.viewcounter'
57 | Tchoulom\ViewCounterBundle\Manager\CounterManager: '@tchoulom.viewcounter.manager'
58 | Tchoulom\ViewCounterBundle\Model\ViewcounterConfig: '@tchoulom.viewcounter_config'
59 | Tchoulom\ViewCounterBundle\Model\ViewcounterNodeConfig: '@tchoulom.viewcounter_node_config'
60 | Tchoulom\ViewCounterBundle\Model\StatisticsNodeConfig: '@tchoulom.statistics_node_config'
61 |
--------------------------------------------------------------------------------
/Resources/doc/images/geolocation-data-washington.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tchoulom/ViewCounterBundle/3d8686988c4976de5f2e887aa7fa6c1f920297a7/Resources/doc/images/geolocation-data-washington.png
--------------------------------------------------------------------------------
/Resources/doc/images/geolocation-data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tchoulom/ViewCounterBundle/3d8686988c4976de5f2e887aa7fa6c1f920297a7/Resources/doc/images/geolocation-data.png
--------------------------------------------------------------------------------
/Resources/doc/images/geolocation-view-date.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tchoulom/ViewCounterBundle/3d8686988c4976de5f2e887aa7fa6c1f920297a7/Resources/doc/images/geolocation-view-date.png
--------------------------------------------------------------------------------
/Resources/doc/images/monthly-views-2018.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tchoulom/ViewCounterBundle/3d8686988c4976de5f2e887aa7fa6c1f920297a7/Resources/doc/images/monthly-views-2018.png
--------------------------------------------------------------------------------
/Resources/doc/images/statistical-data-2018.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tchoulom/ViewCounterBundle/3d8686988c4976de5f2e887aa7fa6c1f920297a7/Resources/doc/images/statistical-data-2018.png
--------------------------------------------------------------------------------
/Resources/doc/images/statistical-data-first-week-january-2018.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tchoulom/ViewCounterBundle/3d8686988c4976de5f2e887aa7fa6c1f920297a7/Resources/doc/images/statistical-data-first-week-january-2018.png
--------------------------------------------------------------------------------
/Resources/doc/readme/geolocation.md:
--------------------------------------------------------------------------------
1 | ## Step 6: The Geolocation
2 |
3 | Some bundles can be used to have a geolocation system in your project.
4 | These bundles usually use the ip address in order to geolocate the visitor of the web page.
5 |
6 | For the purposes of this documentation, we will use this bundle, for example:
7 |
8 | **gpslab/geoip2** : [https://github.com/gpslab/geoip2](https://github.com/gpslab/geoip2)
9 |
10 | You can read the documentation for installing and using this bundle if you want to use it.
11 |
12 | Otherwise, you can use another geolocation bundle according to your preferences.
13 |
14 | *****Create the "Geolocator" service that will allow you to manage geolocation data*****
15 |
16 | ```php
17 | request = $requestStack->getCurrentRequest();
52 | $this->reader = $reader;
53 | }
54 |
55 | /**
56 | * Gets the record.
57 | *
58 | * @return \GeoIp2\Model\City|mixed
59 | * @throws \GeoIp2\Exception\AddressNotFoundException
60 | * @throws \MaxMind\Db\Reader\InvalidDatabaseException
61 | */
62 | public function getRecord()
63 | {
64 | $clientIp = $this->request->getClientIp();
65 |
66 | return $this->reader->city($clientIp);
67 | }
68 |
69 | /**
70 | * Gets the continent.
71 | *
72 | * @return string
73 | * @throws \GeoIp2\Exception\AddressNotFoundException
74 | * @throws \MaxMind\Db\Reader\InvalidDatabaseException
75 | */
76 | public function getContinent(): string
77 | {
78 | return $this->getRecord()->continent->name;
79 | }
80 |
81 | /**
82 | * Gets the country.
83 | *
84 | * @return string
85 | * @throws \GeoIp2\Exception\AddressNotFoundException
86 | * @throws \MaxMind\Db\Reader\InvalidDatabaseException
87 | */
88 | public function getCountry(): string
89 | {
90 | return $this->getRecord()->country->name;
91 | }
92 |
93 | /**
94 | * Gets the region.
95 | *
96 | * @return string
97 | * @throws \GeoIp2\Exception\AddressNotFoundException
98 | * @throws \MaxMind\Db\Reader\InvalidDatabaseException
99 | */
100 | public function getRegion(): string
101 | {
102 | return $this->getRecord()->subdivisions[0]->names['en'];
103 | }
104 |
105 | /**
106 | * Gets the city.
107 | *
108 | * @return string
109 | * @throws \GeoIp2\Exception\AddressNotFoundException
110 | * @throws \MaxMind\Db\Reader\InvalidDatabaseException
111 | */
112 | public function getCity(): string
113 | {
114 | return $this->getRecord()->city->name;
115 | }
116 | }
117 | ```
118 |
119 | Your Geolocation service must implement the "Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapterInterface" interface.
120 |
121 | you are free to improve the above "Geolocator" service, in particular to verify the existence of geolocation data.
122 |
123 | You can go to this step for the use of geolocation data [Search for geolocation data](statistics-finder.md#search-for-geolocation-data).
124 |
--------------------------------------------------------------------------------
/Resources/doc/readme/graph-google-charts.md:
--------------------------------------------------------------------------------
1 | ### Build a graph with "Google Charts"
2 |
3 | You can now use these statistical data to build a graph, as shown in the following figure:
4 |
5 | **Statistics of monthly views in 2018**
6 |
7 |
8 |
9 | Also, you can build the graph on statistics of **daily view**, **hourly view**, **weekly view** and **yearly view** according to the data in the statistics file.
10 |
11 | You can find out about "Google Charts" [here](https://developers.google.com/chart/interactive/docs/gallery/linechart)
12 |
--------------------------------------------------------------------------------
/Resources/doc/readme/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | ## Step 1: Download TchoulomViewCounterBundle using composer
4 |
5 | You can install it via Composer:
6 |
7 | ``` bash
8 | $ php composer.phar update tchoulom/view-counter-bundle
9 | ```
10 | or
11 | ``` bash
12 | $ composer require tchoulom/view-counter-bundle
13 | ```
14 | or
15 | ``` bash
16 | $ composer req tchoulom/view-counter-bundle
17 | ```
18 |
19 | Check that it is recorded in the **composer.json** file
20 |
21 | ```js
22 | {
23 | "require": {
24 | ...
25 | "tchoulom/view-counter-bundle": "^5.0"
26 | ...
27 | }
28 | }
29 | ```
30 | ## Step 2: Enable the Bundle
31 |
32 | Edit the **appKernel.php** file
33 |
34 | ```php
35 | ...
36 | $bundles = array(
37 | ...
38 | new Tchoulom\ViewCounterBundle\TchoulomViewCounterBundle(),
39 | ...
40 | );
41 | ...
42 | ```
--------------------------------------------------------------------------------
/Resources/doc/readme/statistics-computer.md:
--------------------------------------------------------------------------------
1 | ### The *StatsComputer* service
2 |
3 | Use the **StatsComputer** service to calculate the min value, max value, average value, range value, mode value, median value and the number of occurrences of the statistics :
4 |
5 | First of all, get the stats computer service
6 |
7 | ```php
8 | $statsComputer = $this->get('tchoulom.viewcounter.stats_computer');
9 | ```
10 |
11 | The functions of the **statsComputer** service can take as argument the *$yearlyStats*, *$monthlyStats*, *$weeklyStats*, *$daylyStats*, *$hourlyStats*, *$statsPerMinute*, and *$statsPerSecond*
12 |
13 | #### Calculates the *min value*
14 |
15 | ```php
16 | // Get the min value of the yearly statistics
17 | $minValue = $statsComputer->computeMinValue($yearlyStats);
18 | ```
19 |
20 | Result:
21 | ```php
22 | [2017,47882376]
23 | ```
24 |
25 | #### Calculates the *max value*
26 |
27 | ```php
28 | // Get the max value of the monthly statistics
29 | $maxValue = $statsComputer->computeMaxValue($monthlyStats);
30 | ```
31 |
32 | Result:
33 | ```php
34 | [8,951224]
35 | ```
36 |
37 | #### Calculates the *average*
38 |
39 | The **average** is the sum of the values of the statistical series divided by the number of values.
40 |
41 | ```php
42 | // Get the average of the weekly statistics
43 | $average = $statsComputer->computeAverage($weeklyStats);
44 | ```
45 |
46 | Result:
47 | ```php
48 | 265039
49 | ```
50 |
51 | #### Calculates the *range*
52 |
53 | The **range** is the difference between the highest number and the lowest number.
54 |
55 | ```php
56 | // Get the range of the daily statistics
57 | $range = $statsComputer->computeRange($dailyStats);
58 | ```
59 |
60 | Result:
61 | ```php
62 | 6
63 | ```
64 |
65 | #### Calculates the *mode*
66 |
67 | The **mode** is the number that is in the array the most times.
68 |
69 | ```php
70 | // Get the mode of the hourly statistics
71 | $mode = $statsComputer->computeMode($hourlyStats);
72 | ```
73 |
74 | Result:
75 | ```php
76 | 700
77 | ```
78 |
79 | #### Calculates the *median*
80 |
81 | The **median** is the middle value after the numbers are sorted smallest to largest.
82 |
83 | ```php
84 | // Get the median of the statistics per minute
85 | $median = $statsComputer->computeMedian($statsPerMinute);
86 | ```
87 |
88 | Result:
89 | ```php
90 | 75.5
91 | ```
92 |
93 | #### Count the number of values in the statistical series
94 |
95 | ```php
96 | // Get the count of the statistics per second
97 | $count = $statsComputer->count($statsPerSecond);
98 | ```
99 |
100 | Result:
101 | ```php
102 | 60
103 | ```
104 |
--------------------------------------------------------------------------------
/Resources/doc/readme/tools-command-cleanup.md:
--------------------------------------------------------------------------------
1 | # Tools
2 |
3 | ## Command
4 |
5 | ### Cleanup viewcounter data
6 |
7 | You can delete the viewcounter data using the **ViewcounterCleanupCommand** command:
8 |
9 | - Delete all the viewcounter data from the database:
10 |
11 | ```bash
12 | php bin/console tchoulom:viewcounter:cleanup
13 | ```
14 |
15 | - Delete all the viewcounter data whose article was viewed at least 1 hour ago:
16 |
17 | ```bash
18 | php bin/console tchoulom:viewcounter:cleanup --min=1h
19 | ```
20 |
21 | - Delete all the viewcounter data whose article was viewed at most 1 day ago:
22 |
23 | ```bash
24 | php bin/console tchoulom:viewcounter:cleanup --max=1d
25 | ```
26 |
27 | - Delete all the viewcounter data whose article was viewed at least 3 years ago:
28 |
29 | ```bash
30 | php bin/console tchoulom:viewcounter:cleanup --min=3y
31 | ```
32 |
33 | - Delete all the viewcounter data whose article was viewed at most 5 months ago:
34 |
35 | ```bash
36 | php bin/console tchoulom:viewcounter:cleanup --max=5M
37 | ```
38 |
39 | - Add the 'auto-approve' option to skip approval questions:
40 |
41 | ```bash
42 | php bin/console tchoulom:viewcounter:cleanup --max=5M --auto-approve=true
43 |
44 | By default, the value of the 'auto-approve' option is equal to false.
45 | ```
46 |
47 | - Examples of date interval:
48 |
49 | ```text
50 | 's' => 'second'
51 | 'm' => 'minute'
52 | 'h' => 'hour'
53 | 'd' => 'day'
54 | 'w' => 'week'
55 | 'M' => 'month'
56 | 'y' => 'year'
57 | ```
58 |
--------------------------------------------------------------------------------
/Resources/doc/readme/tools-command-stats-converter.md:
--------------------------------------------------------------------------------
1 | # Tools
2 |
3 | ## Command
4 |
5 | ### Converts ViewCounter entities to statistical data
6 |
7 | The creation of statistical data after each view count may slow performance of your application.
8 |
9 | It is possible to avoid the creation of statistical data after each view count, by proceeding as follows:
10 |
11 | - Disable the use of statistics
12 |
13 | Set **enabled** to **false** in config :
14 |
15 | ```yaml
16 |
17 | tchoulom_view_counter:
18 | ...
19 | statistics:
20 | enabled: false
21 | ...
22 | ```
23 |
24 | - Run the following command:
25 |
26 | This command converts ViewCounter entities to statistical data.
27 |
28 | ```bash
29 | php bin/console tchoulom:viewcounter:stats:convert
30 | ```
31 |
32 | or
33 |
34 | ```bash
35 | php bin/console tchoulom:viewcounter:stats:convert --cleanup=true
36 | ```
37 |
38 | - Add the 'auto-approve' option to skip approval questions:
39 |
40 | ```bash
41 | php bin/console tchoulom:viewcounter:stats:convert --cleanup=true --auto-approve=true
42 |
43 | By default, the value of the 'auto-approve' option is equal to false.
44 | ```
45 |
46 | This command can be automated via a cron task.
47 |
48 | The **cleanup** option allows to delete or not the ViewCounter entities after the generation of the statistical data.
49 |
50 | If the **cleanup** option is equal to **true**, the ViewCounter entities will be deleted after generating the statistical data.
51 |
52 | If the **cleanup** option is equal to **false**, the ViewCounter entities will not be deleted after generating the statistical data.
53 |
54 | By default the value of the **cleanup** option is equal to **true**.
55 |
--------------------------------------------------------------------------------
/Statistics/Date.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | /**
18 | * Class Date
19 | */
20 | class Date
21 | {
22 | /**
23 | * The total.
24 | *
25 | * @var int
26 | */
27 | protected $total = 0;
28 |
29 | /**
30 | * The Full Date.
31 | *
32 | * @var \DateTimeInterface
33 | */
34 | protected $fullDate;
35 |
36 | /**
37 | * Date constructor.
38 | *
39 | * @param int $total
40 | * @param $fullDate
41 | */
42 | public function __construct(int $total, $fullDate)
43 | {
44 | $this->total = $total;
45 | $this->fullDate = $fullDate;
46 | }
47 |
48 | /**
49 | * Gets the total.
50 | *
51 | * @return int The total
52 | */
53 | public function getTotal(): int
54 | {
55 | return $this->total;
56 | }
57 |
58 | /**
59 | * Sets the total.
60 | *
61 | * @param int $total The total
62 | *
63 | * @return self
64 | */
65 | public function setTotal(int $total): self
66 | {
67 | $this->total = $total;
68 |
69 | return $this;
70 | }
71 |
72 | /**
73 | * Gets the full date.
74 | *
75 | * @return \DateTimeInterface The DateTimeInterface
76 | */
77 | public function getFullDate(): \DateTimeInterface
78 | {
79 | return $this->fullDate;
80 | }
81 |
82 | /**
83 | * Sets the full date.
84 | *
85 | * @param \DateTimeInterface $fullDate The DateTimeInterface
86 | *
87 | * @return self
88 | */
89 | public function setFullDate(\DateTimeInterface $fullDate): self
90 | {
91 | $this->fullDate = $fullDate;
92 |
93 | return $this;
94 | }
95 |
96 | /**
97 | * Builds the Date.
98 | *
99 | * @return self
100 | */
101 | public function build(): self
102 | {
103 | $this->total++;
104 |
105 | return $this;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Statistics/Day.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 | use Tchoulom\ViewCounterBundle\Util\Date;
19 |
20 | /**
21 | * Class Day
22 | */
23 | class Day
24 | {
25 | /**
26 | * The Day name.
27 | *
28 | * @var string
29 | */
30 | protected $name;
31 |
32 | /**
33 | * The total.
34 | *
35 | * @var int
36 | */
37 | protected $total = 0;
38 |
39 | /**
40 | * The Date.
41 | *
42 | * @var \DateTimeInterface
43 | */
44 | protected $date;
45 |
46 | use HourTrait;
47 |
48 | /**
49 | * Day constructor.
50 | *
51 | * @param string $name
52 | * @param int $total
53 | */
54 | public function __construct(string $name, int $total)
55 | {
56 | $this->name = $name;
57 | $this->total = $total;
58 | }
59 |
60 | /**
61 | * Gets the name.
62 | *
63 | * @return string
64 | */
65 | public function getName(): string
66 | {
67 | return $this->name;
68 | }
69 |
70 | /**
71 | * Sets the name.
72 | *
73 | * @param string $name
74 | *
75 | * @return self
76 | */
77 | public function setName(string $name): self
78 | {
79 | $this->name = $name;
80 |
81 | return $this;
82 | }
83 |
84 | /**
85 | * Gets the date.
86 | *
87 | * @return \DateTimeInterface
88 | */
89 | public function getDate(): \DateTimeInterface
90 | {
91 | return $this->date;
92 | }
93 |
94 | /**
95 | * Sets the date.
96 | *
97 | * @param \DateTimeInterface $date
98 | *
99 | * @return self
100 | */
101 | public function setDate(\DateTimeInterface $date): self
102 | {
103 | $this->date = $date;
104 |
105 | return $this;
106 | }
107 |
108 | /**
109 | * Gets the total.
110 | *
111 | * @return int
112 | */
113 | public function getTotal(): int
114 | {
115 | return $this->total;
116 | }
117 |
118 | /**
119 | * Sets the total.
120 | *
121 | * @param int $total
122 | *
123 | * @return self
124 | */
125 | public function setTotal(int $total): self
126 | {
127 | $this->total = $total;
128 |
129 | return $this;
130 | }
131 |
132 | /**
133 | * Builds the day.
134 | *
135 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
136 | *
137 | * @return self
138 | *
139 | * @throws \Exception
140 | */
141 | public function build(ViewCounterInterface $viewcounter): self
142 | {
143 | $this->total++;
144 | $this->date = $viewcounter->getViewDate();
145 | $hourName = 'h' . $viewcounter->getViewDate()->format('H');
146 | $hour = $this->getHour($hourName);
147 | $hourName = strtolower($hour->getName());
148 | $this->$hourName = $hour->build($viewcounter);
149 |
150 | return $this;
151 | }
152 |
153 | /**
154 | * Gets the hour.
155 | *
156 | * @param string|null $hourName The hour name.
157 | *
158 | * @return Hour The hour.
159 | */
160 | public function getHour(string $hourName = null): Hour
161 | {
162 | if (null == $hourName) {
163 | $hourName = 'h' . Date::getHour();
164 | }
165 |
166 | $hour = $this->get($hourName);
167 | if (!$hour instanceof Hour) {
168 | $hour = new Hour($hourName, 0);
169 | }
170 |
171 | return $hour;
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/Statistics/Hour.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 | use Tchoulom\ViewCounterBundle\Util\Date;
19 |
20 | /**
21 | * Class Hour
22 | */
23 | class Hour
24 | {
25 | /**
26 | * The Hour name.
27 | *
28 | * @var string
29 | */
30 | protected $name;
31 |
32 | /**
33 | * The Full Hour.
34 | *
35 | * @var false|string
36 | */
37 | protected $fullHour;
38 |
39 | /**
40 | * The total.
41 | *
42 | * @var int
43 | */
44 | protected $total = 0;
45 |
46 | use MinuteTrait;
47 |
48 | /**
49 | * Hour constructor.
50 | *
51 | * @param string $name
52 | * @param int $total
53 | */
54 | public function __construct(string $name, int $total)
55 | {
56 | $this->name = $name;
57 | $this->total = $total;
58 | }
59 |
60 | /**
61 | * Gets the name.
62 | *
63 | * @return string
64 | */
65 | public function getName(): string
66 | {
67 | return $this->name;
68 | }
69 |
70 | /**
71 | * Sets the name.
72 | *
73 | * @param string $name
74 | *
75 | * @return self
76 | */
77 | public function setName(string $name): self
78 | {
79 | $this->name = $name;
80 |
81 | return $this;
82 | }
83 |
84 | /**
85 | * Gets the full hour.
86 | *
87 | * @return false|string
88 | */
89 | public function getFullHour()
90 | {
91 | return $this->fullHour;
92 | }
93 |
94 | /**
95 | * Sets the full hour.
96 | *
97 | * @param false|string $fullHour
98 | *
99 | * @return self
100 | */
101 | public function setFullHour($fullHour): self
102 | {
103 | $this->fullHour = $fullHour;
104 |
105 | return $this;
106 | }
107 |
108 |
109 | /**
110 | * Gets the total.
111 | *
112 | * @return int
113 | */
114 | public function getTotal(): int
115 | {
116 | return $this->total;
117 | }
118 |
119 | /**
120 | * Sets the total.
121 | *
122 | * @param $total
123 | *
124 | * @return self
125 | */
126 | public function setTotal(int $total): self
127 | {
128 | $this->total = $total;
129 |
130 | return $this;
131 | }
132 |
133 | /**
134 | * Builds the hour.
135 | *
136 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
137 | *
138 | * @return self
139 | */
140 | public function build(ViewCounterInterface $viewcounter): self
141 | {
142 | $this->total++;
143 | $this->fullHour = Date::getFullHour();
144 |
145 | $minuteName = 'm' . $viewcounter->getViewDate()->format('i');
146 | $minute = $this->getMinute($minuteName);
147 | $minuteName = strtolower($minute->getName());
148 | $this->$minuteName = $minute->build($viewcounter);
149 |
150 | return $this;
151 | }
152 |
153 | /**
154 | * Gets the minute.
155 | *
156 | * @param string|null $minuteName The minute name.
157 | *
158 | * @return Minute The minute.
159 | */
160 | public function getMinute(string $minuteName = null): Minute
161 | {
162 | if (null == $minuteName) {
163 | $minuteName = 'm' . Date::getMinute();
164 | }
165 |
166 | $minute = $this->get($minuteName);
167 | if (!$minute instanceof Minute) {
168 | $minute = new Minute($minuteName, 0);
169 | }
170 |
171 | return $minute;
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/Statistics/HourTrait.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | /**
18 | * Trait HourTrait
19 | */
20 | trait HourTrait
21 | {
22 | protected $h00;
23 | protected $h01;
24 | protected $h02;
25 | protected $h03;
26 | protected $h04;
27 | protected $h05;
28 | protected $h06;
29 | protected $h07;
30 | protected $h08;
31 | protected $h09;
32 | protected $h10;
33 | protected $h11;
34 | protected $h12;
35 | protected $h13;
36 | protected $h14;
37 | protected $h15;
38 | protected $h16;
39 | protected $h17;
40 | protected $h18;
41 | protected $h19;
42 | protected $h20;
43 | protected $h21;
44 | protected $h22;
45 | protected $h23;
46 |
47 | /**
48 | * Gets the hour.
49 | *
50 | * @param string $hourName The given hour name.
51 | *
52 | * @return Hour|null The hour.
53 | */
54 | public function get(string $hourName): ?Hour
55 | {
56 | return $this->$hourName;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Statistics/Minute.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 | use Tchoulom\ViewCounterBundle\Util\Date;
19 |
20 | /**
21 | * Class Minute
22 | */
23 | class Minute
24 | {
25 | /**
26 | * The name.
27 | *
28 | * @var string
29 | */
30 | protected $name;
31 |
32 | /**
33 | * The total.
34 | *
35 | * @var int
36 | */
37 | protected $total = 0;
38 |
39 | use SecondTrait;
40 |
41 | /**
42 | * Minute constructor.
43 | *
44 | * @param string $name
45 | * @param int $total
46 | */
47 | public function __construct(string $name, int $total)
48 | {
49 | $this->name = $name;
50 | $this->total = $total;
51 | }
52 |
53 | /**
54 | * Gets the name.
55 | *
56 | * @return string
57 | */
58 | public function getName(): string
59 | {
60 | return $this->name;
61 | }
62 |
63 | /**
64 | * Sets the name.
65 | *
66 | * @param string $name
67 | *
68 | * @return self
69 | */
70 | public function setName(string $name): self
71 | {
72 | $this->name = $name;
73 |
74 | return $this;
75 | }
76 |
77 | /**
78 | * Gets the total.
79 | *
80 | * @return int
81 | */
82 | public function getTotal(): int
83 | {
84 | return $this->total;
85 | }
86 |
87 | /**
88 | * Sets the total.
89 | *
90 | * @param int $total
91 | *
92 | * @return self
93 | */
94 | public function setTotal(int $total): self
95 | {
96 | $this->total = $total;
97 |
98 | return $this;
99 | }
100 |
101 | /**
102 | * Builds the minute.
103 | *
104 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
105 | *
106 | * @return self
107 | */
108 | public function build(ViewCounterInterface $viewcounter): self
109 | {
110 | $this->total++;
111 |
112 | $secondName = 's' . $viewcounter->getViewDate()->format('s');
113 | $second = $this->getSecond($secondName);
114 | $secondName = strtolower($second->getName());
115 | $this->$secondName = $second->build($viewcounter);
116 |
117 | return $this;
118 | }
119 |
120 | /**
121 | * Gets the second.
122 | *
123 | * @param string|null $secondName The second name.
124 | *
125 | * @return Second The second.
126 | */
127 | public function getSecond(string $secondName = null): Second
128 | {
129 | if (null == $secondName) {
130 | $secondName = 's' . Date::getSecond();
131 | }
132 |
133 | $second = $this->get($secondName);
134 | if (!$second instanceof Second) {
135 | $second = new Second($secondName, 0);
136 | }
137 |
138 | return $second;
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/Statistics/MinuteTrait.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | /**
18 | * Trait MinuteTrait
19 | */
20 | trait MinuteTrait
21 | {
22 | protected $m00;
23 | protected $m01;
24 | protected $m02;
25 | protected $m03;
26 | protected $m04;
27 | protected $m05;
28 | protected $m06;
29 | protected $m07;
30 | protected $m08;
31 | protected $m09;
32 | protected $m10;
33 | protected $m11;
34 | protected $m12;
35 | protected $m13;
36 | protected $m14;
37 | protected $m15;
38 | protected $m16;
39 | protected $m17;
40 | protected $m18;
41 | protected $m19;
42 | protected $m20;
43 | protected $m21;
44 | protected $m22;
45 | protected $m23;
46 | protected $m24;
47 | protected $m25;
48 | protected $m26;
49 | protected $m27;
50 | protected $m28;
51 | protected $m29;
52 | protected $m30;
53 | protected $m31;
54 | protected $m32;
55 | protected $m33;
56 | protected $m34;
57 | protected $m35;
58 | protected $m36;
59 | protected $m37;
60 | protected $m38;
61 | protected $m39;
62 | protected $m40;
63 | protected $m41;
64 | protected $m42;
65 | protected $m43;
66 | protected $m44;
67 | protected $m45;
68 | protected $m46;
69 | protected $m47;
70 | protected $m48;
71 | protected $m49;
72 | protected $m50;
73 | protected $m51;
74 | protected $m52;
75 | protected $m53;
76 | protected $m54;
77 | protected $m55;
78 | protected $m56;
79 | protected $m57;
80 | protected $m58;
81 | protected $m59;
82 |
83 | /**
84 | * Gets the minute.
85 | *
86 | * @param string $minuteName The minute name.
87 | *
88 | * @return Minute|null The minute.
89 | */
90 | public function get(string $minuteName): ?Minute
91 | {
92 | return $this->$minuteName;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Statistics/Month.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 | use Tchoulom\ViewCounterBundle\Util\Date;
19 |
20 | /**
21 | * Class Month
22 | */
23 | class Month
24 | {
25 | /**
26 | * The month number.
27 | *
28 | * @var int
29 | */
30 | protected $monthNumber;
31 |
32 | /**
33 | * The total.
34 | *
35 | * @var int
36 | */
37 | protected $total = 0;
38 |
39 | /**
40 | * The weeks.
41 | *
42 | * @var Week[]
43 | */
44 | protected $weeks = [];
45 |
46 | /**
47 | * Month constructor.
48 | */
49 | public function __construct()
50 | {
51 | $this->monthNumber = Date::getNowMonth();
52 | }
53 |
54 | /**
55 | * Gets the number of month.
56 | *
57 | * @return int
58 | */
59 | public function getMonthNumber(): int
60 | {
61 | return $this->monthNumber;
62 | }
63 |
64 | /**
65 | * Sets the number of month.
66 | *
67 | * @param int $monthNumber
68 | *
69 | * @return self
70 | */
71 | public function setMonthNumber(int $monthNumber): self
72 | {
73 | $this->monthNumber = $monthNumber;
74 |
75 | return $this;
76 | }
77 |
78 | /**
79 | * Gets the total.
80 | *
81 | * @return int
82 | */
83 | public function getTotal(): int
84 | {
85 | return $this->total;
86 | }
87 |
88 | /**
89 | * Sets the total.
90 | *
91 | * @param int $total
92 | *
93 | * @return self
94 | */
95 | public function setTotal(int $total): self
96 | {
97 | $this->total = $total;
98 |
99 | return $this;
100 | }
101 |
102 | /**
103 | * Gets the weeks.
104 | *
105 | * @return Week[]
106 | */
107 | public function getWeeks(): array
108 | {
109 | return $this->weeks;
110 | }
111 |
112 | /**
113 | * Builds the week.
114 | *
115 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
116 | *
117 | * @return self
118 | */
119 | public function buildWeek(ViewCounterInterface $viewcounter): self
120 | {
121 | $this->total++;
122 | $weekNumber = intval($viewcounter->getViewDate()->format('W'));
123 |
124 | if (isset($this->weeks[$weekNumber])) {
125 | $week = $this->weeks[$weekNumber];
126 | } else {
127 | $week = new Week();
128 | }
129 |
130 | $this->weeks[$weekNumber] = $week->buildDay($viewcounter);
131 |
132 | return $this;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/Statistics/Page.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | use Tchoulom\ViewCounterBundle\Adapter\Geolocator\GeolocatorAdapterInterface;
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 | use Tchoulom\ViewCounterBundle\Geolocation\Country;
20 | use Tchoulom\ViewCounterBundle\Util\Date;
21 |
22 | /**
23 | * Class Page
24 | */
25 | class Page
26 | {
27 | /**
28 | * The page ID.
29 | *
30 | * @var int
31 | */
32 | protected $id;
33 |
34 | /**
35 | * The total of views of the current page.
36 | *
37 | * @var int
38 | */
39 | protected $total = 0;
40 |
41 | /**
42 | * The years.
43 | *
44 | * @var Year[]
45 | */
46 | protected $years = [];
47 |
48 | /**
49 | * The countries.
50 | *
51 | * @var Country[]
52 | */
53 | protected $countries = [];
54 |
55 | /**
56 | * Page constructor.
57 | *
58 | * @param int $id
59 | */
60 | public function __construct(int $id)
61 | {
62 | $this->id = $id;
63 | }
64 |
65 | /**
66 | * Gets the Id.
67 | *
68 | * @return int
69 | */
70 | public function getId(): int
71 | {
72 | return $this->id;
73 | }
74 |
75 | /**
76 | * Gets the total of views.
77 | *
78 | * @return int
79 | */
80 | public function getTotal(): int
81 | {
82 | return $this->total;
83 | }
84 |
85 | /**
86 | * Sets the total of views.
87 | *
88 | * @param int $total
89 | *
90 | * @return self
91 | */
92 | public function setTotal(int $total): self
93 | {
94 | $this->total = $total;
95 |
96 | return $this;
97 | }
98 |
99 | /**
100 | * @return Year[]
101 | */
102 | public function getYears(): array
103 | {
104 | return $this->years;
105 | }
106 |
107 | /**
108 | * Gets the countries.
109 | *
110 | * @return Country[]
111 | */
112 | public function getCountries(): array
113 | {
114 | return $this->countries;
115 | }
116 |
117 | /**
118 | * Builds the year.
119 | *
120 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
121 | *
122 | * @return self
123 | */
124 | public function buildYear(ViewCounterInterface $viewcounter): self
125 | {
126 | $this->total++;
127 | $yearNumber = intval($viewcounter->getViewDate()->format('Y'));
128 |
129 | if (isset($this->years[$yearNumber])) {
130 | $year = $this->years[$yearNumber];
131 | } else {
132 | $year = new Year();
133 | }
134 |
135 | $this->years[$yearNumber] = $year->buildMonth($viewcounter);
136 |
137 | return $this;
138 | }
139 |
140 | /**
141 | * Builds the country.
142 | *
143 | * @param GeolocatorAdapterInterface $geolocator The geolocator.
144 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
145 | *
146 | * @return self
147 | */
148 | public function buildCountry(GeolocatorAdapterInterface $geolocator, ViewCounterInterface $viewcounter): self
149 | {
150 | $countryName = $geolocator->getCountry();
151 |
152 | if (isset($this->countries[$countryName])) {
153 | $country = $this->countries[$countryName];
154 | } else {
155 | $country = new Country();
156 | }
157 |
158 | $this->countries[$countryName] = $country->build($geolocator, $viewcounter);
159 |
160 | return $this;
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/Statistics/Second.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 |
19 | /**
20 | * Class Second
21 | */
22 | class Second
23 | {
24 | /**
25 | * The second name.
26 | *
27 | * @var string
28 | */
29 | protected $name;
30 |
31 | /**
32 | * The total.
33 | *
34 | * @var int
35 | */
36 | protected $total = 0;
37 |
38 | /**
39 | * Second constructor.
40 | *
41 | * @param string $name
42 | * @param int $total
43 | */
44 | public function __construct(string $name, int $total)
45 | {
46 | $this->name = $name;
47 | $this->total = $total;
48 | }
49 |
50 | /**
51 | * Gets the name.
52 | *
53 | * @return string
54 | */
55 | public function getName(): string
56 | {
57 | return $this->name;
58 | }
59 |
60 | /**
61 | * Sets the name.
62 | *
63 | * @param string $name
64 | *
65 | * @return self
66 | */
67 | public function setName(string $name): self
68 | {
69 | $this->name = $name;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * Gets the total.
76 | *
77 | * @return int
78 | */
79 | public function getTotal(): int
80 | {
81 | return $this->total;
82 | }
83 |
84 | /**
85 | * Sets the total.
86 | *
87 | * @param int $total
88 | *
89 | * @return self
90 | */
91 | public function setTotal(int $total): self
92 | {
93 | $this->total = $total;
94 |
95 | return $this;
96 | }
97 |
98 | /**
99 | * Builds the second.
100 | *
101 | * ViewCounterInterface $viewcounter The viewcounter entity.
102 | *
103 | * @return self
104 | */
105 | public function build(ViewCounterInterface $viewcounter): self
106 | {
107 | $this->total++;
108 |
109 | return $this;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/Statistics/SecondTrait.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | /**
18 | * Trait SecondTrait
19 | */
20 | trait SecondTrait
21 | {
22 | protected $s00;
23 | protected $s01;
24 | protected $s02;
25 | protected $s03;
26 | protected $s04;
27 | protected $s05;
28 | protected $s06;
29 | protected $s07;
30 | protected $s08;
31 | protected $s09;
32 | protected $s10;
33 | protected $s11;
34 | protected $s12;
35 | protected $s13;
36 | protected $s14;
37 | protected $s15;
38 | protected $s16;
39 | protected $s17;
40 | protected $s18;
41 | protected $s19;
42 | protected $s20;
43 | protected $s21;
44 | protected $s22;
45 | protected $s23;
46 | protected $s24;
47 | protected $s25;
48 | protected $s26;
49 | protected $s27;
50 | protected $s28;
51 | protected $s29;
52 | protected $s30;
53 | protected $s31;
54 | protected $s32;
55 | protected $s33;
56 | protected $s34;
57 | protected $s35;
58 | protected $s36;
59 | protected $s37;
60 | protected $s38;
61 | protected $s39;
62 | protected $s40;
63 | protected $s41;
64 | protected $s42;
65 | protected $s43;
66 | protected $s44;
67 | protected $s45;
68 | protected $s46;
69 | protected $s47;
70 | protected $s48;
71 | protected $s49;
72 | protected $s50;
73 | protected $s51;
74 | protected $s52;
75 | protected $s53;
76 | protected $s54;
77 | protected $s55;
78 | protected $s56;
79 | protected $s57;
80 | protected $s58;
81 | protected $s59;
82 |
83 | /**
84 | * Gets the second.
85 | *
86 | * @param string $secondName The second name.
87 | *
88 | * @return Second|null The second.
89 | */
90 | public function get(string $secondName): ?Second
91 | {
92 | return $this->$secondName;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Statistics/ViewDateTrait.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 |
18 | use Tchoulom\ViewCounterBundle\Statistics\Date as ViewDate;
19 | use Tchoulom\ViewCounterBundle\Util\Date;
20 |
21 | /**
22 | * Trait ViewDateTrait
23 | */
24 | trait ViewDateTrait
25 | {
26 | /**
27 | * The view dates.
28 | *
29 | * @var array
30 | */
31 | protected $viewDates = [];
32 |
33 | /**
34 | * Gets the view dates.
35 | *
36 | * @return array
37 | */
38 | public function getViewDates(): array
39 | {
40 | return $this->viewDates;
41 | }
42 |
43 | /**
44 | * Sets the view dates.
45 | *
46 | * @param array $viewDates The view dates.
47 | *
48 | * @return self
49 | */
50 | public function setViewDates(array $viewDates): self
51 | {
52 | $this->viewDates = $viewDates;
53 |
54 | return $this;
55 | }
56 |
57 | /**
58 | * Builds the view date.
59 | */
60 | public function buildViewDate(): void
61 | {
62 | $date = $this->viewcounter->getViewDate();
63 | $formattedDate = $date->format('Y-m-d H:i:s');
64 |
65 | if (isset($this->viewDates[$formattedDate])) {
66 | $date = $this->viewDates[$formattedDate];
67 | $date->build();
68 | } else {
69 | $date = new ViewDate(1, $date);
70 | }
71 |
72 | $this->viewDates[$formattedDate] = $date;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Statistics/Year.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Statistics;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 | use Tchoulom\ViewCounterBundle\Util\Date;
19 |
20 | /**
21 | * Class Year
22 | */
23 | class Year
24 | {
25 | /**
26 | * The year number.
27 | *
28 | * @var int
29 | */
30 | protected $yearNumber;
31 |
32 | /**
33 | * The total.
34 | *
35 | * @var int
36 | */
37 | protected $total = 0;
38 |
39 | /**
40 | * The months.
41 | *
42 | * @var Month[]
43 | */
44 | protected $months = [];
45 |
46 | /**
47 | * Year constructor.
48 | */
49 | public function __construct()
50 | {
51 | $this->yearNumber = Date::getNowYear();
52 | }
53 |
54 | /**
55 | * Gets the number of year.
56 | *
57 | * @return int
58 | */
59 | public function getYearNumber(): int
60 | {
61 | return $this->yearNumber;
62 | }
63 |
64 | /**
65 | * Sets the number of year.
66 | *
67 | * @param int $yearNumber
68 | *
69 | * @return self
70 | */
71 | public function setYearNumber(int $yearNumber): self
72 | {
73 | $this->yearNumber = $yearNumber;
74 |
75 | return $this;
76 | }
77 |
78 | /**
79 | * Gets the total.
80 | *
81 | * @return int
82 | */
83 | public function getTotal(): int
84 | {
85 | return $this->total;
86 | }
87 |
88 | /**
89 | * Sets the total.
90 | *
91 | * @param int $total
92 | *
93 | * @return self
94 | */
95 | public function setTotal(int $total): self
96 | {
97 | $this->total = $total;
98 |
99 | return $this;
100 | }
101 |
102 | /**
103 | * Gets the months.
104 | *
105 | * @return Month[]
106 | */
107 | public function getMonths(): array
108 | {
109 | return $this->months;
110 | }
111 |
112 | /**
113 | * Builds the month.
114 | *
115 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
116 | *
117 | * @return self
118 | */
119 | public function buildMonth(ViewCounterInterface $viewcounter): self
120 | {
121 | $this->total++;
122 | $monthNumber = intval($viewcounter->getViewDate()->format('m'));
123 |
124 | if (isset($this->months[$monthNumber])) {
125 | $month = $this->months[$monthNumber];
126 | } else {
127 | $month = new Month();
128 | }
129 |
130 | $this->months[$monthNumber] = $month->buildWeek($viewcounter);
131 |
132 | return $this;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/Storage/Database/MongoDB/DocumentStorageInterface.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Storage\Database\MongoDB;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
18 |
19 | /**
20 | * Interface DocumentStorageInterface
21 | *
22 | * @package Tchoulom\ViewCounterBundle\Storage\Database
23 | */
24 | interface DocumentStorageInterface
25 | {
26 | /**
27 | * Saves the statistics.
28 | *
29 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
30 | */
31 | public function save(ViewCounterInterface $viewcounter);
32 | }
33 |
--------------------------------------------------------------------------------
/Storage/Filesystem/FilesystemStorageInterface.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Storage\Filesystem;
16 |
17 |
18 | use Tchoulom\ViewCounterBundle\Entity\ViewCounterInterface;
19 | use Tchoulom\ViewCounterBundle\Model\ViewCountable;
20 |
21 | /**
22 | * Class FilesystemStorageInterface is used to manipulate the file system.
23 | */
24 | interface FilesystemStorageInterface
25 | {
26 | /**
27 | * Saves the statistics.
28 | *
29 | * @param ViewCounterInterface $viewcounter The viewcounter entity.
30 | */
31 | public function save(ViewCounterInterface $viewcounter);
32 |
33 | /**
34 | * Loads the contents.
35 | *
36 | * @return mixed
37 | */
38 | public function loadContents();
39 |
40 | /**
41 | * Gets the stats file name.
42 | *
43 | * @return string
44 | */
45 | public function getStatsFileName(): string;
46 |
47 | /**
48 | * Gets the stats file extension.
49 | *
50 | * @return string|null
51 | */
52 | public function getStatsFileExtension(): ?string;
53 |
54 | /**
55 | * Gets the full stats file name.
56 | *
57 | * @return string
58 | */
59 | public function getFullStatsFileName(): string;
60 |
61 | /**
62 | * Gets the viewcounter directory.
63 | *
64 | * @return string
65 | */
66 | public function getViewcounterDir(): string;
67 |
68 | /**
69 | * Creates a directory.
70 | *
71 | * @param $dirname
72 | * @param int $mode
73 | * @param bool $recursive
74 | */
75 | public function mkdir($dirname, $mode = 0777, $recursive = true);
76 |
77 | /**
78 | * Opens a file.
79 | *
80 | * @param $filename
81 | * @param string $mode
82 | *
83 | * @return bool|resource
84 | */
85 | public function fopen($filename, $mode = 'w');
86 |
87 | /**
88 | * Writes to file.
89 | *
90 | * @param $file
91 | * @param $stats
92 | */
93 | public function fwrite($file, $stats);
94 |
95 | /**
96 | * Closes an output file.
97 | *
98 | * @param $file
99 | */
100 | public function fclose($file);
101 | }
102 |
--------------------------------------------------------------------------------
/TchoulomViewCounterBundle.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle;
16 |
17 | use Symfony\Component\DependencyInjection\ContainerBuilder;
18 | use Symfony\Component\HttpKernel\Bundle\Bundle;
19 | use Tchoulom\ViewCounterBundle\DependencyInjection\Compiler\ViewcounterPass;
20 |
21 | class TchoulomViewCounterBundle extends Bundle
22 | {
23 | /**
24 | * @param ContainerBuilder $container
25 | */
26 | public function build(ContainerBuilder $container): void
27 | {
28 | parent::build($container);
29 |
30 | $container->addCompilerPass(new ViewcounterPass());
31 | }
32 |
33 | /**
34 | * The supported view strategy.
35 | *
36 | * @var array
37 | */
38 | const SUPPORTED_STRATEGY = ['on_refresh', 'unique_view', 'daily_view', 'hourly_view', 'weekly_view', 'monthly_view', 'yearly_view', 'view_per_minute', 'view_per_second'];
39 |
40 | /**
41 | * The supported statistics keys.
42 | *
43 | * @var array
44 | */
45 | const SUPPORTED_STATS_KEYS = ['enabled', 'stats_file_name', 'stats_file_extension'];
46 |
47 | /**
48 | * The filesystem storage engine name.
49 | *
50 | * @var string
51 | */
52 | const FILESYSTEM_STORAGE_ENGINE_NAME = 'filesystem';
53 |
54 | /**
55 | * The mongodb storage engine name.
56 | *
57 | * @var string
58 | */
59 | const MONGODB_STORAGE_ENGINE_NAME = 'mongodb';
60 | }
61 |
--------------------------------------------------------------------------------
/Tests/BaseTest.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Tests;
16 |
17 | use PHPUnit\Framework\TestCase;
18 | use Tchoulom\ViewCounterBundle\Storage\Filesystem\FilesystemStorageInterface;
19 |
20 | /**
21 | * Class BaseTest
22 | */
23 | abstract class BaseTest extends TestCase
24 | {
25 | protected $clientIP = '127.0.0.1';
26 | protected $filesystemStorageMock;
27 | protected $viewInterval = ['on_refresh', 'daily_view', 'unique_view', 'hourly_view', 'weekly_view', 'monthly_view', 'yearly_view', 'view_per_minute', 'view_per_second'];
28 |
29 | /**
30 | * Setup the fixtures.
31 | */
32 | protected function setUp()
33 | {
34 | parent::setUp();
35 |
36 | $this->filesystemStorageMock = $this->createMock(FilesystemStorageInterface::class);
37 | }
38 |
39 | /**
40 | * tearDown
41 | */
42 | public function tearDown()
43 | {
44 | $this->filesystemStorageMock = null;
45 | }
46 |
47 | /**
48 | * Invokes a method.
49 | *
50 | * @param $object
51 | * @param $methodName
52 | * @param array $arguments
53 | *
54 | * @return mixed
55 | *
56 | * @throws \ReflectionException
57 | */
58 | public function invokeMethod($object, $methodName, array $arguments = array())
59 | {
60 | $reflection = new \ReflectionClass(get_class($object));
61 | $method = $reflection->getMethod($methodName);
62 | $method->setAccessible(true);
63 |
64 | return $method->invokeArgs($object, $arguments);
65 | }
66 |
67 | /**
68 | * Sets a protected property on a given object via reflection
69 | *
70 | * @param $object Instance in which protected value is being modified
71 | * @param $property Property on instance being modified
72 | * @param $value New value of the property being modified
73 | *
74 | * @return void
75 | *
76 | * @throws \ReflectionException
77 | */
78 | public function setProtectedProperty($object, $property, $value)
79 | {
80 | $reflection = new \ReflectionClass($object);
81 | $reflectionProperty = $reflection->getProperty($property);
82 | $reflectionProperty->setAccessible(true);
83 | $reflectionProperty->setValue($object, $value);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Tests/DependencyInjection/TchoulomViewCounterExtensionTest.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Tests\DependencyInjection;
16 |
17 | use Tchoulom\ViewCounterBundle\DependencyInjection\TchoulomViewCounterExtension;
18 | use Tchoulom\ViewCounterBundle\Tests\BaseTest;
19 |
20 | /**
21 | * Class TchoulomViewCounterExtensionTest
22 | */
23 | class TchoulomViewCounterExtensionTest extends BaseTest
24 | {
25 | protected $viewCounterExtension;
26 |
27 | /**
28 | * Setup the fixtures.
29 | */
30 | protected function setUp()
31 | {
32 | parent::setUp();
33 |
34 | $this->viewCounterExtension = new TchoulomViewCounterExtension();
35 | }
36 |
37 | /**
38 | * tearDown
39 | */
40 | public function tearDown()
41 | {
42 | parent::tearDown();
43 |
44 | $this->viewCounterExtension = null;
45 | }
46 |
47 | /**
48 | * tests postProcessSuccess
49 | *
50 | * @dataProvider postProcessProvider
51 | */
52 | public function testPostProcessSuccess($configs)
53 | {
54 | $uniqueElt = $this->viewCounterExtension->postProcess($configs);
55 |
56 | $this->assertTrue(is_array($uniqueElt));
57 | }
58 |
59 | /**
60 | * tests postProcessError
61 | *
62 | * @expectedException \Tchoulom\ViewCounterBundle\Exception\RuntimeException
63 | * @expectedExceptionMessage You must choose one of the following values: on_refresh, unique_view, daily_view, hourly_view, weekly_view, monthly_view, yearly_view, view_per_minute, view_per_second.
64 | */
65 | public function testPostProcessError($configs = null)
66 | {
67 | $this->viewCounterExtension->postProcess($configs);
68 | }
69 |
70 | /**
71 | * @return array
72 | */
73 | public function postProcessProvider()
74 | {
75 | return [
76 | [
77 | [
78 | ['view_counter' => ['daily_view' => 1]]
79 | ]
80 | ]
81 | ];
82 | }
83 | }
--------------------------------------------------------------------------------
/Tests/Entity/ViewCounterTest.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Tests\Entity;
16 |
17 | use Tchoulom\ViewCounterBundle\Entity\ViewCounter;
18 | use Tchoulom\ViewCounterBundle\Tests\BaseTest;
19 |
20 | /**
21 | * Class ViewCounterTest
22 | */
23 | class ViewCounterTest extends BaseTest
24 | {
25 | /**
26 | * Setup the fixtures.
27 | */
28 | protected function setUp()
29 | {
30 | parent::setUp();
31 | }
32 |
33 | /**
34 | * tearDown
35 | */
36 | public function tearDown()
37 | {
38 | parent::tearDown();
39 | }
40 |
41 | /**
42 | * tests GetIp
43 | */
44 | public function testGetIp()
45 | {
46 | $thisEntity = $this->viewCounterEntity->setIp($this->clientIP);
47 |
48 | $this->assertInstanceOf(ViewCounter::class, $thisEntity);
49 | $this->assertTrue(is_string($this->viewCounterEntity->getIp()));
50 | }
51 |
52 | /**
53 | * tests ViewDate
54 | */
55 | public function testViewDate()
56 | {
57 | $entityViewed = $this->viewCounterEntity->setViewDate($this->viewDate);
58 |
59 | $this->assertInstanceOf(ViewCounter::class, $entityViewed);
60 | $this->assertTrue(is_numeric($this->viewCounterEntity->getViewDate()->getTimestamp()));
61 | }
62 | }
--------------------------------------------------------------------------------
/Util/ReflectionExtractor.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * (c) Ernest TCHOULOM
10 | *
11 | * For the full copyright and license information, please view the LICENSE
12 | * file that was distributed with this source code.
13 | */
14 |
15 | namespace Tchoulom\ViewCounterBundle\Util;
16 |
17 | /**
18 | * Class ReflectionExtractor
19 | */
20 | class ReflectionExtractor
21 | {
22 | /**
23 | * Gets the short class name.
24 | *
25 | * @param $class
26 | *
27 | * @return string
28 | *
29 | * @throws \ReflectionException
30 | */
31 | public static function getShortClassName($class): string
32 | {
33 | return (new \ReflectionClass($class))->getShortName();
34 | }
35 |
36 | /**
37 | * Gets the class name.
38 | *
39 | * @param $class
40 | *
41 | * @return string
42 | *
43 | * @throws \ReflectionException
44 | */
45 | public static function getClassName($class): string
46 | {
47 | return strtolower(self::getShortClassName($class));
48 | }
49 |
50 | /**
51 | * Gets the class name pluralized.
52 | *
53 | * @param $class
54 | *
55 | * @return string
56 | *
57 | * @throws \ReflectionException
58 | */
59 | public static function getClassNamePluralized($class): string
60 | {
61 | return self::getClassName($class) . 's';
62 | }
63 |
64 | /**
65 | * Gets the full class name.
66 | *
67 | * @param $class
68 | *
69 | * @return string The full
70 | */
71 | public static function getFullClassName($class): string
72 | {
73 | return get_class($class);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tchoulom/view-counter-bundle",
3 | "license": "MIT",
4 | "type": "symfony-bundle",
5 | "description": "The \"View Counter\" bundle",
6 | "keywords": ["view counter", "view counter symfony", "statistics", "statistics bundle", "statistics symfony","statistics of web pages", "Google Charts", "view counter bundle", "Count the number of views of a page", "pages views counter", "view count", "viewership", "viewership measurement", "page views", "page view count", "view counter interface"],
7 | "authors": [
8 | {
9 | "name": "Ernest TCHOULOM",
10 | "email": "tchoulomernest@gmail.com",
11 | "homepage": "https://www.linkedin.com/in/ernest-tchoulom-69422025/"
12 | }
13 | ],
14 | "autoload": {
15 | "psr-4": {
16 | "Tchoulom\\ViewCounterBundle\\": ""
17 | },
18 | "exclude-from-classmap": [
19 | "/Tests/"
20 | ]
21 | },
22 | "require": {
23 | "php": ">=8.0.2",
24 | "symfony/framework-bundle": "^6.0|^7.0"
25 | },
26 | "require-dev": {
27 | "phpunit/phpunit": ">5.7"
28 | },
29 | "minimum-stability": "stable"
30 | }
31 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | tests
18 |
19 |
20 |
21 |
22 |
23 | src
24 |
25 | src/*Bundle/Resources
26 | src/*/*Bundle/Resources
27 | src/*/Bundle/*Bundle/Resources
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------