Skip to content

Commit

Permalink
Merge pull request #88 from Extendy/local-mshannaq-work
Browse files Browse the repository at this point in the history
Feat: List URL Hits
  • Loading branch information
mshannaq authored Nov 9, 2023
2 parents 52bec5a + 055dc6c commit e6cfc70
Show file tree
Hide file tree
Showing 19 changed files with 512 additions and 26 deletions.
20 changes: 20 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
changelog:
exclude:
authors:
- dependabot
categories:
- title: Breaking Changes
labels:
- 'breaking change'
- title: Fixed Bugs
labels:
- bug
- title: Enhancements
labels:
- enhancement
- title: Translations
labels:
- lang
- title: New Features
labels:
- 'new feature'
1 change: 0 additions & 1 deletion ChangeLog.md

This file was deleted.

2 changes: 2 additions & 0 deletions app/Config/Boot/development.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
| In development, we want to show as many errors as possible to help
| make sure they don't make it to production. And save us hours of
| painful debugging.
|
| If you set 'display_errors' to '1', CI4's detailed error report will show.
*/
error_reporting(-1);
ini_set('display_errors', '1');
Expand Down
2 changes: 2 additions & 0 deletions app/Config/Boot/production.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
|--------------------------------------------------------------------------
| Don't show ANY in production environments. Instead, let the system catch
| it and display a generic error message.
|
| If you set 'display_errors' to '1', CI4's detailed error report will show.
*/
ini_set('display_errors', '0');
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
Expand Down
6 changes: 6 additions & 0 deletions app/Config/Boot/testing.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<?php

/*
* The environment testing is reserved for PHPUnit testing. It has special
* conditions built into the framework at various places to assist with that.
* You can’t use it for your development.
*/

/*
|--------------------------------------------------------------------------
| ERROR DISPLAY
Expand Down
1 change: 1 addition & 0 deletions app/Config/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
$routes->get('edit/(:num)', 'Url::edit/$1', ['filter' => 'session']);
$routes->post('edit/(:num)', 'Url::editAction/$1', ['filter' => 'session']);
$routes->get('hits/(:num)', 'Url::hitslist/$1', ['filter' => 'session']);
$routes->get('hitslistdata/(:num)', 'Url::hitslistData/$1', ['filter' => 'session']); // json hits list for url
$routes->get('qrcode/(:num)', 'Url::generateQRCode/$1', ['filter' => 'session']);
});

Expand Down
2 changes: 1 addition & 1 deletion app/Config/Smarty.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Smarty extends BaseConfig
{
public $smarty_name = 'SmartyURL';
public $smarty_online_repo = 'https://smartyurl.extendy.net';
public $smarty_version = '0.0.0-dev-DND-1';
public $smarty_version = '0.0.0-dev-dnd.2';

/**
* @var string contain the file name of jquery supported version eg jquery-3.7.1 without js
Expand Down
133 changes: 130 additions & 3 deletions app/Controllers/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,6 @@ public function editAction($UrlId)
// updated ok

// i will check tags and update any changes
// samsam
// first of all i will delete all url tags
$delresult = $this->urltagsdatamodel->delUrlTags($url_id);
// now i will enter the tags again
Expand Down Expand Up @@ -736,10 +735,138 @@ public function editAction($UrlId)

public function hitslist($UrlId)
{
echo 'URL HITS OF.' . $UrlId;
if (! auth()->user()->can('url.access', 'admin.manageotherurls', 'super.admin')) {
return smarty_permission_error();
}

$url_id = (int) esc(smarty_remove_whitespace_from_url_identifier($UrlId));
if ($url_id === 0) {
// url_id given is not valid id
return redirect()->to('dashboard')->with('notice', lang('Url.urlError'));
}
$urlData = $this->urlmodel->where('url_id', $url_id)->first();

if ($urlData === null) {
// url not exsists in dataase
return redirect()->to('dashboard')->with('error', lang('Url.urlNotFoundShort'));
}

// i will check the user permission , does he allowed to access this url info
$userCanAccessUrl = $this->smartyurl->userCanAccessUrlInfo($url_id, (int) $urlData['url_user_id']);
if (! $userCanAccessUrl) {
return smarty_permission_error('It not your URL 😉😉😉');
}
$Go_Url = esc(smarty_detect_site_shortlinker() . $urlData['url_identifier']);

$data = [];

$data['lang'] = session('lang');
$data['url_id'] = (int) $urlData['url_id'];
$data['url_identifier'] = esc($urlData['url_identifier']);
$data['url_hitscounter'] = $urlData['url_hitscounter'];
$data['go_url'] = $Go_Url;

return view(smarty_view('url/hitslist'), $data);
}

public function hitslistData($urlId)
{
if (! auth()->user()->can('url.access', 'admin.manageotherurls', 'super.admin')) {
return smarty_permission_error(lang('Common.permissionsNoenoughpermissions'), true);
}

$url_id = (int) $urlId;
$userCanAccessUrl = $this->smartyurl->userCanAccessUrlInfo($url_id);
if (! $userCanAccessUrl) {
return smarty_permission_error('It is not your URL 😉😉😉', true);
}

$draw = $this->request->getGet('draw');
$start = $this->request->getGet('start');
$length = $this->request->getGet('length');

// Do not think that the data that comes from the client is always correct
// so set force max length it maxUrlListPerPage
$system_forcemax_length = setting('Smartyurl.maxUrlListPerPage');
if ($length > setting('Smartyurl.maxUrlListPerPage')) {
$length = $system_forcemax_length;
}

$columnOrder = $this->request->getGet('order');
if ($columnOrder !== null) {
$ajax_column_index = $columnOrder['0']['column'];
$order_by_dir = $columnOrder['0']['dir'];

// Do not think that the data that comes from the client is always correct
// so switch it to use defaults
switch ($order_by_dir) {
case 'asc':
$order_by_rule = 'asc';
break;

case 'desc':
$order_by_rule = 'desc';
break;

default:
$order_by_rule = 'desc';
break;
}

// i will know the column name from get
$ajax_columns = $this->request->getGet('columns');
$order_by_ajax_column_name = $ajax_columns[$ajax_column_index]['name'];

// echo $order_by_ajax_column_name;
// echo $order_by_rule;

switch ($order_by_ajax_column_name) {
case 'hit_date':
$order_by = 'urlhit_at';
break;

default:
$order_by = 'urlhit_urlid';
break;
}
} else {
$order_by = 'urlhit_id';
$order_by_rule = 'desc';
}

$urlAllCount = $this->urlhitsmodel->getHitsByUrlId($url_id, null, null, 'urlhit_urlid', 'desc', false);
$filterAllnumRows = $urlAllCount;
$results = $this->urlhitsmodel->getHitsByUrlId($url_id, $start, $length, $order_by, $order_by_rule, true);
$records = [];
if ($results !== null) {
foreach ($results as $result) {
$records[] = [
'hit_date_col' => $result->urlhit_at,
'hit_ip_col' => $result->urlhit_ip,
'hit_country_col' => $result->urlhit_country,
'hit_device_col' => $result->urlhit_visitordevice,
'hit_useragent_col' => esc($result->urlhit_useragent),
'hit_finalurl_col' => esc($result->urlhit_finaltarget),
];
}
}

$data = [
'draw' => $draw,
'recordsTotal' => $urlAllCount, // $urlAllCount
'recordsFiltered' => $filterAllnumRows, // $filterAllnumRows
'data' => $records,
];

return $this->response->setJSON($data);
}

public function generateQRCode($UrlId)
/**
* This function generates QR Code for tge given URL id
*
* @return mixed
*/
public function generateQRCode(int $UrlId)
{
// set response type
$response = service('response');
Expand Down
3 changes: 2 additions & 1 deletion app/Language/ar/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@
'urlInfoNoRecdirectCondition' => 'لم يتم تعريف شروط اعادة توجيه',
'urlInfoLast25Hits' => 'اخر 25 زيارة للرابط',
'urlInfoSeeAllHits' => 'استعراض جميع الزيارات',
'urlInfoSeeAllHitsforURL' => 'استعراض جميع زيارات الرابط',
'urlInfoVisitDate' => 'التاريخ',
'urlInfoVisitorIP' => 'عنوان الاي بي',
'urlInfoVisitorIP' => 'الاي بي',
'urlInfoVisitorCountry' => 'الدولة',
'urlInfoVisitorDevice' => 'الجهاز',
'urlInfoVisitorUserAgent' => 'الوكيل',
Expand Down
1 change: 1 addition & 0 deletions app/Language/en/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
'urlInfoNoRecdirectCondition' => 'No redirect conditions defined',
'urlInfoLast25Hits' => 'URl Last 25 visits',
'urlInfoSeeAllHits' => 'Show all visits',
'urlInfoSeeAllHitsforURL' => 'Show URL visits',
'urlInfoVisitDate' => 'Date',
'urlInfoVisitorIP' => 'IP',
'urlInfoVisitorCountry' => 'Country',
Expand Down
33 changes: 32 additions & 1 deletion app/Models/UrlHitsModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class UrlHitsModel extends BaseModel
{
protected $DBGroup = 'default';
protected $primaryKey = 'id';
protected $primaryKey = 'urlhit_id';
protected $useAutoIncrement = true;
protected $returnType = 'array';
protected $useSoftDeletes = false;
Expand Down Expand Up @@ -55,6 +55,8 @@ protected function initialize(): void
/**
* get the last 25 hits for URL
*
* @param mixed $UrlId
*
* @return mixed
*/
public function getLast25Hits($UrlId)
Expand All @@ -66,4 +68,33 @@ public function getLast25Hits($UrlId)
->get()
->getResult();
}

/**
* This function gets the URL visit list for a given $urlId which can be a single Url ID or an array of Url IDs.
* $returnType can be:
* - true to return data as an array
* - false to return the row count as an integer without the start and limit
*/
public function getHitsByUrlId(int|array $urlId, int|null $start = null, int|null $length = null, string $orderBy = 'urlhit_urlid', string $orderDirection = 'DESC', bool $returnData = true)
{
$builder = $this->builder();

$builder->orderBy($orderBy, $orderDirection);

if (is_array($urlId)) {
$builder->whereIn('urlhit_urlid', $urlId);
} else {
$builder->where('urlhit_urlid', $urlId);
}

if ($start !== null && $length !== null) {
$builder->limit($length, $start);
}

if ($returnData) {
return $builder->get()->getResult();
}

return $builder->countAllResults();
}
}
Loading

0 comments on commit e6cfc70

Please sign in to comment.