Unverified Commit a1d95760 authored by David Morley's avatar David Morley Committed by GitHub

use carbon for nice human dates. add country name in full (#164)

* use carbon for nice human dates. add country name in full

* use carbon for nice human dates. add country name in full

* old axis not used

* Improve usage of Carbon. (#166)

* changelog

* use API for pulls of master version - enforce some security (#159)

* use API for pulls of master version - enforce some security

* add migration

* fix podcrawler

* fix podcrawler

* add diasp.org json active pods
update composer to 7.2 php

* add diasp.org json active pods
update composer to 7.2 php

* remove wizard junk from this branch

* remove wizard junk from this branch

* Revamp masterversionpull fixes (#163)

* Use PHP_SAPI constant to save function call.

* Fix podcrawler to properly filter out only pods that support the diaspora protocol.

* Fix DB write logic and clean up pull.php code a bit.

* Use the best nodeinfo available

* Use the best nodeinfo available, need to default to 1.0

* same order each time vs random

* fix link

* little more universality

* freindica version edit, support as best as can

* using jasonrobinson.me as an example last updated at 2018-04-12 17:23:41.55 is now hidden, giving more time padding for dev branches.

* bower to yarn (#162)

* bower to yarn

* yarn -> Javascript dependencies
composer -> PHP dependencies

* changelog

* Add filter, paging, update menus to make them mobile (#161)

* Add filter, paging, update menus to make them mobile

* remove legacy items unused

* switch from images to css and bigger for fingers

* allow search/filter podmin data

* cleanup

* css important there

* footer mobile fix

* changelog

* use carbon for nice human dates. add country name in full

* Improve usage of Carbon. (#166)
parent 4d45f5b0
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
## DB ## DB
* Add development and release dates to masterversions table https://github.com/diasporg/Poduptime/issues/143 * Add development and release dates to masterversions table https://github.com/diasporg/Poduptime/issues/143
* Store full country name, store days monitored each pod
* DB migrations see db/version.md
## Cleanup ## Cleanup
* Use the git API for release versions, check development releases on pods https://github.com/diasporg/Poduptime/issues/143 * Use the git API for release versions, check development releases on pods https://github.com/diasporg/Poduptime/issues/143
...@@ -16,6 +18,7 @@ ...@@ -16,6 +18,7 @@
* Edit will send to email on file and be less delay, runner of site does not really have anyway to verify email address * Edit will send to email on file and be less delay, runner of site does not really have anyway to verify email address
* Filter and search on the columns of data * Filter and search on the columns of data
* Paginate the results so they fit per page * Paginate the results so they fit per page
* Show time as human readable everywhere
# 2.2.0 # 2.2.0
......
...@@ -8,9 +8,10 @@ ...@@ -8,9 +8,10 @@
"noplanman/xec": "0.1.0", "noplanman/xec": "0.1.0",
"gabordemooij/redbean": "^5.0", "gabordemooij/redbean": "^5.0",
"jaybizzle/crawler-detect" :"1.*", "jaybizzle/crawler-detect" :"1.*",
"commerceguys/enum": "^1.0",
"twbs/bootstrap": "^4.1.0", "twbs/bootstrap": "^4.1.0",
"php" : "^7.2" "php" : "^7.2",
"commerceguys/enum": "^1.0",
"nesbot/carbon": "^1.31"
}, },
"autoload": { "autoload": {
"classmap": ["lib"] "classmap": ["lib"]
......
...@@ -134,6 +134,61 @@ ...@@ -134,6 +134,61 @@
], ],
"time": "2018-06-22T20:32:56+00:00" "time": "2018-06-22T20:32:56+00:00"
}, },
{
"name": "nesbot/carbon",
"version": "1.31.1",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "385780c8ca2dbfd25452666e3f55e8dc1df58c41"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/385780c8ca2dbfd25452666e3f55e8dc1df58c41",
"reference": "385780c8ca2dbfd25452666e3f55e8dc1df58c41",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/translation": "~2.6 || ~3.0 || ~4.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~2",
"phpunit/phpunit": "^4.8.35 || ^5.7"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Carbon\\Laravel\\ServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Brian Nesbitt",
"email": "brian@nesbot.com",
"homepage": "http://nesbot.com"
}
],
"description": "A simple API extension for DateTime.",
"homepage": "http://carbon.nesbot.com",
"keywords": [
"date",
"datetime",
"time"
],
"time": "2018-06-25T13:15:16+00:00"
},
{ {
"name": "noplanman/xec", "name": "noplanman/xec",
"version": "v0.1.0", "version": "v0.1.0",
...@@ -236,6 +291,134 @@ ...@@ -236,6 +291,134 @@
"web" "web"
], ],
"time": "2018-04-09T16:00:23+00:00" "time": "2018-04-09T16:00:23+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.8.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "3296adf6a6454a050679cde90f95350ad604b171"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171",
"reference": "3296adf6a6454a050679cde90f95350ad604b171",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"time": "2018-04-26T10:06:28+00:00"
},
{
"name": "symfony/translation",
"version": "v4.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "b6d8164085ee0b6debcd1b7a131fd6f63bb04854"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/b6d8164085ee0b6debcd1b7a131fd6f63bb04854",
"reference": "b6d8164085ee0b6debcd1b7a131fd6f63bb04854",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"symfony/config": "<3.4",
"symfony/dependency-injection": "<3.4",
"symfony/yaml": "<3.4"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~3.4|~4.0",
"symfony/console": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/finder": "~2.8|~3.0|~4.0",
"symfony/intl": "~3.4|~4.0",
"symfony/yaml": "~3.4|~4.0"
},
"suggest": {
"psr/log-implementation": "To use logging capability in translator",
"symfony/config": "",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Translation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2018-06-22T08:59:39+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],
......
ALTER TABLE masterversions ADD devlastcommit timestamp; ALTER TABLE masterversions ADD devlastcommit timestamp;
ALTER TABLE masterversions ADD releasedate timestamp; ALTER TABLE masterversions ADD releasedate timestamp;
ALTER TABLE pods ADD daysmonitored int, ADD countryname text;
...@@ -220,17 +220,19 @@ foreach ($pods as $pod) { ...@@ -220,17 +220,19 @@ foreach ($pods as $pod) {
$location = geoip_record_by_name($ip); $location = geoip_record_by_name($ip);
_debug('Location', $location, true); _debug('Location', $location, true);
$country = !empty($location['country_code']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['country_code']) : null; $countryname = !empty($location['country_name']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['country_name']) : null;
$city = !empty($location['city']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['city']) : null; $country = !empty($location['country_code']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['country_code']) : null;
$state = !empty($location['region']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['region']) : null; $city = !empty($location['city']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['city']) : null;
$lat = !empty($location['latitude']) ? $location['latitude'] : 0; $state = !empty($location['region']) ? iconv('UTF-8', 'UTF-8//IGNORE', $location['region']) : null;
$long = !empty($location['longitude']) ? $location['longitude'] : 0; $lat = !empty($location['latitude']) ? $location['latitude'] : 0;
$long = !empty($location['longitude']) ? $location['longitude'] : 0;
echo $newline; echo $newline;
$statslastdate = date('Y-m-d H:i:s'); $statslastdate = date('Y-m-d H:i:s');
$diff = (new DateTime())->diff(new DateTime($dateadded)); $diff = (new DateTime())->diff(new DateTime($dateadded));
$months = $diff->m + ($diff->y * 12); $months = $diff->m + ($diff->y * 12);
$days = $diff->days;
try { try {
$checks = R::getRow(' $checks = R::getRow('
...@@ -320,6 +322,7 @@ foreach ($pods as $pod) { ...@@ -320,6 +322,7 @@ foreach ($pods as $pod) {
$p['hidden'] = $hidden; $p['hidden'] = $hidden;
$p['ip'] = $ip; $p['ip'] = $ip;
$p['ipv6'] = $ipv6; $p['ipv6'] = $ipv6;
$p['daysmonitored'] = $days;
$p['monthsmonitored'] = $months; $p['monthsmonitored'] = $months;
$p['uptime_alltime'] = $uptime; $p['uptime_alltime'] = $uptime;
$p['status'] = $status; $p['status'] = $status;
...@@ -329,6 +332,7 @@ foreach ($pods as $pod) { ...@@ -329,6 +332,7 @@ foreach ($pods as $pod) {
$p['score'] = $score; $p['score'] = $score;
$p['adminrating'] = $admin_rating; $p['adminrating'] = $admin_rating;
$p['country'] = $country; $p['country'] = $country;
$p['countryname'] = $countryname;
$p['city'] = $city; $p['city'] = $city;
$p['state'] = $state; $p['state'] = $state;
$p['lat'] = $lat; $p['lat'] = $lat;
......
...@@ -13,6 +13,7 @@ CREATE TABLE pods ( ...@@ -13,6 +13,7 @@ CREATE TABLE pods (
hidden boolean DEFAULT true, hidden boolean DEFAULT true,
ip text, ip text,
country text, country text,
countryname text,
city text, city text,
state text, state text,
lat text, lat text,
...@@ -22,6 +23,7 @@ CREATE TABLE pods ( ...@@ -22,6 +23,7 @@ CREATE TABLE pods (
secure boolean, secure boolean,
sslvalid text, sslvalid text,
monthsmonitored int, monthsmonitored int,
daysmonitored int,
signup boolean, signup boolean,
total_users int, total_users int,
active_users_halfyear int, active_users_halfyear int,
......
<?php <?php
use RedBeanPHP\R; use RedBeanPHP\R;
use Carbon\Carbon;
require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/config.php'; require_once __DIR__ . '/config.php';
...@@ -63,6 +64,54 @@ $navs = [ ...@@ -63,6 +64,54 @@ $navs = [
], ],
]; ];
?> ?>
<nav class="navbar navbar-inverse bg-primary fixed-top">
<button class="navbar-toggler navbar-toggler-right hidden-md-up" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="/">Poduptime</a>
<div class="collapse navbar-toggleable hidden-md-up" id="navbar">
<ul class="navbar-nav">
<?php
foreach ($navs['views'] as $nav_item) {
printf(
'<li class="nav-item"><a class="nav-link%1$s" href="%2$s">%3$s%4$s</a></li>',
$nav_item['active'] ? ' active' : '',
$nav_item['href'],
$nav_item['text'],
$nav_item['active'] ? ' <span class="sr-only">(current)</span>' : ''
);
}
?>
</ul>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="sidebar col-md-3 col-lg-1 hidden-sm-down">
<?php foreach ($navs as $nav) : ?>
<ul class="nav nav-pills flex-column">
<?php
/** @var array $nav */
/** @var array $nav_item */
foreach ($nav as $nav_item) {
printf(
'<li class="nav-item"><a class="nav-link%1$s" href="%2$s">%3$s%4$s</a></li>',
$nav_item['active'] ? ' active' : '',
$nav_item['href'],
$nav_item['text'],
$nav_item['active'] ? ' <span class="sr-only">(current)</span>' : ''
);
}
?>
</ul>
<hr>
<?php endforeach; ?>
<p>
<small>Data refreshed: <br><?php echo Carbon::createFromTimestamp(filemtime($lastfile))->diffForHumans(); ?></small>
</p>
<header> <header>
<div class="collapse bg-dark" id="navbarHeader"> <div class="collapse bg-dark" id="navbarHeader">
<div class="container"> <div class="container">
......
<?php <?php
use RedBeanPHP\R; use RedBeanPHP\R;
use Carbon\Carbon;
defined('PODUPTIME') || die(); defined('PODUPTIME') || die();
try { try {
$pods = R::getAll(' $pods = R::getAll('
SELECT domain, masterversion, shortversion, softwarename, monthsmonitored, podmin_statement, score, signup, name, country, city, state, uptime_alltime, active_users_halfyear, active_users_monthly, service_facebook, service_twitter, service_tumblr, service_wordpress, service_xmpp SELECT domain, masterversion, shortversion, softwarename, daysmonitored, podmin_statement, score, signup, name, country, countryname, city, state, uptime_alltime, active_users_halfyear, active_users_monthly, service_facebook, service_twitter, service_tumblr, service_wordpress, service_xmpp
FROM pods FROM pods
WHERE NOT hidden WHERE NOT hidden
AND status = ? AND status = ?
...@@ -38,12 +39,8 @@ try { ...@@ -38,12 +39,8 @@ try {
foreach ($pods as $pod) { foreach ($pods as $pod) {
$verdiff = str_replace('.', '', $pod['masterversion']) - str_replace('.', '', $pod['shortversion']); $verdiff = str_replace('.', '', $pod['masterversion']) - str_replace('.', '', $pod['shortversion']);
$pod_name = htmlentities($pod['name'], ENT_QUOTES); $pod_name = htmlentities($pod['name'], ENT_QUOTES);
$tip = sprintf( $humanmonitored = Carbon::now()->subDays($pod['daysmonitored'])->diffForHumans(null, true);
'This %3$s pod\'s uptime is %2$s%% over %1$s months.', $tip = "This {$pod['softwarename']} pod's uptime is {$pod['uptime_alltime']}% over {$humanmonitored}.";
$pod['monthsmonitored'],
$pod['uptime_alltime'],
$pod['softwarename']
);
echo '<tr><td><div title="' . $tip . '" data-toggle="tooltip" data-placement="bottom"><a class="text-success url" target="_self" href="/go.php?domain=' . $pod['domain'] . '">' . $pod['domain'] . '</a></div></td>'; echo '<tr><td><div title="' . $tip . '" data-toggle="tooltip" data-placement="bottom"><a class="text-success url" target="_self" href="/go.php?domain=' . $pod['domain'] . '">' . $pod['domain'] . '</a></div></td>';
echo '<td>' . $pod['uptime_alltime'] . '%</td>'; echo '<td>' . $pod['uptime_alltime'] . '%</td>';
...@@ -53,9 +50,9 @@ try { ...@@ -53,9 +50,9 @@ try {
echo '<td data-toggle="tooltip" data-placement="bottom" title="Pod does not share user data."></td>'; echo '<td data-toggle="tooltip" data-placement="bottom" title="Pod does not share user data."></td>';
} }
if ($country_code === $pod['country']) { if ($country_code === $pod['country']) {
echo '<td class="text-success" data-toggle="tooltip" data-placement="bottom" title="City: ' . ($pod['city'] ?? 'n/a') . ', State: ' . ($pod['state'] ?? 'n/a') . '"><b>' . $pod['country'] . '</b></td>'; echo '<td class="text-success" data-toggle="tooltip" data-placement="bottom" title="Country: ' . ($pod['countryname'] ?? 'n/a') . '&#0010;City: ' . ($pod['city'] ?? 'n/a') . '&#0010;State: ' . ($pod['state'] ?? 'n/a') . '"><b>' . $pod['country'] . '</b></td>';
} else { } else {
echo '<td data-toggle="tooltip" data-placement="bottom" title="City: ' . ($pod['city'] ?? 'n/a') . ', State: ' . ($pod['state'] ?? 'n/a') . '">' . $pod['country'] . '</td>'; echo '<td data-toggle="tooltip" data-placement="bottom" title="Country: ' . ($pod['countryname'] ?? 'n/a') . '&#0010;City: ' . ($pod['city'] ?? 'n/a') . '&#0010;State: ' . ($pod['state'] ?? 'n/a') . '">' . $pod['country'] . '</td>';
} }
echo '<td>'; echo '<td>';
$pod['service_facebook'] && print '<div class="smlogo smlogo-facebook" title="Publish to Facebook"></div>'; $pod['service_facebook'] && print '<div class="smlogo smlogo-facebook" title="Publish to Facebook"></div>';
......
<?php <?php
use RedBeanPHP\R; use RedBeanPHP\R;
use Carbon\Carbon;
defined('PODUPTIME') || die(); defined('PODUPTIME') || die();
try { try {
$pods = R::getAll(' $pods = R::getAll('
SELECT domain, dnssec, podmin_statement, sslexpire, masterversion, shortversion, softwarename, monthsmonitored, score, signup, name, country, city, state, lat, long, uptime_alltime, active_users_halfyear, active_users_monthly, service_facebook, service_twitter, service_tumblr, service_wordpress, service_xmpp, latency, date_updated, ipv6, total_users, local_posts, comment_counts, userrating, status SELECT domain, dnssec, podmin_statement, sslexpire, masterversion, shortversion, softwarename, daysmonitored, monthsmonitored, score, signup, name, country, countryname, city, state, lat, long, uptime_alltime, active_users_halfyear, active_users_monthly, service_facebook, service_twitter, service_tumblr, service_wordpress, service_xmpp, latency, date_updated, ipv6, total_users, local_posts, comment_counts, userrating, status
FROM pods FROM pods
WHERE status < ? WHERE status < ?
ORDER BY weightedscore DESC ORDER BY weightedscore DESC
...@@ -47,7 +48,10 @@ try { ...@@ -47,7 +48,10 @@ try {
<?php <?php
foreach ($pods as $pod) { foreach ($pods as $pod) {
$pod_name = htmlentities($pod['name'], ENT_QUOTES); $pod_name = htmlentities($pod['name'], ENT_QUOTES);
$tip = "\n Over {$pod['monthsmonitored']} months uptime is {$pod['uptime_alltime']}% and response time is {$pod['latency']}ms, last check on {$pod['date_updated']}. This site is SSL/TLS encrypted with a cert that expires: " . $pod['sslexpire']; $humanmonitored = Carbon::now()->subDays($pod['daysmonitored'])->diffForHumans(null, true);
$humanlastcheck = (new Carbon($pod['date_updated']))->diffForHumans();
$humansslexpire = (new Carbon($pod['sslexpire']))->diffForHumans();
$tip = "\nOver the last {$humanmonitored} pod uptime was {$pod['uptime_alltime']}% and response time from Los Angeles was {$pod['latency']}ms, with a SSL cert that expires {$humansslexpire}. This pod was last checked {$humanlastcheck}";
echo '<tr><td><a title="' . $tip . '" class="text-success url" data-toggle="tooltip" data-placement="bottom" target="_self" href="/go.php?domain=' . $pod['domain'] . '">' . $pod['domain'] . '</a></td>'; echo '<tr><td><a title="' . $tip . '" class="text-success url" data-toggle="tooltip" data-placement="bottom" target="_self" href="/go.php?domain=' . $pod['domain'] . '">' . $pod['domain'] . '</a></td>';
...@@ -79,14 +83,14 @@ try { ...@@ -79,14 +83,14 @@ try {
echo '<td>' . ($pod['active_users_monthly'] > 0 ? $pod['active_users_monthly'] : '') . '</td>'; echo '<td>' . ($pod['active_users_monthly'] > 0 ? $pod['active_users_monthly'] : '') . '</td>';
echo '<td>' . ($pod['local_posts'] > 0 ? $pod['local_posts'] : '') . '</td>'; echo '<td>' . ($pod['local_posts'] > 0 ? $pod['local_posts'] : '') . '</td>';
echo '<td>' . ($pod['comment_counts'] > 0 ? $pod['comment_counts'] : '') . '</td>'; echo '<td>' . ($pod['comment_counts'] > 0 ? $pod['comment_counts'] : '') . '</td>';
echo '<td><div title="Last Check ' . $pod['date_updated'] . '" data-toggle="tooltip" data-placement="bottom">' . $pod['monthsmonitored'] . '</div></td>'; echo '<td><div title="This pod has been monitored ' . $humanmonitored . '" data-toggle="tooltip" data-placement="bottom">' . $pod['monthsmonitored'] . '</div></td>';
echo '<td><a rel="facebox" href="rate.php?domain=' . $pod['domain'] . '">' . $pod['userrating'] . '</a></td>'; echo '<td><a rel="facebox" href="rate.php?domain=' . $pod['domain'] . '">' . $pod['userrating'] . '</a></td>';
echo '<td><div title="Pod Status is: ' . PodStatus::getKey((int)$pod['status']) . '" data-toggle="tooltip" data-placement="bottom">' . $pod['score'] . '</div></td>'; echo '<td><div title="Pod Status is: ' . PodStatus::getKey((int)$pod['status']) . '" data-toggle="tooltip" data-placement="bottom">' . $pod['score'] . '</div></td>';
echo '<td>' . ($pod['dnssec'] ? 'Y' : 'N') . '</td>'; echo '<td>' . ($pod['dnssec'] ? 'Y' : 'N') . '</td>';
if ($country_code === $pod['country']) { if ($country_code === $pod['country']) {
echo '<td class="text-success" data-toggle="tooltip" data-placement="bottom" title="City: ' . ($pod['city'] ?? 'n/a') . ' State: ' . ($pod['state'] ?? 'n/a') . '"><b>' . $pod['country'] . '</b></td>'; echo '<td class="text-success" data-toggle="tooltip" data-placement="bottom" title="Country: ' . ($pod['countryname'] ?? 'n/a') . ' City: ' . ($pod['city'] ?? 'n/a') . ' State: ' . ($pod['state'] ?? 'n/a') . '"><b>' . $pod['country'] . '</b></td>';
} else { } else {
echo '<td data-toggle="tooltip" data-placement="bottom" title="City: ' . ($pod['city'] ?? 'n/a') . ' State: ' . ($pod['state'] ?? 'n/a') . '">' . $pod['country'] . '</td>'; echo '<td data-toggle="tooltip" data-placement="bottom" title="Country: ' . ($pod['countryname'] ?? 'n/a') . ' City: ' . ($pod['city'] ?? 'n/a') . ' State: ' . ($pod['state'] ?? 'n/a') . '">' . $pod['country'] . '</td>';
} }
echo '<td>'; echo '<td>';
$pod['service_facebook'] && print '<div class="smlogo smlogo-facebook" title="Publish to Facebook"></div>'; $pod['service_facebook'] && print '<div class="smlogo smlogo-facebook" title="Publish to Facebook"></div>';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment