Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions App/Manager/Download/DownloadManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class DownloadManager
* @desc Download and install package with api return link, ex: "/Public/market/Resources/forum.zip"
* @throws DownloadException
*/
public static function installPackageWithLink(string $url, #[ExpectedValues(['package', 'Theme'])] string $type, string $name): void
public static function installPackageWithLink(string $url, #[ExpectedValues(['package', 'Theme'])] string $type, string $name, bool $runInit = true): void
{
if (!in_array($type, ['package', 'Theme'], true)) {
throw new DownloadException('Type invalide');
Expand Down Expand Up @@ -56,7 +56,7 @@ public static function installPackageWithLink(string $url, #[ExpectedValues(['pa
$archiveUpdate->close();
@unlink($zipPath);

if ($type === 'package') {
if ($type === 'package' && $runInit) {
self::initPackages($name);
}
}
Expand Down
25 changes: 6 additions & 19 deletions App/Manager/Env/EnvManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,27 +209,14 @@ public function addValue(string $key, ?string $value): void
$key = mb_strtoupper(trim($key));

if (!$this->valueExistInFile($key)) {
$path = $this->envPath . $this->envFileName;
$file = fopen($this->envPath . $this->envFileName, 'ab');
$textToSet = static function (string $key, ?string $value) {
return $key . '=' . trim($value ?? 'UNDEFINED') . PHP_EOL;
};

$file = fopen($path, 'cb+');
if ($file === false) {
ErrorManager::showCustomErrorPage('IO error', 'Unable to open .env');
}
$needsNewline = false;
$size = filesize($path);
if ($size > 0) {
fseek($file, -1, SEEK_END);
$lastChar = fgetc($file);
$needsNewline = ($lastChar !== "\n");
fseek($file, 0, SEEK_END);
}

if ($needsNewline) {
fwrite($file, PHP_EOL);
}
$res = $textToSet($key, $value);
fwrite($file, $res);

$line = $key . '=' . trim($value ?? '') . PHP_EOL;
fwrite($file, $line);
fclose($file);

$this->load();
Expand Down
2 changes: 1 addition & 1 deletion App/Manager/Loader/Loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public static function loadImplementations(string $interface): array
$packages = PackageController::getAllPackages();

foreach ($packages as $package) {
$implementationsFolder = EnvManager::getInstance()->getValue('dir') . "App/Package/{$package->name()}/Implementations";
$implementationsFolder = EnvManager::getInstance()->getValue('DIR') . "App/Package/{$package->name()}/Implementations";

if (!is_dir($implementationsFolder)) {
continue;
Expand Down
5 changes: 4 additions & 1 deletion App/Package/Core/Controllers/CoreController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use CMW\Manager\Uploads\ImagesManager;
use CMW\Manager\Views\View;
use CMW\Model\Core\CoreModel;
use CMW\Model\Core\UpdateCheckerModel;
use CMW\Utils\Redirect;
use JetBrains\PhpStorm\NoReturn;
use function date;
Expand Down Expand Up @@ -61,8 +62,10 @@ private function adminDashboard(): void
Redirect::redirect(EnvManager::getInstance()->getValue('PATH_SUBFOLDER') . 'cmw-admin/dashboard');
}

$outdatedResources = UpdateCheckerModel::getInstance()->getOutdatedResources();

View::createAdminView('Core', 'Dashboard/dashboard')
->addVariableList([])
->addVariableList(['outdatedResources' => $outdatedResources])
->addScriptBefore('Admin/Resources/Vendors/Apexcharts/Js/apexcharts.js')
->view();
}
Expand Down
40 changes: 39 additions & 1 deletion App/Package/Core/Controllers/PackageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ private function adminPackageUpdate(): void

if ($i === $lastUpdateIndex) {
try {
DownloadManager::installPackageWithLink($update['file'], 'package', $packageName);
DownloadManager::installPackageWithLink($update['file'], 'package', $packageName, false);
} catch (DownloadException $e) {
Flash::send(
Alert::ERROR,
Expand Down Expand Up @@ -573,4 +573,42 @@ private function uninstallPackage(string $packageName): bool
// Uninstall package:
return Directory::delete(EnvManager::getInstance()->getValue('DIR') . "App/Package/$packageName");
}

// HELPER
public function formatDownloads(int $value): string
{
if ($value >= 1_000_000_000) {
return floor($value / 1_000_000_000) . 'B+';
}

if ($value >= 1_000_000) {
return floor($value / 1_000_000) . 'M+';
}

if ($value >= 1000) {
return floor($value / 1000) . 'k+';
}

return (string) $value;
}

public function renderStars(?string $rate): string
{
$value = (float) ($rate ?? 0);
$html = '';

for ($i = 1; $i <= 5; $i++) {
if ($value >= 1) {
$html .= '<i class="fa-solid fa-star" style="color:#FFD43B;"></i>';
$value -= 1;
} elseif ($value === 0.5) {
$html .= '<i class="fa-solid fa-star-half-stroke" style="color:#FFD43B;"></i>';
$value = 0;
} else {
$html .= '<i class="fa-regular fa-star"></i>';
}
}

return $html;
}
}
80 changes: 80 additions & 0 deletions App/Package/Core/Entities/UpdateCheckerEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace CMW\Entity\Core;

use CMW\Manager\Package\AbstractEntity;
use CMW\Utils\Date;

/**
* Class: @UpdateCheckerEntity
* @package Core
* @link https://craftmywebsite.fr/docs/fr/technical/creer-un-package/entities
*/
class UpdateCheckerEntity extends AbstractEntity
{
private string $name;
private ?string $marketName;
private string $type; // 'theme' | 'package'
private string $localVersion;
private string $remoteVersion;
private ?string $dateRelease;
private ?int $versionId;

public function __construct(
string $name,
?string $marketName,
string $type,
string $localVersion,
string $remoteVersion,
?string $dateRelease = null,
?int $versionId = null
) {
$this->name = $name;
$this->marketName = $marketName;
$this->type = $type;
$this->localVersion = $localVersion;
$this->remoteVersion = $remoteVersion;
$this->dateRelease = $dateRelease;
$this->versionId = $versionId;
}

public function name(): string
{
return $this->name;
}

public function marketName(): ?string
{
return $this->marketName;
}

public function type(): string
{
return $this->type;
}

public function localVersion(): string
{
return $this->localVersion;
}

public function remoteVersion(): string
{
return $this->remoteVersion;
}

public function dateRelease(): ?string
{
return Date::formatDate($this->dateRelease);
}

public function versionId(): ?int
{
return $this->versionId;
}

public function isOutdated(): bool
{
return $this->localVersion !== $this->remoteVersion;
}
}
14 changes: 11 additions & 3 deletions App/Package/Core/Lang/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,15 @@
'weeks' => 'Weeks',
'months' => 'Months',
'alpha' => 'Please note that CraftMyWebsite2 is currently in BETA phase and is not yet complete. <br>Its use in a production environment is strongly discouraged. Key features may be missing or may not work as expected. <br><b>During this phase, complete system reinstalls may be required.</b> <br>We appreciate your understanding and patience while we work on CraftMyWebsite.',
'updateWarning' => '<strong>Attention :</strong>The current version of your CMS is not the latest available. It is strongly recommended to <a class="link" href="updates/cms">update your CMS</a> to benefit from the latest security fixes as well as new features added.',
'updateWarningTitle' => 'Your CMS is not up to date!',
'updateWarning' => 'Warning: The currently installed version of your CMS is not up to date.<br>
Continuing to use an outdated version may expose your website to security vulnerabilities, compatibility issues, or unexpected malfunctions with certain modules and themes.<br>
We strongly recommend performing the <a class="link" href="updates/cms">CMS update</a> to benefit from the latest security patches, performance improvements, enhanced stability, and newly added features.<br>
Keeping your CMS up to date ensures a reliable, secure, and future-proof environment.',
'updateResTitle' => 'Requires your attention',
'updateResWaiting' => ' has a pending update!',
'updateResFrom' => 'Since ',
'updateResBtn' => 'Update',
],
'menus' => [
'title' => 'Menus',
Expand Down Expand Up @@ -180,8 +188,8 @@
],
'db' => [
'config' => [
'success' => 'Good configuration',
'error' => 'Configuration error',
'success' => 'Connection to the database is working!',
'error' => 'Unable to connect to the database!',
'alreadyInstalled' => 'Data base already installed !',
],
'missing_inputs' => 'Please fill all inputs !',
Expand Down
14 changes: 11 additions & 3 deletions App/Package/Core/Lang/fr.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,15 @@
'weeks' => 'Semaines',
'months' => 'Mois',
'alpha' => 'Veuillez noter que CraftMyWebsite2 est actuellement en phase BETA et n\'est pas encore achevé. <br>Son utilisation en environnement de production est fortement déconseillée. Des fonctionnalités clés peuvent manquer ou ne pas fonctionner comme prévu. <br><b>Pendant cette phase, des réinstallations complètes du système pourront être nécessaires.</b> <br>Nous vous remercions de votre compréhension et de votre patience pendant que nous travaillons sur CraftMyWebsite.',
'updateWarning' => '<strong>Attention :</strong> La version actuelle de votre CMS n\'est pas la dernière disponible.Il est fortement conseillé de <a class="link" href="updates/cms">mettre à jour</a> votre CMS pour bénéficier des derniers correctifs de sécurité ainsi que des nouvelles fonctionnalités ajoutées.',
'updateWarningTitle' => 'Votre CMS n\'est pas à jour !',
'updateWarning' => 'Attention : La version actuellement installée de votre CMS n’est pas à jour.<br>
Continuer à utiliser une version obsolète peut exposer votre site à des failles de sécurité, à des problèmes de compatibilité ou à des dysfonctionnements avec certains packages et thèmes.<br>
Nous vous recommandons vivement d’effectuer la <a class="link" href="updates/cms">mise à jour du CMS</a> afin de bénéficier des derniers correctifs de sécurité, d’améliorations de performances, d’une meilleure stabilité globale et des nouvelles fonctionnalités récemment ajoutées.<br>
Mettre à jour régulièrement votre CMS permet de garantir un environnement fiable, sécurisé et conforme aux évolutions techniques.',
'updateResTitle' => 'Requiert votre attention',
'updateResWaiting' => 'à une mise à jour en attente !',
'updateResFrom' => 'Depuis le ',
'updateResBtn' => 'Mettre à jour',
],
'menus' => [
'title' => 'Menus',
Expand Down Expand Up @@ -180,8 +188,8 @@
],
'db' => [
'config' => [
'success' => 'Configuration fonctionnelle',
'error' => 'Configuration invalide',
'success' => 'Connexion avec la base de donnée fonctionnel !',
'error' => 'Impossible de se connecter à la base de données',
'alreadyInstalled' => 'Base de données déjà installée !',
],
'missing_inputs' => 'Merci de remplir tous les champs !',
Expand Down
93 changes: 93 additions & 0 deletions App/Package/Core/Models/UpdateCheckerModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace CMW\Model\Core;

use CMW\Controller\Core\PackageController;
use CMW\Entity\Core\UpdateCheckerEntity;
use CMW\Manager\Api\PublicAPI;
use CMW\Manager\Package\AbstractModel;
use CMW\Manager\Theme\Loader\ThemeLoader;

/**
* Class: @UpdateCheckerModel
* @package Core
* @link https://craftmywebsite.fr/docs/fr/technical/creer-un-package/models
*/
class UpdateCheckerModel extends AbstractModel
{
/**
* @return array
* @desc Return all the online ressources
*/
public function getMarketResourcesOnline(): array
{
return PublicAPI::getData('market/resources/latest/online');
}

/**
* @return UpdateCheckerEntity[]
* @desc Return the list of public thèmes from our market
*/
public function getOutdatedResources(): array
{
$marketResources = $this->getMarketResourcesOnline();

$marketByName = [];
foreach ($marketResources as $r) {
$name = $r['name'] ?? null;
if ($name) {
$marketByName[$name] = $r;
}
}

$outdated = [];

foreach (ThemeLoader::getInstance()->getInstalledThemes() as $theme) {
$name = $theme->name();
$localVersion = (string) $theme->version();

if (!isset($marketByName[$name])) {
continue;
}

$remoteVersion = (string) ($marketByName[$name]['version_name'] ?? '');

if ($remoteVersion !== '' && $localVersion !== $remoteVersion) {
$outdated[] = new UpdateCheckerEntity(
name: $name,
marketName: $marketByName[$name]['market_name'] ?? null,
type: 'theme',
localVersion: $localVersion,
remoteVersion: $remoteVersion,
dateRelease: $marketByName[$name]['date_release'] ?? null,
versionId: isset($marketByName[$name]['version_id']) ? (int) $marketByName[$name]['version_id'] : null
);
}
}

foreach (PackageController::getInstalledPackages() as $package) {
$name = $package->name();
$localVersion = (string) $package->version();

if (!isset($marketByName[$name])) {
continue;
}

$remoteVersion = (string) ($marketByName[$name]['version_name'] ?? '');

if ($remoteVersion !== '' && $localVersion !== $remoteVersion) {
$outdated[] = new UpdateCheckerEntity(
name: $name,
marketName: $marketByName[$name]['market_name'] ?? null,
type: 'package',
localVersion: $localVersion,
remoteVersion: $remoteVersion,
dateRelease: $marketByName[$name]['date_release'] ?? null,
versionId: isset($marketByName[$name]['version_id']) ? (int) $marketByName[$name]['version_id'] : null
);
}
}

return $outdated;
}
}
Loading