Skip to content

Commit aeb5958

Browse files
authored
Merge pull request #263 from WebFiori/dev
Dev
2 parents f2c8df2 + 5ed85f3 commit aeb5958

7 files changed

Lines changed: 181 additions & 29 deletions

File tree

tests/webfiori/framework/test/PageTest.php

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,100 @@ public function testBeforeRender00() {
154154
$c->assertTrue($p->getDocument()->hasChild('super-el'));
155155
},0, [$this]);
156156
$this->assertNotNull($c);
157-
$this->assertEquals(2, $c->getID());
158157
$this->assertEquals(0, $c->getPriority());
159158

160159
$c2 = $page->addBeforeRender(function(WebPage $p, TestCase $c)
161160
{
162161
$ch = $p->insert('div');
163162
$ch->setID('super-el');
164163
}, 3, [$this]);
165-
$this->assertEquals(3, $c2->getID());
166164
$this->assertEquals(3, $c2->getPriority());
167165
}
166+
/**
167+
* @test
168+
*/
169+
public function testBeforeRender01() {
170+
$page = new WebPage();
171+
$c = $page->addBeforeRender(function (WebPage $p, TestCase $c)
172+
{
173+
$c->assertTrue($p->getDocument()->getChildByID('super-el') !== null);
174+
},0, [$this]);
175+
176+
$c2 = $page->addBeforeRender(function(WebPage $p, TestCase $c)
177+
{
178+
$ch = $p->insert('div');
179+
$ch->setID('super-el');
180+
}, 3, [$this]);
181+
$this->assertNull($page->getDocument()->getChildByID('super-el'));
182+
$page->beforeRender();
183+
$this->assertNotNull($page->getDocument()->getChildByID('super-el'));
184+
}
185+
/**
186+
* @test
187+
*/
188+
public function testBeforeRender02() {
189+
$page = new WebPage();
190+
$c = $page->addBeforeRender(function (WebPage $p, TestCase $c)
191+
{
192+
$c->assertTrue($p->getDocument()->getChildByID('super-el') === null);
193+
},0, [$this]);
194+
195+
$c2 = $page->addBeforeRender(function(WebPage $p, TestCase $c)
196+
{
197+
$ch = $p->insert('div');
198+
$ch->setID('super-el');
199+
}, 3, [$this]);
200+
$page->removeBeforeRender($c2->getID());
201+
$page->beforeRender();
202+
$this->assertNull($page->getDocument()->getChildByID('super-el'));
203+
}
204+
/**
205+
* @test
206+
*/
207+
public function testBeforeRender03() {
208+
$page = new WebPage();
209+
$c = $page->addBeforeRender(function (WebPage $p, TestCase $c)
210+
{
211+
212+
$p->addBeforeRender(function (WebPage $p, TestCase $c) {
213+
$c->assertTrue($p->getDocument()->getChildByID('super-el') === null);
214+
}, 4, [$this]);
215+
$p->addBeforeRender(function(WebPage $p, TestCase $c)
216+
{
217+
$ch = $p->insert('div');
218+
$ch->setID('super-el');
219+
}, 3, [$this]);
220+
$p->addBeforeRender(function (WebPage $p, TestCase $c) {
221+
$c->assertTrue($p->getDocument()->getChildByID('super-el') !== null);
222+
}, 2, [$this]);
223+
224+
},0, [$this]);
225+
226+
$page->beforeRender();
227+
$this->assertNotNull($page->getDocument()->getChildByID('super-el'));
228+
}
229+
/**
230+
* @test
231+
*/
232+
public function testBeforeRender04() {
233+
$page = new WebPage();
234+
235+
$c2 = $page->addBeforeRender(function(WebPage $p, TestCase $c)
236+
{
237+
$ch = $p->insert('div');
238+
$ch->setID('super-el');
239+
}, 3, [$this]);
240+
241+
$c2->setCallback(function(WebPage $p, TestCase $c)
242+
{
243+
$ch = $p->insert('div');
244+
$ch->setID('super-cool');
245+
}, [$this]);
246+
247+
$page->beforeRender();
248+
$this->assertNull($page->getDocument()->getChildByID('super-el'));
249+
$this->assertNotNull($page->getDocument()->getChildByID('super-cool'));
250+
}
168251
/**
169252
* @test
170253
*/

tests/webfiori/framework/test/cli/AddCommandTest.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
namespace webfiori\framework\test\cli;
33

4-
use PHPUnit\Framework\TestCase;
4+
use webfiori\cli\CommandTestCase;
55
use webfiori\cli\Runner;
66
use webfiori\file\File;
77
use webfiori\framework\App;
@@ -13,30 +13,32 @@
1313
*
1414
* @author Ibrahim
1515
*/
16-
class AddCommandTest extends TestCase {
16+
class AddCommandTest extends CommandTestCase {
1717
/**
1818
* @test
1919
*/
2020
public function test00() {
21+
$output = $this->executeSingleCommand(new AddCommand(), [], [
22+
'3'
23+
]);
2124
$runner = new Runner();
2225
$runner->setInputs([
2326
'3'
2427
]);
25-
$this->assertEquals(0, $runner->runCommand(new AddCommand()));
2628
$this->assertEquals([
2729
"What would you like to add?\n",
2830
"0: New database connection.\n",
2931
"1: New SMTP connection.\n",
3032
"2: New website language.\n",
3133
"3: Quit. <--\n"
32-
], $runner->getOutput());
34+
], $output);
35+
$this->assertEquals(0, $this->getExitCode());
3336
}
3437
/**
3538
* @test
3639
*/
3740
public function testAddDBConnection00() {
38-
$runner = App::getRunner();
39-
$runner->setInputs([
41+
$output = $this->executeSingleCommand(new AddCommand(), [], [
4042
'0',
4143
'0',
4244
'127.0.0.1',
@@ -46,11 +48,8 @@ public function testAddDBConnection00() {
4648
'testing_db',
4749
''
4850
]);
49-
$runner->setArgsVector([
50-
'webfiori',
51-
'add'
52-
]);
53-
$this->assertEquals(0, $runner->start());
51+
52+
5453
$connName = 'db-connection-'.(count(App::getConfig()->getDBConnections()) - 1);
5554
$this->assertEquals([
5655
"What would you like to add?\n",
@@ -70,7 +69,8 @@ public function testAddDBConnection00() {
7069
"Trying to connect to the database...\n",
7170
"Success: Connected. Adding the connection...\n",
7271
"Success: Connection information was stored in application configuration.\n"
73-
], $runner->getOutput());
72+
], $output);
73+
$this->assertEquals(0, $this->getExitCode());
7474
}
7575
/**
7676
* @test
@@ -111,8 +111,9 @@ public function testAddDBConnection01() {
111111
"Database name:\n",
112112
"Give your connection a friendly name: Enter = '$connName'\n",
113113
"Trying to connect to the database...\n",
114+
"Trying with 'localhost'...\n",
114115
"Error: Unable to connect to the database.\n",
115-
"Error: Unable to connect to database: 2002 - No such file or directory\n",
116+
"Error: Unable to connect to database: 1045 - Access denied for user 'root'@'localhost' (using password: YES)\n",
116117
"Would you like to store connection information anyway?(y/N)\n",
117118
"Success: Connection information was stored in application configuration.\n"
118119
], $runner->getOutput());
@@ -155,8 +156,9 @@ public function testAddDBConnection02() {
155156
"Database name:\n",
156157
"Give your connection a friendly name: Enter = '$connName'\n",
157158
"Trying to connect to the database...\n",
159+
"Trying with 'localhost'...\n",
158160
"Error: Unable to connect to the database.\n",
159-
"Error: Unable to connect to database: 2002 - No such file or directory\n",
161+
"Error: Unable to connect to database: 1045 - Access denied for user 'root'@'localhost' (using password: YES)\n",
160162
"Would you like to store connection information anyway?(y/N)\n",
161163
], $runner->getOutput());
162164
}

webfiori/framework/App.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ public static function initFrameworkVersionInfo() {
637637
*
638638
* @since 2.1
639639
*/
640-
define('WF_VERSION', '3.0.0-Beta.26');
640+
define('WF_VERSION', '3.0.0-Beta.27');
641641
/**
642642
* A constant that tells the type of framework version.
643643
*
@@ -653,7 +653,7 @@ public static function initFrameworkVersionInfo() {
653653
*
654654
* @since 2.1
655655
*/
656-
define('WF_RELEASE_DATE', '2025-04-07');
656+
define('WF_RELEASE_DATE', '2025-05-26');
657657
}
658658

659659
/**

webfiori/framework/cli/commands/AddCommand.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,16 @@ private function addDbConnection(): int {
7575
$this->println('Trying to connect to the database...');
7676

7777
$addConnection = $this->tryConnect($connInfoObj);
78-
78+
$orgHost = $connInfoObj->getHost();
79+
$orgErr = $addConnection !== true ? $addConnection->getMessage() : '';
80+
7981
if ($addConnection !== true) {
8082
if ($connInfoObj->getHost() == '127.0.0.1') {
83+
$this->println("Trying with 'localhost'...");
8184
$connInfoObj->setHost('localhost');
8285
$addConnection = $this->tryConnect($connInfoObj);
8386
} else if ($connInfoObj->getHost() == 'localhost') {
87+
$this->println("Trying with '127.0.0.1'...");
8488
$connInfoObj->setHost('127.0.0.1');
8589
$addConnection = $this->tryConnect($connInfoObj);
8690
}
@@ -92,8 +96,9 @@ private function addDbConnection(): int {
9296
App::getConfig()->addOrUpdateDBConnection($connInfoObj);
9397
$this->success('Connection information was stored in application configuration.');
9498
} else {
99+
$connInfoObj->setHost($orgHost);
95100
$this->error('Unable to connect to the database.');
96-
$this->error($addConnection->getMessage());
101+
$this->error($orgErr);
97102
$this->confirmAdd($connInfoObj);
98103
}
99104

webfiori/framework/cli/commands/RunMigrationsCommand.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,19 @@ private function getDBConnection(?MigrationsRunner $runner = null) {
232232
return CLIUtils::getConnectionName($this);
233233
}
234234
}
235+
public function getNext(MigrationsRunner $runner) : ?AbstractMigration {
236+
foreach ($runner->getMigrations() as $m) {
237+
if ($runner->isApplied($m->getName())) {
238+
continue;
239+
} else {
240+
return $m;
241+
}
242+
}
243+
return null;
244+
}
235245
private function applyNext(MigrationsRunner $runner, &$listOfApplied) : bool {
246+
$toBeApplied = $this->getNext($runner);
247+
236248
try {
237249
//$this->println("Executing migration...");
238250
$applied = $runner->applyOne();
@@ -248,6 +260,15 @@ private function applyNext(MigrationsRunner $runner, &$listOfApplied) : bool {
248260
$this->error('Failed to execute migration due to following:');
249261
$this->println($ex->getMessage().' (Line '.$ex->getLine().')');
250262
$this->warning('Execution stopped.');
263+
$this->warning('Rolling back changes...');
264+
265+
try {
266+
$toBeApplied->down($runner);
267+
} catch (Throwable $exc) {
268+
$this->error('Failed to rollback due to following:');
269+
$this->println($ex->getMessage().' (Line '.$ex->getLine().')');
270+
}
271+
251272
return false;
252273
}
253274
}

webfiori/framework/ui/BeforeRenderCallback.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,22 @@ class BeforeRenderCallback implements Comparable {
4242
*
4343
*/
4444
public function __construct(callable $func, int $priority = 0, array $params = []) {
45+
$this->setCallback($func, $params);
46+
$this->setPriority($priority >= 0 ? $priority : 0);
47+
$this->isExecuted = false;
48+
$this->setID(hash('sha256', microtime().''.$priority.random_bytes(20)));
49+
}
50+
/**
51+
* Sets the callback.
52+
*
53+
* @param callable $func A function to be executed.
54+
*
55+
* @param array $params An optional array that can hold extra parameters to
56+
* pass to the callback.
57+
*/
58+
public function setCallback(callable $func, array $params = []) {
4559
$this->callback = $func;
4660
$this->params = $params;
47-
$this->priority = $priority >= 0 ? $priority : 0;
48-
$this->isExecuted = false;
4961
}
5062
/**
5163
* Execute the callback.
@@ -75,9 +87,9 @@ public function compare($other): int {
7587
/**
7688
* Returns the identifier of the callback.
7789
*
78-
* @return int The identifier of the callback.
90+
* @return string The identifier of the callback.
7991
*/
80-
public function getID() : int {
92+
public function getID() : string {
8193
return $this->id;
8294
}
8395
/**
@@ -104,9 +116,9 @@ public function isExecuted() : bool {
104116
/**
105117
* Sets a unique identifier for the callback.
106118
*
107-
* @param int $id A unique identifier for the callback.
119+
* @param string $id A unique identifier for the callback.
108120
*/
109-
public function setID(int $id) {
121+
public function setID(string $id) {
110122
$this->id = $id;
111123
}
112124
/**

webfiori/framework/ui/WebPage.php

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,8 @@ public function __construct() {
236236
*
237237
* @since 1.0
238238
*/
239-
public function addBeforeRender(callable $callable, $priority = 0, array $params = []) : BeforeRenderCallback {
239+
public function &addBeforeRender(callable $callable, $priority = 0, array $params = []) : BeforeRenderCallback {
240240
$beforeRender = new BeforeRenderCallback($callable, $priority, $params);
241-
$beforeRender->setID($this->beforeRenderCallbacks->size() + 1);
242241
$this->beforeRenderCallbacks->add($beforeRender);
243242

244243
return $beforeRender;
@@ -728,6 +727,29 @@ public function insert($node, string $parentNodeId = self::MAIN_ELEMENTS[2]) {
728727
public function isThemeLoaded() : bool {
729728
return $this->theme instanceof Theme;
730729
}
730+
/**
731+
* Removes a callback given its ID.
732+
*
733+
* @param string $id The unique identifier of the callback.
734+
*
735+
* @return BeforeRenderCallback|null If removed, an object will be returned
736+
* that holds its information. Other than that, null is returned.
737+
*/
738+
public function removeBeforeRender(string $id) : ?BeforeRenderCallback {
739+
$index = -1;
740+
$tempIndex = 0;
741+
742+
foreach ($this->beforeRenderCallbacks as $callback) {
743+
744+
if ($callback->getID() == $id) {
745+
$index = $tempIndex;
746+
break;
747+
}
748+
$tempIndex++;
749+
}
750+
751+
return $this->beforeRenderCallbacks->remove($index);
752+
}
731753
/**
732754
* Removes a child node from the document of the page.
733755
*
@@ -762,7 +784,7 @@ public function removeChild($node) {
762784
* @since 1.0
763785
*/
764786
public function render(bool $formatted = false, bool $returnResult = false) {
765-
$this->invokeBeforeRender();
787+
$this->beforeRender();
766788

767789
if (!$returnResult) {
768790
$formatted = $formatted === true || (defined('WF_VERBOSE') && WF_VERBOSE);
@@ -1227,6 +1249,10 @@ private function getHead() {
12271249

12281250
return $headNode;
12291251
}
1252+
public function beforeRender() {
1253+
$this->beforeRenderCallbacks->insertionSort(false);
1254+
$this->invokeBeforeRender();
1255+
}
12301256
private function invokeBeforeRender(int $current = 0) {
12311257
$currentCount = count($this->beforeRenderCallbacks);
12321258

@@ -1237,6 +1263,9 @@ private function invokeBeforeRender(int $current = 0) {
12371263
$newCount = count($this->beforeRenderCallbacks);
12381264

12391265
if ($newCount != $currentCount) {
1266+
//This part is used to handel callbacks
1267+
//which are added during the process of executing
1268+
//callbacks
12401269
$this->beforeRenderCallbacks->insertionSort(false);
12411270
$this->invokeBeforeRender();
12421271
} else {

0 commit comments

Comments
 (0)