Split Utilities apart into individual categories.
This commit is contained in:
parent
a228e5def3
commit
4ca8ce0bc6
|
@ -117,34 +117,51 @@ class BackupCommand extends CommandAbstract
|
|||
$io->section(__('Creating backup archive...'));
|
||||
|
||||
// Strip leading slashes from backup paths.
|
||||
$files_to_backup = array_map(function ($val) {
|
||||
if (0 === strpos($val, '/')) {
|
||||
return substr($val, 1);
|
||||
}
|
||||
return $val;
|
||||
}, $files_to_backup);
|
||||
$files_to_backup = array_map(
|
||||
function ($val) {
|
||||
if (0 === strpos($val, '/')) {
|
||||
return substr($val, 1);
|
||||
}
|
||||
return $val;
|
||||
},
|
||||
$files_to_backup
|
||||
);
|
||||
|
||||
switch ($file_ext) {
|
||||
case 'gz':
|
||||
case 'tgz':
|
||||
$this->passThruProcess($io, array_merge([
|
||||
'tar',
|
||||
'zcvf',
|
||||
$tmpPath,
|
||||
], $files_to_backup), '/');
|
||||
$this->passThruProcess(
|
||||
$io,
|
||||
array_merge(
|
||||
[
|
||||
'tar',
|
||||
'zcvf',
|
||||
$tmpPath,
|
||||
],
|
||||
$files_to_backup
|
||||
),
|
||||
'/'
|
||||
);
|
||||
break;
|
||||
|
||||
case 'zip':
|
||||
default:
|
||||
$dont_compress = ['.tar.gz', '.zip', '.jpg', '.mp3', '.ogg', '.flac', '.aac', '.wav'];
|
||||
|
||||
$this->passThruProcess($io, array_merge([
|
||||
'zip',
|
||||
'-r',
|
||||
'-n',
|
||||
implode(':', $dont_compress),
|
||||
$tmpPath,
|
||||
], $files_to_backup), '/');
|
||||
$this->passThruProcess(
|
||||
$io,
|
||||
array_merge(
|
||||
[
|
||||
'zip',
|
||||
'-r',
|
||||
'-n',
|
||||
implode(':', $dont_compress),
|
||||
$tmpPath,
|
||||
],
|
||||
$files_to_backup
|
||||
),
|
||||
'/'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -158,16 +175,18 @@ class BackupCommand extends CommandAbstract
|
|||
// Cleanup
|
||||
$io->section(__('Cleaning up temporary files...'));
|
||||
|
||||
Utilities::rmdirRecursive($tmp_dir_mariadb);
|
||||
Utilities\File::rmdirRecursive($tmp_dir_mariadb);
|
||||
|
||||
$io->newLine();
|
||||
|
||||
$end_time = microtime(true);
|
||||
$time_diff = $end_time - $start_time;
|
||||
|
||||
$io->success([
|
||||
__('Backup complete in %.2f seconds.', $time_diff),
|
||||
]);
|
||||
$io->success(
|
||||
[
|
||||
__('Backup complete in %.2f seconds.', $time_diff),
|
||||
]
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,19 +43,27 @@ class RestoreCommand extends CommandAbstract
|
|||
switch ($file_ext) {
|
||||
case 'gz':
|
||||
case 'tgz':
|
||||
$this->passThruProcess($io, [
|
||||
'tar',
|
||||
'zxvf',
|
||||
$path,
|
||||
], '/');
|
||||
$this->passThruProcess(
|
||||
$io,
|
||||
[
|
||||
'tar',
|
||||
'zxvf',
|
||||
$path,
|
||||
],
|
||||
'/'
|
||||
);
|
||||
break;
|
||||
|
||||
case 'zip':
|
||||
default:
|
||||
$this->passThruProcess($io, [
|
||||
'unzip',
|
||||
$path,
|
||||
], '/');
|
||||
$this->passThruProcess(
|
||||
$io,
|
||||
[
|
||||
'unzip',
|
||||
$path,
|
||||
],
|
||||
'/'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -88,7 +96,7 @@ class RestoreCommand extends CommandAbstract
|
|||
]
|
||||
);
|
||||
|
||||
Utilities::rmdirRecursive($tmp_dir_mariadb);
|
||||
Utilities\File::rmdirRecursive($tmp_dir_mariadb);
|
||||
$io->newLine();
|
||||
|
||||
// Update from current version to latest.
|
||||
|
@ -99,9 +107,11 @@ class RestoreCommand extends CommandAbstract
|
|||
$end_time = microtime(true);
|
||||
$time_diff = $end_time - $start_time;
|
||||
|
||||
$io->success([
|
||||
'Restore complete in ' . round($time_diff, 3) . ' seconds.',
|
||||
]);
|
||||
$io->success(
|
||||
[
|
||||
'Restore complete in ' . round($time_diff, 3) . ' seconds.',
|
||||
]
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ class ListCommand extends CommandAbstract
|
|||
$all_settings = $settingsTableRepo->readSettingsArray();
|
||||
foreach ($all_settings as $setting_key => $setting_value) {
|
||||
$value = print_r($setting_value, true);
|
||||
$value = Utilities::truncateText($value, 600);
|
||||
$value = Utilities\Strings::truncateText($value, 600);
|
||||
|
||||
$rows[] = [$setting_key, $value];
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ class ResetPasswordCommand extends CommandAbstract
|
|||
->findOneBy(['email' => $email]);
|
||||
|
||||
if ($user instanceof Entity\User) {
|
||||
$temp_pw = Utilities::generatePassword(15);
|
||||
$temp_pw = Utilities\Strings::generatePassword(15);
|
||||
|
||||
$user->setNewPassword($temp_pw);
|
||||
$user->setTwoFactorSecret(null);
|
||||
|
|
|
@ -6,7 +6,6 @@ use App\Config;
|
|||
use App\Controller\AbstractLogViewerController;
|
||||
use App\Entity;
|
||||
use App\Exception\NotFoundException;
|
||||
use App\File;
|
||||
use App\Flysystem\Filesystem;
|
||||
use App\Form\BackupSettingsForm;
|
||||
use App\Form\Form;
|
||||
|
@ -15,6 +14,7 @@ use App\Http\ServerRequest;
|
|||
use App\Message\BackupMessage;
|
||||
use App\Session\Flash;
|
||||
use App\Sync\Task\RunBackupTask;
|
||||
use App\Utilities\File;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Symfony\Component\Messenger\MessageBus;
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ namespace App\Controller\Admin;
|
|||
use App\Console\Application;
|
||||
use App\Controller\AbstractLogViewerController;
|
||||
use App\Entity;
|
||||
use App\File;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Message\RunSyncTaskMessage;
|
||||
|
@ -14,6 +13,7 @@ use App\Radio\AutoDJ;
|
|||
use App\Radio\Backend\Liquidsoap;
|
||||
use App\Session\Flash;
|
||||
use App\Sync\Runner;
|
||||
use App\Utilities\File;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
|
@ -53,11 +53,15 @@ class DebugController extends AbstractLogViewerController
|
|||
$queueTotals[$queue] = $queueManager->getQueueCount($queue);
|
||||
}
|
||||
|
||||
return $request->getView()->renderToResponse($response, 'admin/debug/index', [
|
||||
'sync_times' => $sync->getSyncTimes(),
|
||||
'queue_totals' => $queueTotals,
|
||||
'stations' => $stationRepo->fetchArray(),
|
||||
]);
|
||||
return $request->getView()->renderToResponse(
|
||||
$response,
|
||||
'admin/debug/index',
|
||||
[
|
||||
'sync_times' => $sync->getSyncTimes(),
|
||||
'queue_totals' => $queueTotals,
|
||||
'stations' => $stationRepo->fetchArray(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function syncAction(
|
||||
|
@ -73,10 +77,14 @@ class DebugController extends AbstractLogViewerController
|
|||
|
||||
$this->messageBus->dispatch($message);
|
||||
|
||||
return $request->getView()->renderToResponse($response, 'admin/debug/sync', [
|
||||
'title' => __('Run Synchronized Task'),
|
||||
'outputLog' => basename($tempFile),
|
||||
]);
|
||||
return $request->getView()->renderToResponse(
|
||||
$response,
|
||||
'admin/debug/sync',
|
||||
[
|
||||
'title' => __('Run Synchronized Task'),
|
||||
'outputLog' => basename($tempFile),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function logAction(
|
||||
|
@ -112,11 +120,15 @@ class DebugController extends AbstractLogViewerController
|
|||
|
||||
$this->logger->popHandler();
|
||||
|
||||
return $request->getView()->renderToResponse($response, 'system/log_view', [
|
||||
'sidebar' => null,
|
||||
'title' => __('Debug Output'),
|
||||
'log_records' => $this->testHandler->getRecords(),
|
||||
]);
|
||||
return $request->getView()->renderToResponse(
|
||||
$response,
|
||||
'system/log_view',
|
||||
[
|
||||
'sidebar' => null,
|
||||
'title' => __('Debug Output'),
|
||||
'log_records' => $this->testHandler->getRecords(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function telnetAction(
|
||||
|
@ -132,18 +144,25 @@ class DebugController extends AbstractLogViewerController
|
|||
$command = $request->getParam('command');
|
||||
|
||||
$telnetResponse = $backend->command($station, $command);
|
||||
$this->logger->debug('Telnet Command Response', [
|
||||
'response' => $telnetResponse,
|
||||
]);
|
||||
$this->logger->debug(
|
||||
'Telnet Command Response',
|
||||
[
|
||||
'response' => $telnetResponse,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$this->logger->popHandler();
|
||||
|
||||
return $request->getView()->renderToResponse($response, 'system/log_view', [
|
||||
'sidebar' => null,
|
||||
'title' => __('Debug Output'),
|
||||
'log_records' => $this->testHandler->getRecords(),
|
||||
]);
|
||||
return $request->getView()->renderToResponse(
|
||||
$response,
|
||||
'system/log_view',
|
||||
[
|
||||
'sidebar' => null,
|
||||
'title' => __('Debug Output'),
|
||||
'log_records' => $this->testHandler->getRecords(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function clearCacheAction(
|
||||
|
|
|
@ -54,7 +54,7 @@ abstract class AbstractApiCrudController
|
|||
|
||||
// Older jQuery Bootgrid requests should be "flattened".
|
||||
if ($is_bootgrid && !$is_internal) {
|
||||
return Utilities::flattenArray($return, '_');
|
||||
return Utilities\Arrays::flattenArray($return, '_');
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
|
|
@ -44,7 +44,8 @@ class ListAction
|
|||
: $currentDir . '/%';
|
||||
|
||||
$media_query = $em->createQueryBuilder()
|
||||
->select('partial sm.{
|
||||
->select(
|
||||
'partial sm.{
|
||||
id,
|
||||
unique_id,
|
||||
art_updated_at,
|
||||
|
@ -55,7 +56,8 @@ class ListAction
|
|||
title,
|
||||
album,
|
||||
genre
|
||||
}')
|
||||
}'
|
||||
)
|
||||
->addSelect('partial spm.{id}, partial sp.{id, name}')
|
||||
->addSelect('partial smcf.{id, field_id, value}')
|
||||
->from(Entity\StationMedia::class, 'sm')
|
||||
|
@ -178,9 +180,12 @@ class ListAction
|
|||
$files[] = $short_path;
|
||||
}
|
||||
} else {
|
||||
$filesIterator = $fs->createIterator($currentDir, [
|
||||
Options::OPTION_IS_RECURSIVE => false,
|
||||
]);
|
||||
$filesIterator = $fs->createIterator(
|
||||
$currentDir,
|
||||
[
|
||||
Options::OPTION_IS_RECURSIVE => false,
|
||||
]
|
||||
);
|
||||
|
||||
$protectedPaths = [Entity\StationMedia::DIR_ALBUM_ART, Entity\StationMedia::DIR_WAVEFORMS];
|
||||
|
||||
|
@ -253,7 +258,7 @@ class ListAction
|
|||
$sort_by[] = SORT_ASC;
|
||||
}
|
||||
|
||||
$result = Utilities::arrayOrderBy($result, $sort_by);
|
||||
$result = Utilities\Arrays::arrayOrderBy($result, $sort_by);
|
||||
|
||||
$num_results = count($result);
|
||||
|
||||
|
@ -276,11 +281,13 @@ class ListAction
|
|||
$return_result = [];
|
||||
}
|
||||
|
||||
return $response->withJson([
|
||||
'current' => $page,
|
||||
'rowCount' => $row_count,
|
||||
'total' => $num_results,
|
||||
'rows' => $return_result,
|
||||
]);
|
||||
return $response->withJson(
|
||||
[
|
||||
'current' => $page,
|
||||
'rowCount' => $row_count,
|
||||
'total' => $num_results,
|
||||
'rows' => $return_result,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ class HistoryController
|
|||
$row->resolveUrls($router->getBaseUrl());
|
||||
|
||||
if ($is_bootgrid) {
|
||||
return App\Utilities::flattenArray($row, '_');
|
||||
return App\Utilities\Arrays::flattenArray($row, '_');
|
||||
}
|
||||
|
||||
return $row;
|
||||
|
|
|
@ -144,7 +144,7 @@ class ListAction
|
|||
|
||||
$row->resolveUrls($router->getBaseUrl());
|
||||
|
||||
$list[] = Utilities::flattenArray($row, '_');
|
||||
$list[] = Utilities\Arrays::flattenArray($row, '_');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,24 +108,29 @@ class RequestsController
|
|||
$is_bootgrid = $paginator->isFromBootgrid();
|
||||
$router = $request->getRouter();
|
||||
|
||||
$paginator->setPostprocessor(function ($media_row) use ($station, $is_bootgrid, $router) {
|
||||
/** @var Entity\StationMedia $media_row */
|
||||
$row = new Entity\Api\StationRequest();
|
||||
$row->song = ($this->songApiGenerator)($media_row);
|
||||
$row->request_id = $media_row->getUniqueId();
|
||||
$row->request_url = (string)$router->named('api:requests:submit', [
|
||||
'station_id' => $station->getId(),
|
||||
'media_id' => $media_row->getUniqueId(),
|
||||
]);
|
||||
$paginator->setPostprocessor(
|
||||
function ($media_row) use ($station, $is_bootgrid, $router) {
|
||||
/** @var Entity\StationMedia $media_row */
|
||||
$row = new Entity\Api\StationRequest();
|
||||
$row->song = ($this->songApiGenerator)($media_row);
|
||||
$row->request_id = $media_row->getUniqueId();
|
||||
$row->request_url = (string)$router->named(
|
||||
'api:requests:submit',
|
||||
[
|
||||
'station_id' => $station->getId(),
|
||||
'media_id' => $media_row->getUniqueId(),
|
||||
]
|
||||
);
|
||||
|
||||
$row->resolveUrls($router->getBaseUrl());
|
||||
$row->resolveUrls($router->getBaseUrl());
|
||||
|
||||
if ($is_bootgrid) {
|
||||
return Utilities::flattenArray($row, '_');
|
||||
if ($is_bootgrid) {
|
||||
return Utilities\Arrays::flattenArray($row, '_');
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
return $row;
|
||||
});
|
||||
);
|
||||
|
||||
return $paginator->write($response);
|
||||
}
|
||||
|
@ -175,7 +180,13 @@ class RequestsController
|
|||
$isAuthenticated = ($user instanceof Entity\User);
|
||||
|
||||
try {
|
||||
$this->requestRepo->submit($station, $media_id, $isAuthenticated, $request->getIp());
|
||||
$this->requestRepo->submit(
|
||||
$station,
|
||||
$media_id,
|
||||
$isAuthenticated,
|
||||
$request->getIp(),
|
||||
$request->getHeaderLine('User-Agent')
|
||||
);
|
||||
|
||||
return $response->withJson(new Entity\Api\Status(true, __('Request submitted successfully.')));
|
||||
} catch (Exception $e) {
|
||||
|
|
|
@ -4,12 +4,12 @@ namespace App\Controller\Api\Stations\Streamers;
|
|||
|
||||
use App\Controller\Api\AbstractApiCrudController;
|
||||
use App\Entity;
|
||||
use App\File;
|
||||
use App\Flysystem\FilesystemManager;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Paginator\QueryPaginator;
|
||||
use App\Utilities;
|
||||
use App\Utilities\File;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class BroadcastsController extends AbstractApiCrudController
|
||||
|
@ -55,46 +55,48 @@ class BroadcastsController extends AbstractApiCrudController
|
|||
|
||||
$fs = $filesystem->getForStation($station);
|
||||
|
||||
$paginator->setPostprocessor(function ($row) use ($is_bootgrid, $router, $fs) {
|
||||
/** @var Entity\StationStreamerBroadcast $row */
|
||||
$return = $this->toArray($row);
|
||||
$paginator->setPostprocessor(
|
||||
function ($row) use ($is_bootgrid, $router, $fs) {
|
||||
/** @var Entity\StationStreamerBroadcast $row */
|
||||
$return = $this->toArray($row);
|
||||
|
||||
unset($return['recordingPath']);
|
||||
unset($return['recordingPath']);
|
||||
|
||||
$recordingPath = $row->getRecordingPath();
|
||||
$recordingUri = FilesystemManager::PREFIX_RECORDINGS . '://' . $recordingPath;
|
||||
$recordingPath = $row->getRecordingPath();
|
||||
$recordingUri = FilesystemManager::PREFIX_RECORDINGS . '://' . $recordingPath;
|
||||
|
||||
if ($fs->has($recordingUri)) {
|
||||
$recordingMeta = $fs->getMetadata($recordingUri);
|
||||
if ($fs->has($recordingUri)) {
|
||||
$recordingMeta = $fs->getMetadata($recordingUri);
|
||||
|
||||
$return['recording'] = [
|
||||
'path' => $recordingPath,
|
||||
'size' => $recordingMeta['size'],
|
||||
'links' => [
|
||||
'download' => $router->fromHere(
|
||||
'api:stations:streamer:broadcast:download',
|
||||
['broadcast_id' => $row->getId()],
|
||||
[],
|
||||
true
|
||||
),
|
||||
'delete' => $router->fromHere(
|
||||
'api:stations:streamer:broadcast:delete',
|
||||
['broadcast_id' => $row->getId()],
|
||||
[],
|
||||
true
|
||||
),
|
||||
],
|
||||
];
|
||||
} else {
|
||||
$return['recording'] = [];
|
||||
$return['recording'] = [
|
||||
'path' => $recordingPath,
|
||||
'size' => $recordingMeta['size'],
|
||||
'links' => [
|
||||
'download' => $router->fromHere(
|
||||
'api:stations:streamer:broadcast:download',
|
||||
['broadcast_id' => $row->getId()],
|
||||
[],
|
||||
true
|
||||
),
|
||||
'delete' => $router->fromHere(
|
||||
'api:stations:streamer:broadcast:delete',
|
||||
['broadcast_id' => $row->getId()],
|
||||
[],
|
||||
true
|
||||
),
|
||||
],
|
||||
];
|
||||
} else {
|
||||
$return['recording'] = [];
|
||||
}
|
||||
|
||||
if ($is_bootgrid) {
|
||||
return Utilities\Arrays::flattenArray($return, '_');
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
if ($is_bootgrid) {
|
||||
return Utilities::flattenArray($return, '_');
|
||||
}
|
||||
|
||||
return $return;
|
||||
});
|
||||
);
|
||||
|
||||
return $paginator->write($response);
|
||||
}
|
||||
|
@ -177,20 +179,24 @@ class BroadcastsController extends AbstractApiCrudController
|
|||
protected function getRecord(Entity\Station $station, int $id): ?Entity\StationStreamerBroadcast
|
||||
{
|
||||
/** @var Entity\StationStreamerBroadcast|null $broadcast */
|
||||
$broadcast = $this->em->getRepository(Entity\StationStreamerBroadcast::class)->findOneBy([
|
||||
'id' => $id,
|
||||
'station' => $station,
|
||||
]);
|
||||
$broadcast = $this->em->getRepository(Entity\StationStreamerBroadcast::class)->findOneBy(
|
||||
[
|
||||
'id' => $id,
|
||||
'station' => $station,
|
||||
]
|
||||
);
|
||||
return $broadcast;
|
||||
}
|
||||
|
||||
protected function getStreamer(Entity\Station $station, int $id): ?Entity\StationStreamer
|
||||
{
|
||||
/** @var Entity\StationStreamer|null $streamer */
|
||||
$streamer = $this->em->getRepository(Entity\StationStreamer::class)->findOneBy([
|
||||
'id' => $id,
|
||||
'station' => $station,
|
||||
]);
|
||||
$streamer = $this->em->getRepository(Entity\StationStreamer::class)->findOneBy(
|
||||
[
|
||||
'id' => $id,
|
||||
'station' => $station,
|
||||
]
|
||||
);
|
||||
return $streamer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Entity\Api;
|
||||
|
||||
use App\File;
|
||||
use App\Utilities\File;
|
||||
use OpenApi\Annotations as OA;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
|
|
|
@ -292,7 +292,7 @@ class StationRepository extends Repository
|
|||
|
||||
// Remove media folders.
|
||||
$radio_dir = $station->getRadioBaseDir();
|
||||
Utilities::rmdirRecursive($radio_dir);
|
||||
Utilities\File::rmdirRecursive($radio_dir);
|
||||
|
||||
// Save changes and continue to the last setup step.
|
||||
$this->em->flush();
|
||||
|
|
|
@ -7,7 +7,6 @@ use App\Entity;
|
|||
use App\Environment;
|
||||
use App\Exception;
|
||||
use App\Radio\AutoDJ;
|
||||
use App\Utilities;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Carbon\CarbonInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
@ -34,10 +33,11 @@ class StationRequestRepository extends Repository
|
|||
Entity\Station $station,
|
||||
string $trackId,
|
||||
bool $isAuthenticated,
|
||||
string $ip
|
||||
string $ip,
|
||||
string $userAgent
|
||||
): int {
|
||||
// Forbid web crawlers from using this feature.
|
||||
if (Utilities::isCrawler()) {
|
||||
if ($this->isCrawler($userAgent)) {
|
||||
throw new Exception(__('Search engine crawlers are not permitted to use this feature.'));
|
||||
}
|
||||
|
||||
|
@ -84,9 +84,11 @@ class StationRequestRepository extends Repository
|
|||
->getArrayResult();
|
||||
|
||||
if (count($recent_requests) > 0) {
|
||||
throw new Exception(__(
|
||||
'You have submitted a request too recently! Please wait before submitting another one.'
|
||||
));
|
||||
throw new Exception(
|
||||
__(
|
||||
'You have submitted a request too recently! Please wait before submitting another one.'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,6 +100,26 @@ class StationRequestRepository extends Repository
|
|||
return $record->getId();
|
||||
}
|
||||
|
||||
protected function isCrawler(string $userAgent): bool
|
||||
{
|
||||
$userAgent = strtolower($userAgent);
|
||||
|
||||
// phpcs:disable Generic.Files.LineLength
|
||||
$crawlers_agents = strtolower(
|
||||
'Bloglines subscriber|Dumbot|Sosoimagespider|QihooBot|FAST-WebCrawler|Superdownloads Spiderman|LinkWalker|msnbot|ASPSeek|WebAlta Crawler|Lycos|FeedFetcher-Google|Yahoo|YoudaoBot|AdsBot-Google|Googlebot|Scooter|Gigabot|Charlotte|eStyle|AcioRobot|GeonaBot|msnbot-media|Baidu|CocoCrawler|Google|Charlotte t|Yahoo! Slurp China|Sogou web spider|YodaoBot|MSRBOT|AbachoBOT|Sogou head spider|AltaVista|IDBot|Sosospider|Yahoo! Slurp|Java VM|DotBot|LiteFinder|Yeti|Rambler|Scrubby|Baiduspider|accoona'
|
||||
);
|
||||
// phpcs:enable
|
||||
$crawlers = explode('|', $crawlers_agents);
|
||||
|
||||
foreach ($crawlers as $crawler) {
|
||||
if (strpos($userAgent, trim($crawler)) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the song is already enqueued as a request.
|
||||
*
|
||||
|
@ -211,9 +233,11 @@ class StationRequestRepository extends Repository
|
|||
$isDuplicate = (null === AutoDJ\Queue::getDistinctTrack($eligibleTracks, $recentTracks));
|
||||
|
||||
if ($isDuplicate) {
|
||||
throw new Exception(__(
|
||||
'This song or artist has been played too recently. Wait a while before requesting it again.'
|
||||
));
|
||||
throw new Exception(
|
||||
__(
|
||||
'This song or artist has been played too recently. Wait a while before requesting it again.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -6,9 +6,9 @@ namespace App\Entity;
|
|||
|
||||
use App\Annotations\AuditLog;
|
||||
use App\Environment;
|
||||
use App\File;
|
||||
use App\Normalizer\Annotation\DeepNormalize;
|
||||
use App\Radio\Adapters;
|
||||
use App\Utilities\File;
|
||||
use App\Validator\Constraints as AppAssert;
|
||||
use DateTimeZone;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
|
|
@ -530,7 +530,7 @@ class StationRemote implements StationMountInterface
|
|||
return $this->autodj_bitrate . 'kbps ' . strtoupper($this->autodj_format);
|
||||
}
|
||||
|
||||
return Utilities::truncateUrl($this->url);
|
||||
return Utilities\Strings::truncateUrl($this->url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,7 +48,7 @@ class GetId3MetadataManager implements MetadataManagerInterface
|
|||
if (!empty($tagContents[0]) && !$metaTags->containsKey($tagName)) {
|
||||
$tagValue = $tagContents[0];
|
||||
if (is_array($tagValue)) {
|
||||
$flatValue = Utilities::flattenArray($tagValue);
|
||||
$flatValue = Utilities\Arrays::flattenArray($tagValue);
|
||||
$tagValue = implode(', ', $flatValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -129,10 +129,10 @@ class Icecast extends AbstractFrontend
|
|||
'burst-size' => 65535,
|
||||
],
|
||||
'authentication' => [
|
||||
'source-password' => Utilities::generatePassword(),
|
||||
'relay-password' => Utilities::generatePassword(),
|
||||
'source-password' => Utilities\Strings::generatePassword(),
|
||||
'relay-password' => Utilities\Strings::generatePassword(),
|
||||
'admin-user' => 'admin',
|
||||
'admin-password' => Utilities::generatePassword(),
|
||||
'admin-password' => Utilities\Strings::generatePassword(),
|
||||
],
|
||||
|
||||
'listen-socket' => [
|
||||
|
|
|
@ -212,8 +212,8 @@ class SHOUTcast extends AbstractFrontend
|
|||
$config_path = $station->getRadioConfigDir();
|
||||
|
||||
return [
|
||||
'password' => Utilities::generatePassword(),
|
||||
'adminpassword' => Utilities::generatePassword(),
|
||||
'password' => Utilities\Strings::generatePassword(),
|
||||
'adminpassword' => Utilities\Strings::generatePassword(),
|
||||
'logfile' => $config_path . '/sc_serv.log',
|
||||
'w3clog' => $config_path . '/sc_w3c.log',
|
||||
'banfile' => $this->writeIpBansFile($station),
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
namespace App\Service;
|
||||
|
||||
use App\Exception;
|
||||
use App\File;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Utilities\File;
|
||||
use Normalizer;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
@ -104,11 +104,13 @@ class Flow
|
|||
}
|
||||
|
||||
if ($file->getSize() !== $currentChunkSize) {
|
||||
throw new Exception(sprintf(
|
||||
'File size of %s does not match expected size of %s',
|
||||
$file->getSize(),
|
||||
$currentChunkSize
|
||||
));
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'File size of %s does not match expected size of %s',
|
||||
$file->getSize(),
|
||||
$currentChunkSize
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$file->moveTo($chunkPath);
|
||||
|
|
|
@ -1,259 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Miscellaneous Utilities Class
|
||||
**/
|
||||
|
||||
namespace App;
|
||||
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use SplFileInfo;
|
||||
|
||||
use function is_array;
|
||||
|
||||
class Utilities
|
||||
{
|
||||
/**
|
||||
* Generate a randomized password of specified length.
|
||||
*
|
||||
* @param int $char_length
|
||||
*/
|
||||
public static function generatePassword($char_length = 8): string
|
||||
{
|
||||
// String of all possible characters. Avoids using certain letters and numbers that closely resemble others.
|
||||
$numeric_chars = str_split('234679');
|
||||
$uppercase_chars = str_split('ACDEFGHJKLMNPQRTWXYZ');
|
||||
$lowercase_chars = str_split('acdefghjkmnpqrtwxyz');
|
||||
|
||||
$chars = [$numeric_chars, $uppercase_chars, $lowercase_chars];
|
||||
|
||||
$password = '';
|
||||
for ($i = 1; $i <= $char_length; $i++) {
|
||||
$char_array = $chars[$i % 3];
|
||||
$password .= $char_array[random_int(0, count($char_array) - 1)];
|
||||
}
|
||||
|
||||
return str_shuffle($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate URL in text-presentable format (i.e. "http://www.example.com" becomes "example.com")
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $length
|
||||
*/
|
||||
public static function truncateUrl($url, $length = 40): string
|
||||
{
|
||||
$url = str_replace(['http://', 'https://', 'www.'], '', $url);
|
||||
|
||||
return self::truncateText(rtrim($url, '/'), $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate text (adding "..." if needed)
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $limit
|
||||
* @param string $pad
|
||||
*/
|
||||
public static function truncateText($text, $limit = 80, $pad = '...'): string
|
||||
{
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
if (mb_strlen($text) <= $limit) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$wrapped_text = self::mbWordwrap($text, $limit, '{N}', true);
|
||||
$shortened_text = mb_substr($wrapped_text, 0, strpos($wrapped_text, '{N}'));
|
||||
|
||||
// Prevent the padding string from bumping up against punctuation.
|
||||
$punctuation = ['.', ',', ';', '?', '!'];
|
||||
if (in_array(mb_substr($shortened_text, -1), $punctuation, true)) {
|
||||
$shortened_text = mb_substr($shortened_text, 0, -1);
|
||||
}
|
||||
|
||||
return $shortened_text . $pad;
|
||||
}
|
||||
|
||||
/**
|
||||
* UTF-8 capable replacement for wordwrap function.
|
||||
*
|
||||
* @param string $str
|
||||
* @param int $width
|
||||
* @param string $break
|
||||
* @param bool $cut
|
||||
*/
|
||||
public static function mbWordwrap($str, $width = 75, $break = "\n", $cut = false): string
|
||||
{
|
||||
$lines = explode($break, $str);
|
||||
foreach ($lines as &$line) {
|
||||
$line = rtrim($line);
|
||||
if (mb_strlen($line) <= $width) {
|
||||
continue;
|
||||
}
|
||||
$words = explode(' ', $line);
|
||||
$line = '';
|
||||
$actual = '';
|
||||
foreach ($words as $word) {
|
||||
if (mb_strlen($actual . $word) <= $width) {
|
||||
$actual .= $word . ' ';
|
||||
} else {
|
||||
if ($actual != '') {
|
||||
$line .= rtrim($actual) . $break;
|
||||
}
|
||||
$actual = $word;
|
||||
if ($cut) {
|
||||
while (mb_strlen($actual) > $width) {
|
||||
$line .= mb_substr($actual, 0, $width) . $break;
|
||||
$actual = mb_substr($actual, $width);
|
||||
}
|
||||
}
|
||||
$actual .= ' ';
|
||||
}
|
||||
}
|
||||
$line .= trim($actual);
|
||||
}
|
||||
|
||||
return implode($break, $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort a supplied array (the first argument) by one or more indices, specified in this format:
|
||||
* arrayOrderBy($data, [ 'index_name', SORT_ASC, 'index2_name', SORT_DESC ])
|
||||
*
|
||||
* Internally uses array_multisort().
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $args
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function arrayOrderBy($data, array $args = [])
|
||||
{
|
||||
if (empty($args)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
foreach ($args as $n => $field) {
|
||||
if (is_string($field)) {
|
||||
$tmp = [];
|
||||
foreach ($data as $key => $row) {
|
||||
$tmp[$key] = $row[$field];
|
||||
}
|
||||
$args[$n] = $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
$args[] = &$data;
|
||||
array_multisort(...$args);
|
||||
|
||||
return array_pop($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if the User-Agent matches common crawler UAs.
|
||||
* Not expected to be 100% accurate or trustworthy, just used to prevent
|
||||
* common crawlers from accessing features like API endpoints.
|
||||
*/
|
||||
public static function isCrawler(): bool
|
||||
{
|
||||
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||
|
||||
// phpcs:disable Generic.Files.LineLength
|
||||
$crawlers_agents = strtolower('Bloglines subscriber|Dumbot|Sosoimagespider|QihooBot|FAST-WebCrawler|Superdownloads Spiderman|LinkWalker|msnbot|ASPSeek|WebAlta Crawler|Lycos|FeedFetcher-Google|Yahoo|YoudaoBot|AdsBot-Google|Googlebot|Scooter|Gigabot|Charlotte|eStyle|AcioRobot|GeonaBot|msnbot-media|Baidu|CocoCrawler|Google|Charlotte t|Yahoo! Slurp China|Sogou web spider|YodaoBot|MSRBOT|AbachoBOT|Sogou head spider|AltaVista|IDBot|Sosospider|Yahoo! Slurp|Java VM|DotBot|LiteFinder|Yeti|Rambler|Scrubby|Baiduspider|accoona');
|
||||
// phpcs:enable
|
||||
$crawlers = explode('|', $crawlers_agents);
|
||||
|
||||
foreach ($crawlers as $crawler) {
|
||||
if (strpos($ua, trim($crawler)) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively remove a directory and its contents.
|
||||
*
|
||||
* @param string $source
|
||||
*/
|
||||
public static function rmdirRecursive(string $source): bool
|
||||
{
|
||||
if (empty($source) || !file_exists($source)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_file($source) || is_link($source)) {
|
||||
return @unlink($source);
|
||||
}
|
||||
|
||||
$files = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($files as $fileinfo) {
|
||||
/** @var SplFileInfo $fileinfo */
|
||||
if ('link' !== $fileinfo->getType() && $fileinfo->isDir()) {
|
||||
if (!rmdir($fileinfo->getRealPath())) {
|
||||
return false;
|
||||
}
|
||||
} elseif (!unlink($fileinfo->getRealPath())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return rmdir($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an array from format:
|
||||
* [
|
||||
* 'user' => [
|
||||
* 'id' => 1,
|
||||
* 'name' => 'test',
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* to format:
|
||||
* [
|
||||
* 'user.id' => 1,
|
||||
* 'user.name' => 'test',
|
||||
* ]
|
||||
*
|
||||
* This function is used to create replacements for variables in strings.
|
||||
*
|
||||
* @param array|object $array
|
||||
* @param string $separator
|
||||
* @param null $prefix
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public static function flattenArray($array, $separator = '.', $prefix = null): array
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
if (is_object($array)) {
|
||||
// Quick and dirty conversion from object to array.
|
||||
$array = json_decode(json_encode($array, JSON_THROW_ON_ERROR), true, 512, JSON_THROW_ON_ERROR);
|
||||
} else {
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
$return = [];
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
$return_key = $prefix ? $prefix . $separator . $key : $key;
|
||||
if (is_array($value)) {
|
||||
$return = array_merge($return, self::flattenArray($value, $separator, $return_key));
|
||||
} else {
|
||||
$return[$return_key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace App\Utilities;
|
||||
|
||||
class Arrays
|
||||
{
|
||||
/**
|
||||
* Sort a supplied array (the first argument) by one or more indices, specified in this format:
|
||||
* arrayOrderBy($data, [ 'index_name', SORT_ASC, 'index2_name', SORT_DESC ])
|
||||
*
|
||||
* Internally uses array_multisort().
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $args
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function arrayOrderBy($data, array $args = [])
|
||||
{
|
||||
if (empty($args)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
foreach ($args as $n => $field) {
|
||||
if (is_string($field)) {
|
||||
$tmp = [];
|
||||
foreach ($data as $key => $row) {
|
||||
$tmp[$key] = $row[$field];
|
||||
}
|
||||
$args[$n] = $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
$args[] = &$data;
|
||||
array_multisort(...$args);
|
||||
|
||||
return array_pop($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an array from format:
|
||||
* [
|
||||
* 'user' => [
|
||||
* 'id' => 1,
|
||||
* 'name' => 'test',
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* to format:
|
||||
* [
|
||||
* 'user.id' => 1,
|
||||
* 'user.name' => 'test',
|
||||
* ]
|
||||
*
|
||||
* This function is used to create replacements for variables in strings.
|
||||
*
|
||||
* @param array|object $array
|
||||
* @param string $separator
|
||||
* @param null $prefix
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public static function flattenArray($array, $separator = '.', $prefix = null): array
|
||||
{
|
||||
if (!is_array($array)) {
|
||||
if (is_object($array)) {
|
||||
// Quick and dirty conversion from object to array.
|
||||
$array = json_decode(json_encode($array, JSON_THROW_ON_ERROR), true, 512, JSON_THROW_ON_ERROR);
|
||||
} else {
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
$return = [];
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
$return_key = $prefix ? $prefix . $separator . $key : $key;
|
||||
if (is_array($value)) {
|
||||
$return = array_merge($return, self::flattenArray($value, $separator, $return_key));
|
||||
} else {
|
||||
$return[$return_key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
namespace App\Utilities;
|
||||
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use SplFileInfo;
|
||||
|
||||
/**
|
||||
* Static class that facilitates the uploading, reading and deletion of files in a controlled directory.
|
||||
|
@ -72,4 +76,38 @@ class File
|
|||
|
||||
return $fullPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively remove a directory and its contents.
|
||||
*
|
||||
* @param string $source
|
||||
*/
|
||||
public static function rmdirRecursive(string $source): bool
|
||||
{
|
||||
if (empty($source) || !file_exists($source)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_file($source) || is_link($source)) {
|
||||
return @unlink($source);
|
||||
}
|
||||
|
||||
$files = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($files as $fileinfo) {
|
||||
/** @var SplFileInfo $fileinfo */
|
||||
if ('link' !== $fileinfo->getType() && $fileinfo->isDir()) {
|
||||
if (!rmdir($fileinfo->getRealPath())) {
|
||||
return false;
|
||||
}
|
||||
} elseif (!unlink($fileinfo->getRealPath())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return rmdir($source);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace App\Utilities;
|
||||
|
||||
class Strings
|
||||
{
|
||||
/**
|
||||
* Truncate text (adding "..." if needed)
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $limit
|
||||
* @param string $pad
|
||||
*/
|
||||
public static function truncateText($text, $limit = 80, $pad = '...'): string
|
||||
{
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
if (mb_strlen($text) <= $limit) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$wrapped_text = self::mbWordwrap($text, $limit, '{N}', true);
|
||||
$shortened_text = mb_substr($wrapped_text, 0, strpos($wrapped_text, '{N}'));
|
||||
|
||||
// Prevent the padding string from bumping up against punctuation.
|
||||
$punctuation = ['.', ',', ';', '?', '!'];
|
||||
if (in_array(mb_substr($shortened_text, -1), $punctuation, true)) {
|
||||
$shortened_text = mb_substr($shortened_text, 0, -1);
|
||||
}
|
||||
|
||||
return $shortened_text . $pad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a randomized password of specified length.
|
||||
*
|
||||
* @param int $char_length
|
||||
*/
|
||||
public static function generatePassword($char_length = 8): string
|
||||
{
|
||||
// String of all possible characters. Avoids using certain letters and numbers that closely resemble others.
|
||||
$numeric_chars = str_split('234679');
|
||||
$uppercase_chars = str_split('ACDEFGHJKLMNPQRTWXYZ');
|
||||
$lowercase_chars = str_split('acdefghjkmnpqrtwxyz');
|
||||
|
||||
$chars = [$numeric_chars, $uppercase_chars, $lowercase_chars];
|
||||
|
||||
$password = '';
|
||||
for ($i = 1; $i <= $char_length; $i++) {
|
||||
$char_array = $chars[$i % 3];
|
||||
$password .= $char_array[random_int(0, count($char_array) - 1)];
|
||||
}
|
||||
|
||||
return str_shuffle($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* UTF-8 capable replacement for wordwrap function.
|
||||
*
|
||||
* @param string $str
|
||||
* @param int $width
|
||||
* @param string $break
|
||||
* @param bool $cut
|
||||
*/
|
||||
public static function mbWordwrap($str, $width = 75, $break = "\n", $cut = false): string
|
||||
{
|
||||
$lines = explode($break, $str);
|
||||
foreach ($lines as &$line) {
|
||||
$line = rtrim($line);
|
||||
if (mb_strlen($line) <= $width) {
|
||||
continue;
|
||||
}
|
||||
$words = explode(' ', $line);
|
||||
$line = '';
|
||||
$actual = '';
|
||||
foreach ($words as $word) {
|
||||
if (mb_strlen($actual . $word) <= $width) {
|
||||
$actual .= $word . ' ';
|
||||
} else {
|
||||
if ($actual != '') {
|
||||
$line .= rtrim($actual) . $break;
|
||||
}
|
||||
$actual = $word;
|
||||
if ($cut) {
|
||||
while (mb_strlen($actual) > $width) {
|
||||
$line .= mb_substr($actual, 0, $width) . $break;
|
||||
$actual = mb_substr($actual, $width);
|
||||
}
|
||||
}
|
||||
$actual .= ' ';
|
||||
}
|
||||
}
|
||||
$line .= trim($actual);
|
||||
}
|
||||
|
||||
return implode($break, $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate URL in text-presentable format (i.e. "http://www.example.com" becomes "example.com")
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $length
|
||||
*/
|
||||
public static function truncateUrl($url, $length = 40): string
|
||||
{
|
||||
$url = str_replace(['http://', 'https://', 'www.'], '', $url);
|
||||
|
||||
return self::truncateText(rtrim($url, '/'), $length);
|
||||
}
|
||||
}
|
|
@ -100,14 +100,14 @@ class View extends Engine
|
|||
$this->registerFunction(
|
||||
'truncate',
|
||||
function ($text, $length = 80) {
|
||||
return Utilities::truncateText($text, $length);
|
||||
return Utilities\Strings::truncateText($text, $length);
|
||||
}
|
||||
);
|
||||
|
||||
$this->registerFunction(
|
||||
'truncateUrl',
|
||||
function ($url) {
|
||||
return Utilities::truncateUrl($url);
|
||||
return Utilities\Strings::truncateUrl($url);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -121,7 +121,7 @@ class View extends Engine
|
|||
$a[] = 'target="_blank"';
|
||||
}
|
||||
|
||||
$a_body = ($truncate) ? Utilities::truncateUrl($url) : $url;
|
||||
$a_body = ($truncate) ? Utilities\Strings::truncateUrl($url) : $url;
|
||||
return '<a ' . implode(' ', $a) . '>' . $a_body . '</a>';
|
||||
}
|
||||
);
|
||||
|
|
|
@ -49,7 +49,7 @@ abstract class AbstractConnector implements ConnectorInterface
|
|||
*/
|
||||
public function replaceVariables(array $raw_vars, Entity\Api\NowPlaying $np): array
|
||||
{
|
||||
$values = Utilities::flattenArray($np, '.');
|
||||
$values = Utilities\Arrays::flattenArray($np, '.');
|
||||
$vars = [];
|
||||
|
||||
foreach ($raw_vars as $var_key => $var_value) {
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Utilities\Strings;
|
||||
|
||||
class UtilitiesTest extends \Codeception\Test\Unit
|
||||
{
|
||||
/**
|
||||
|
@ -8,16 +11,16 @@ class UtilitiesTest extends \Codeception\Test\Unit
|
|||
|
||||
public function testUtilities()
|
||||
{
|
||||
$test_result = \App\Utilities::generatePassword(10);
|
||||
$test_result = Strings::generatePassword(10);
|
||||
$this->assertTrue(strlen($test_result) == 10);
|
||||
|
||||
$test_string = 'Lorem ipsum dolor sit amet lorem ipsum dolor sit amet lorem ipsum dolor sit amet';
|
||||
$test_result = \App\Utilities::truncateText($test_string, 15);
|
||||
$test_result = Strings::truncateText($test_string, 15);
|
||||
$expected_result = 'Lorem ipsum...';
|
||||
$this->assertEquals($test_result, $expected_result);
|
||||
|
||||
$test_url = 'https://www.twitter.com/';
|
||||
$test_result = \App\Utilities::truncateUrl($test_url);
|
||||
$test_result = Strings::truncateUrl($test_url);
|
||||
$expected_result = 'twitter.com';
|
||||
$this->assertEquals($test_result, $expected_result);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue