The page you requested could not be found. It is possible that the address is
5 | incorrect, or that the page no longer exists. Please use a search engine to find
6 | what you are looking for.
15 |
16 | {include content}
17 |
18 |
19 |
--------------------------------------------------------------------------------
/www/.htaccess:
--------------------------------------------------------------------------------
1 | # Apache configuration file (see httpd.apache.org/docs/current/mod/quickreference.html)
2 |
3 | # disable directory listing
4 |
5 | Options -Indexes
6 |
7 |
8 | # enable cool URL
9 |
10 | RewriteEngine On
11 | # RewriteBase /
12 |
13 | # prevents files starting with dot to be viewed by browser
14 | RewriteRule /\.|^\. - [F]
15 |
16 | # front controller
17 | RewriteCond %{REQUEST_FILENAME} !-f
18 | RewriteCond %{REQUEST_FILENAME} !-d
19 | RewriteRule !\.(pdf|js|ico|gif|jpg|png|css|rar|zip|tar\.gz)$ index.php [L]
20 |
21 |
22 | # enable gzip compression
23 |
24 | AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/x-javascript text/javascript application/javascript application/json
25 |
26 |
--------------------------------------------------------------------------------
/app/Bootstrap.php:
--------------------------------------------------------------------------------
1 | setDebugMode(['127.0.0.1']);
16 | $configurator->enableTracy($appDir . '/log');
17 | $configurator->setTempDirectory($appDir . '/temp');
18 | $configurator->createRobotLoader()->addDirectory(__DIR__)->register();
19 |
20 | $configurator->addConfig($appDir . '/config/common.neon');
21 | $configurator->addConfig($appDir . '/config/services.neon');
22 | $configurator->addConfig($appDir . '/config/db.neon');
23 | $configurator->addConfig($appDir . '/config/db.local.neon');
24 |
25 | return $configurator;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/Presenters/Error4xxPresenter.php:
--------------------------------------------------------------------------------
1 | */
15 | public array $allowedMethods = [];
16 |
17 |
18 | public function renderDefault(Nette\Application\BadRequestException $exception): void
19 | {
20 | // renders the appropriate error template based on the HTTP status code
21 | $code = $exception->getCode();
22 | $file = is_file($file = __DIR__ . "/templates/Error/$code.latte")
23 | ? $file
24 | : __DIR__ . '/templates/Error/4xx.latte';
25 | assert($this->template instanceof Nette\Bridges\ApplicationLatte\Template);
26 | $this->template->httpCode = $code;
27 | $this->template->setFile($file);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "php": ">=8.1",
4 | "nette/application": "^3.2",
5 | "nette/bootstrap": "^3.2",
6 | "nette/caching": "^3.3",
7 | "nette/di": "^3.2",
8 | "nette/finder": "^3.0",
9 | "nette/forms": "^3.2",
10 | "nette/http": "^3.3",
11 | "nette/mail": "^3.1",
12 | "nette/robot-loader": "^4.0",
13 | "nette/security": "^3.2",
14 | "nette/utils": "^4.0",
15 | "latte/latte": "^3.0",
16 | "tracy/tracy": "^2.10",
17 | "nextras/orm": "@dev",
18 | "nextras/dbal": "@dev",
19 | "nextras/migrations": "^3.3",
20 | "contributte/console": "^0.10"
21 | },
22 | "require-dev": {
23 | "phpstan/phpstan": "^1.10",
24 | "nextras/orm-phpstan": "@dev",
25 | "phpstan/phpstan-nette": "^1.2",
26 | "phpstan/extension-installer": "^1.3"
27 | },
28 | "autoload": {
29 | "psr-4": {
30 | "OrmDemo\\": "app"
31 | }
32 | },
33 | "scripts": {
34 | "phpstan": "phpstan analyze -c .phpstan.neon"
35 | },
36 | "config": {
37 | "allow-plugins": {
38 | "phpstan/extension-installer": true
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/Presenters/Error5xxPresenter.php:
--------------------------------------------------------------------------------
1 | getParameter('exception');
27 | $this->logger->log($exception, ILogger::EXCEPTION);
28 |
29 | // Display a generic error message to the user
30 | return new Responses\CallbackResponse(function (Http\IRequest $httpRequest, Http\IResponse $httpResponse): void {
31 | if (preg_match('#^text/html(?:;|$)#', (string)$httpResponse->getHeader('Content-Type'))) {
32 | require __DIR__ . '/templates/Error/500.phtml';
33 | }
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: "Build"
2 |
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - main
8 |
9 | env:
10 | php-tools: "composer:v2"
11 |
12 | jobs:
13 | phpstan:
14 | name: PHPStan
15 |
16 | runs-on: ubuntu-latest
17 |
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v2
21 |
22 | - name: Setup PHP with pecl extension
23 | uses: shivammathur/setup-php@v2
24 | with:
25 | php-version: 8.3
26 |
27 | - name: Get composer cache directory
28 | id: composercache
29 | run: echo "::set-output name=dir::$(composer config cache-files-dir)"
30 |
31 | - name: Cache dependencies
32 | uses: actions/cache@v2
33 | with:
34 | path: ${{ steps.composercache.outputs.dir }}
35 | key: ${{ runner.os }}-composer-${{ hashFiles('composer.json') }}
36 | restore-keys: ${{ runner.os }}-composer-
37 |
38 | - name: Install dependencies
39 | run: composer install --prefer-dist
40 |
41 | - name: Run PHPStan
42 | run: composer phpstan
43 |
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | The MIT License
2 | ===============
3 |
4 | Copyright (c) 2014 Nextras Project
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/migrations/structures/2014-05-30-001-basic-structure.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `comments` (
2 | `id` int(11) NOT NULL AUTO_INCREMENT,
3 | `post_id` int(11) NOT NULL,
4 | `name` varchar(255) DEFAULT NULL,
5 | `email` varchar(255) DEFAULT NULL,
6 | `content` text NOT NULL,
7 | `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
8 | PRIMARY KEY (`id`),
9 | KEY `post_id` (`post_id`),
10 | CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
12 |
13 |
14 | CREATE TABLE `posts` (
15 | `id` int(11) NOT NULL AUTO_INCREMENT,
16 | `title` varchar(255) NOT NULL,
17 | `content` text NOT NULL,
18 | `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
19 | PRIMARY KEY (`id`)
20 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
21 |
22 |
23 | CREATE TABLE `tags` (
24 | `id` int(11) NOT NULL AUTO_INCREMENT,
25 | `name` varchar(255) NOT NULL,
26 | PRIMARY KEY (`id`)
27 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
28 |
29 |
30 | CREATE TABLE `posts_x_tags` (
31 | `post_id` int(11) NOT NULL,
32 | `tag_id` int(11) NOT NULL,
33 | PRIMARY KEY (`post_id`, `tag_id`),
34 | CONSTRAINT `posts_x_tags_ibfk_1` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`),
35 | CONSTRAINT `posts_x_tags_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`)
36 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
37 |
--------------------------------------------------------------------------------
/app/Presenters/templates/Error/500.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Server Error
5 |
6 |
13 |
14 |
15 |
16 |
Server Error
17 |
18 |
We're sorry! The server encountered an internal error and
19 | was unable to complete your request. Please try again later.
20 |
21 |
error 500
22 |
23 |
24 |
25 |
28 |
--------------------------------------------------------------------------------
/app/Blog/Model/Posts/Post.php:
--------------------------------------------------------------------------------
1 | $allComments {1:m Comment::$post}
22 | * @property ManyHasMany $tags {m:m Tag::$posts, isMain=true}
23 | *
24 | * @property-read ICollection $comments {virtual}
25 | */
26 | class Post extends Entity
27 | {
28 | public function __construct(string $title, string $content)
29 | {
30 | parent::__construct();
31 | $this->title = $title;
32 | $this->content = $content;
33 | }
34 |
35 |
36 | /**
37 | * @return ICollection
38 | */
39 | public function getterComments(): ICollection
40 | {
41 | return $this->allComments->toCollection()->findBy(['deletedAt' => null]);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/Blog/Presenters/HomePresenter.php:
--------------------------------------------------------------------------------
1 | createTemplate(PostListTemplate::class);
25 | $template->posts = $this->orm->posts->findHomepageOverview();
26 | $this->sendTemplate($template);
27 | }
28 |
29 |
30 | public function actionDetail(int $id): void
31 | {
32 | $this->post = $this->orm->posts->getByIdChecked($id);
33 | }
34 |
35 |
36 | public function renderDetail(int $id): void
37 | {
38 | if (!$this->post) $this->error();
39 |
40 | $template = $this->createTemplate(PostDetailTemplate::class);
41 | $template->post = $this->post;
42 | $this->sendTemplate($template);
43 | }
44 |
45 |
46 | protected function createComponentAddCommentForm(): Form
47 | {
48 | $form = new Form;
49 | $form->addText('name', 'Name')->setRequired();
50 | $form->addText('email', 'E-mail')->setHtmlType('email');
51 | $form->addTextArea('content', 'Comment');
52 | $form->addSubmit('submit', 'Add comment');
53 | $form->onSuccess[] = $this->processAddCommentForm(...);
54 | return $form;
55 | }
56 |
57 |
58 | public function processAddCommentForm(Form $form, ArrayHash $values): void
59 | {
60 | if (!$this->post) $this->error();
61 |
62 | $comment = new Comment();
63 | $comment->content = $values->content;
64 | $comment->name = $values->name;
65 | $comment->email = $values->email;
66 | $comment->post = $this->post;
67 |
68 | $this->orm->comments->persistAndFlush($comment);
69 | $this->redirect('this');
70 | }
71 |
72 |
73 | public function handleDeleteComment(int $commentId): void
74 | {
75 | $comment = $this->orm->comments->getByIdChecked($commentId);
76 | $comment->deletedAt = 'now';
77 | $this->orm->comments->persistAndFlush($comment);
78 | $this->redirect('this');
79 | }
80 |
81 |
82 | public function createComponentUpdateTagsForm(): Form
83 | {
84 | if (!$this->post) $this->error();
85 |
86 | $form = new Form;
87 | $form->addCheckboxList('tags', 'Tags', $this->orm->tags->findAll()->fetchPairs('id', 'name'))
88 | ->setDefaultValue($this->post->tags->getRawValue());
89 |
90 | $form->addSubmit('submit', 'Save tags');
91 | $form->onSuccess[] = $this->processUpdateTagsForm(...);
92 | return $form;
93 | }
94 |
95 |
96 | public function processUpdateTagsForm(Form $form, ArrayHash $values): void
97 | {
98 | if (!$this->post) $this->error();
99 |
100 | $this->post->tags->set($values->tags);
101 | $this->orm->posts->persistAndFlush($this->post);
102 | $this->redirect('this');
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/migrations/dummy-data/2014-05-30-002-basic-testdata.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO `comments` (`id`, `post_id`, `name`, `email`, `content`, `created_at`) VALUES
2 | (1, 1, 'Jakub', NULL, 'Wort Dressed Sentinent Being water quite a moment and show thirty speck by the floor. brightness glowed at least, nearly dead and was obviously some Vegan Rhino\'s cutlet. It\'s unpleasantly like hitch hiking slang, as anything. - said Zaphod. - Y', '2009-05-11 07:06:05'),
3 | (2, 2, 'Ondřej', NULL, 'Enormous round and guidance system will jump haven\'t opened through the faintly irritated him - That\'s just to Cassette recorder, every to to thirty seconds of us. Arthur began to have Wow, - said to discover into off with pleased with ', '2009-05-19 23:23:21'),
4 | (3, 2, 'Gabriel', NULL, 'Ape-descendant Arthur Dent, and equally get a stone sundial pedestal housed The mice He looked up sharply. He threw Ford handed the Earth passed an answer. - You know, not even finished Permeated - He adjusted it. Arthur agreed with the time', '2009-05-20 04:40:48'),
5 | (4, 2, 'Jakub', NULL, 'Cracked bell, feet up. - Are you will finally managed to see very strong desire just happens. Yeah, I bother please, the not be, - Missiles? Don\'t talk about the common light Slurrp almost to come and the other bits consequences get there ', '2009-05-20 05:14:31'),
6 | (5, 2, 'Daniel', NULL, 'Emphasized because, as the white mice sniffed irritably decided that the ship that the sweaty dishevelled clothes he was for Arthur shivered with Deep Thought, - protested Ford. - said by your brain was almost, miles is each other. Fook ', '2009-05-20 08:31:40'),
7 | (6, 2, 'Emily', NULL, 'Desk. bubble, the wrong bit and the Earth years, maybe that anyone who could get the Sirius Cybernetics Corporation defines a moment, relax and so I\'ve heard rumors about in all intelligent that one pot shot out before a planet ', '2009-05-20 09:52:00'),
8 | (7, 3, 'Olivia', NULL, 'Silly antennae on the thirty seconds later he said. - Yes, - I\'m President always used to give it then? - Well? - Oh into the cold mud. It was clearly was built, and local affairs that\'s for a wicked grin, laugh did we knew much as the spectacle', '2009-05-28 01:50:18'),
9 | (8, 3, 'Vojtěch', NULL, 'Fact! bubble, the wrong bit and the Earth years, maybe that anyone who could get the Sirius Cybernetics Corporation defines a moment, relax and so I\'ve heard rumors about in all ', '2009-05-28 10:06:31'),
10 | (9, 3, 'William', NULL, 'Protruding from years, maybe even myself? slippers, ladder, moon, nightfall was at each other cajoleries and down Diurnal course. - A man frowned at his semi-cousin that through the faintly irritated him - That\'s just to ', '2009-05-28 17:25:41'),
11 | (10, 3, 'Simon', NULL, 'Minds big hello said Arthur. - I will finally realized that he said, - it was only fooling, - What is an interstellar distances in front partly More gunk music and it had nervously, I ', '2009-05-28 23:25:25'),
12 | (11, 3, 'Amelia', NULL, 'Ape-descendant Arthur Dent, and equally get a stone sundial pedestal housed The mice He looked up sharply. He threw Ford handed the Earth passed an answer. - You know, not even finished Permeated - He adjusted it. Arthur agreed with the time', '2009-05-29 06:19:14'),
13 | (12, 4, 'Emily', NULL, 'Violent noise leapt to thirty seconds later he said. - Yes, - I\'m President always used to give it then? - Well? - Oh into the cold mud. It was clearly was built, and local affairs that\'s for a wicked grin, laugh did we knew ', '2009-06-08 17:07:21'),
14 | (13, 4, 'Jessica', NULL, 'Air cushions ballooned out white mice sniffed irritably decided that the ship that the sweaty dishevelled clothes he was for ', '2009-06-08 21:10:34'),
15 | (14, 4, 'Elias', NULL, 'Demarcation may or the wrong bit and the Earth years, maybe that anyone who could get the Sirius Cybernetics Corporation defines a moment, relax and so I\'ve heard rumors about in all intelligent that one pot shot out before a planet ', '2009-06-09 04:40:35'),
16 | (15, 5, 'Jessica', NULL, 'Hence the slow heavy river Moth; wet of the time fresh whalemeat. At lunchtime? The Vogon guard dragged them brightness glowed at least, nearly dead and was obviously some Vegan Rhino\'s cutlet. It\'s unpleasantly like hitch hiking slang, as Tru', '2009-06-19 01:56:47'),
17 | (16, 5, 'Joshua', NULL, 'Optician almost to come and the other bits consequences get there now. The other illusory somewhere brushed backwards of how was was a sharp ringing tones. - he said Slartibartfast coughed politely. - moment in Stone. It saved a white', '2009-06-19 03:44:05'),
18 | (17, 5, 'Lukas', NULL, 'Desk. bubble, the wrong bit and the Earth years, maybe that anyone who could get the Sirius Cybernetics Corporation defines a moment, relax and so I\'ve heard rumors about in all intelligent that one pot shot out before a planet ', '2009-06-19 07:16:40'),
19 | (18, 5, 'Grace', NULL, 'Dent sat on him. - Yeah, OK, - Oh those doors. There must have something else. Come on, to help him, small really thrash it space that ', '2009-06-19 07:28:33');
20 |
21 | INSERT INTO `posts` (`id`, `title`, `content`, `created_at`) VALUES
22 | (1, 'Thronged with making you doing', 'Out! looked like it. At an anachronism. The Dentrassis fine, moon, nightfall was at each other cajoleries and down there? - said Arthur turned himself up. - The that now six know the Universe, and it to know directly his seemed certain carbon-ba', '2009-05-11 03:31:16'),
23 | (2, 'Jerked himself feet up', 'Refit, and found to come and the other bits consequences get there now. The other illusory somewhere brushed backwards of how was was a sharp ringing tones. - he said Slartibartfast coughed. Otherwise me. - He passed right between was b', '2009-05-19 15:24:30'),
24 | (3, 'Danger', 'Usually had to one would I know, - Oh those doors. There must have something else. Come on, to help him, small really thrash it space that now six know the Universe, and it to know directly his seemed certain carbon-based life and.', '2009-05-28 01:18:15'),
25 | (4, 'Tossed looked like it', 'Busy? - Just shut up, that spaceship and spewed up in emergencies as such, but... - yelled Ford, - said Arthur Dent with me? - said about to a rather into his neck. The President of the planet Bethselamin soft and said, very fast. Very good. For wha', '2009-06-08 13:17:21'),
26 | (5, 'Eddie your eyes...', 'Airlock hatchway into your house down! Ford Prefect\'s were it for Magrathea, immediate sense in major intestine, in a solid small really thrash it space that now six know the Universe, and it to know directly. House Down Once you talked to', '2009-06-18 23:55:45');
27 |
28 | INSERT INTO `tags` (`id`, `name`) VALUES
29 | (1, 'PHP'),
30 | (2, 'MySQL'),
31 | (3, 'Nette'),
32 | (4, 'Nextras'),
33 | (5, 'PostgreSQL');
34 |
35 | INSERT INTO `posts_x_tags` (`post_id`, `tag_id`) VALUES
36 | (1, 1),
37 | (1, 2),
38 | (1, 3),
39 | (2, 4),
40 | (3, 4),
41 | (4, 4),
42 | (4, 5),
43 | (5, 1);
44 |
--------------------------------------------------------------------------------
{$comment->content}
17 |