From a41ddec070a83b0aa85c1fbf9549d37e62f72068 Mon Sep 17 00:00:00 2001 From: "Gergely Polonkai (W00d5t0ck)" Date: Wed, 5 Sep 2012 12:59:21 +0200 Subject: [PATCH] Added code chunk viewing and inserting possibility Signed-off-by: Gergely Polonkai (W00d5t0ck) --- .../Version20120904170638.php | 4 +- .../Version20120905113054.php | 28 +++ .../Controller/AdminController.php | 2 +- .../Controller/DefaultController.php | 20 ++ .../FrontBundle/Entity/CodeChunk.php | 192 ++++++++++++++++++ .../FrontBundle/Entity/Post.php | 6 +- .../FrontBundle/Entity/User.php | 12 +- .../FrontBundle/Resources/public/css/code.css | 26 +++ .../Resources/views/Admin/login.html.twig | 2 +- .../views/Admin/newBlogPost.html.twig | 2 +- .../Resources/views/Blog/postViewer.html.twig | 3 + .../Resources/views/Blog/viewPost.html.twig | 5 +- .../Resources/views/Default/index.html.twig | 4 +- .../views/Default/viewCode.html.twig | 11 + .../FrontBundle/Service/CryptEncoder.php | 6 +- .../FrontBundle/Twig/CodeChunk.php | 96 +++++++++ 16 files changed, 399 insertions(+), 20 deletions(-) create mode 100644 app/DoctrineMigrations/Version20120905113054.php create mode 100644 src/GergelyPolonkai/FrontBundle/Entity/CodeChunk.php create mode 100644 src/GergelyPolonkai/FrontBundle/Resources/views/Blog/postViewer.html.twig create mode 100644 src/GergelyPolonkai/FrontBundle/Resources/views/Default/viewCode.html.twig create mode 100644 src/GergelyPolonkai/FrontBundle/Twig/CodeChunk.php diff --git a/app/DoctrineMigrations/Version20120904170638.php b/app/DoctrineMigrations/Version20120904170638.php index cae25de..9266c48 100644 --- a/app/DoctrineMigrations/Version20120904170638.php +++ b/app/DoctrineMigrations/Version20120904170638.php @@ -14,7 +14,7 @@ class Version20120904170638 extends AbstractMigration { // this up() migration is autogenerated, please modify it to your needs $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql"); - + $this->addSql("ALTER TABLE users ADD password VARCHAR(50) NOT NULL"); } @@ -22,7 +22,7 @@ class Version20120904170638 extends AbstractMigration { // this down() migration is autogenerated, please modify it to your needs $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql"); - + $this->addSql("ALTER TABLE users DROP password"); } } diff --git a/app/DoctrineMigrations/Version20120905113054.php b/app/DoctrineMigrations/Version20120905113054.php new file mode 100644 index 0000000..a4eac65 --- /dev/null +++ b/app/DoctrineMigrations/Version20120905113054.php @@ -0,0 +1,28 @@ +abortIf($this->connection->getDatabasePlatform()->getName() != "mysql"); + + $this->addSql("CREATE TABLE code_chunks (id INT AUTO_INCREMENT NOT NULL, language VARCHAR(20) NOT NULL, title VARCHAR(100) NOT NULL, slug VARCHAR(100) NOT NULL, description LONGTEXT DEFAULT NULL, content LONGTEXT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB"); + } + + public function down(Schema $schema) + { + // this down() migration is autogenerated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql"); + + $this->addSql("DROP TABLE code_chunks"); + } +} diff --git a/src/GergelyPolonkai/FrontBundle/Controller/AdminController.php b/src/GergelyPolonkai/FrontBundle/Controller/AdminController.php index df4dc57..ea623cd 100644 --- a/src/GergelyPolonkai/FrontBundle/Controller/AdminController.php +++ b/src/GergelyPolonkai/FrontBundle/Controller/AdminController.php @@ -13,7 +13,7 @@ use GergelyPolonkai\FrontBundle\Entity\Post; * Description of AdminController * * @author polonkai.gergely - * + * * @Route("/admin") */ class AdminController extends Controller diff --git a/src/GergelyPolonkai/FrontBundle/Controller/DefaultController.php b/src/GergelyPolonkai/FrontBundle/Controller/DefaultController.php index 5b83716..066613e 100644 --- a/src/GergelyPolonkai/FrontBundle/Controller/DefaultController.php +++ b/src/GergelyPolonkai/FrontBundle/Controller/DefaultController.php @@ -5,6 +5,9 @@ namespace GergelyPolonkai\FrontBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; + +use GergelyPolonkai\FrontBundle\Entity\CodeChunk; /** * @Route("") @@ -60,4 +63,21 @@ class DefaultController extends Controller ); } } + + /** + * + * @param string $slug + * @param string $language + * @return array + * + * @Route("/code-chunk/{language}/{slug}.html", name="GergelyPolonkaiFrontBundle_viewCode") + * @Template + * @ParamConverter("codeChunk", options={"mapping"={"slug"="slug", "language"="language"}}) + */ + public function viewCodeAction(CodeChunk $codeChunk) + { + return array( + 'code_chunk' => $codeChunk, + ); + } } diff --git a/src/GergelyPolonkai/FrontBundle/Entity/CodeChunk.php b/src/GergelyPolonkai/FrontBundle/Entity/CodeChunk.php new file mode 100644 index 0000000..01a81ac --- /dev/null +++ b/src/GergelyPolonkai/FrontBundle/Entity/CodeChunk.php @@ -0,0 +1,192 @@ +id; + } + + /** + * Set language + * + * @param string $language + * @return CodeChunk + */ + public function setLanguage($language) + { + $this->language = $language; + + return $this; + } + + /** + * Get language + * + * @return string + */ + public function getLanguage() + { + return $this->language; + } + + /** + * Set title + * + * @param string $title + * @return CodeChunk + */ + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set slug + * + * @param string $slug + * @return CodeChunk + */ + public function setSlug($slug) + { + $this->slug = $slug; + + return $this; + } + + /** + * Get slug + * + * @return string + */ + public function getSlug() + { + return $this->slug; + } + + /** + * Set description + * + * @param string $description + * @return CodeChunk + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + /** + * Get description + * + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set content + * + * @param string $content + * @return CodeChunk + */ + public function setContent($content) + { + $this->content = $content; + + return $this; + } + + /** + * Get content + * + * @return string + */ + public function getContent() + { + return $this->content; + } +} diff --git a/src/GergelyPolonkai/FrontBundle/Entity/Post.php b/src/GergelyPolonkai/FrontBundle/Entity/Post.php index 866aff3..7137901 100644 --- a/src/GergelyPolonkai/FrontBundle/Entity/Post.php +++ b/src/GergelyPolonkai/FrontBundle/Entity/Post.php @@ -167,7 +167,7 @@ class Post /** * Set slug * - * @param string $slug + * @param string $slug * @return Post */ public function setSlug($slug) @@ -180,7 +180,7 @@ class Post /** * Set createdAt * - * @param \DateTime $createdAt + * @param \DateTime $createdAt * @return Post */ public function setCreatedAt($createdAt) @@ -189,4 +189,4 @@ class Post return $this; } -} \ No newline at end of file +} diff --git a/src/GergelyPolonkai/FrontBundle/Entity/User.php b/src/GergelyPolonkai/FrontBundle/Entity/User.php index 280636c..bd5b83a 100644 --- a/src/GergelyPolonkai/FrontBundle/Entity/User.php +++ b/src/GergelyPolonkai/FrontBundle/Entity/User.php @@ -43,14 +43,17 @@ class User implements UserInterface return $this->name . '(' . $this->username . ')'; } - public function getSalt() { + public function getSalt() + { return $this->password; } - public function eraseCredentials() { + public function eraseCredentials() + { } - public function getRoles() { + public function getRoles() + { return array('ROLE_ADMIN'); } @@ -119,6 +122,7 @@ class User implements UserInterface public function setPassword($password) { $this->password = $password; + return $this; } @@ -131,4 +135,4 @@ class User implements UserInterface { return $this->password; } -} \ No newline at end of file +} diff --git a/src/GergelyPolonkai/FrontBundle/Resources/public/css/code.css b/src/GergelyPolonkai/FrontBundle/Resources/public/css/code.css index 803f2a3..fddb488 100644 --- a/src/GergelyPolonkai/FrontBundle/Resources/public/css/code.css +++ b/src/GergelyPolonkai/FrontBundle/Resources/public/css/code.css @@ -6,12 +6,38 @@ Purpose of the stylesheet follows. */ +.code-chunk { + background-color: #b5b5b5; + padding: 10px; +} + +.code-chunk .code-title { + text-indent: 0 !important; + font-size: 120%; + font-weight: bold; +} + +.code-chunk .code-description { + border: 1px solid #333; + background-color: #d9d9d9; + padding: 3px; + text-indent: 0 !important; + margin: .5em 0 0 0 !important; + font-size: 75%; + color: #444; +} + .code { font-family: monospace; background-color: #333; padding: 5px; } +.code-chunk .code { + height: 300px; + overflow: auto; +} + .code * { font-family: monospace; color: #b5b5b5; diff --git a/src/GergelyPolonkai/FrontBundle/Resources/views/Admin/login.html.twig b/src/GergelyPolonkai/FrontBundle/Resources/views/Admin/login.html.twig index 0068e6d..8d2976a 100644 --- a/src/GergelyPolonkai/FrontBundle/Resources/views/Admin/login.html.twig +++ b/src/GergelyPolonkai/FrontBundle/Resources/views/Admin/login.html.twig @@ -10,4 +10,4 @@ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/src/GergelyPolonkai/FrontBundle/Resources/views/Admin/newBlogPost.html.twig b/src/GergelyPolonkai/FrontBundle/Resources/views/Admin/newBlogPost.html.twig index c05de15..db3e60d 100644 --- a/src/GergelyPolonkai/FrontBundle/Resources/views/Admin/newBlogPost.html.twig +++ b/src/GergelyPolonkai/FrontBundle/Resources/views/Admin/newBlogPost.html.twig @@ -5,4 +5,4 @@ {{ form_widget(form) }} -{% endblock content %} \ No newline at end of file +{% endblock content %} diff --git a/src/GergelyPolonkai/FrontBundle/Resources/views/Blog/postViewer.html.twig b/src/GergelyPolonkai/FrontBundle/Resources/views/Blog/postViewer.html.twig new file mode 100644 index 0000000..f087b33 --- /dev/null +++ b/src/GergelyPolonkai/FrontBundle/Resources/views/Blog/postViewer.html.twig @@ -0,0 +1,3 @@ +

{% if title_links %}{% endif %}{{ post.title }}{% if title_links %}{% endif %}

+ +{{ post.content|insert_code_chunks }} diff --git a/src/GergelyPolonkai/FrontBundle/Resources/views/Blog/viewPost.html.twig b/src/GergelyPolonkai/FrontBundle/Resources/views/Blog/viewPost.html.twig index 2cfd600..c7fc3e8 100644 --- a/src/GergelyPolonkai/FrontBundle/Resources/views/Blog/viewPost.html.twig +++ b/src/GergelyPolonkai/FrontBundle/Resources/views/Blog/viewPost.html.twig @@ -1,6 +1,5 @@ {% extends 'GergelyPolonkaiFrontBundle:Default:front_base.html.twig' %} + {% block content %} -

{{ post.title }}

- -{{ post.content|raw }} +{% include 'GergelyPolonkaiFrontBundle:Blog:postViewer.html.twig' with {'post': post, 'title_links': false} %} {% endblock content %} diff --git a/src/GergelyPolonkai/FrontBundle/Resources/views/Default/index.html.twig b/src/GergelyPolonkai/FrontBundle/Resources/views/Default/index.html.twig index 08bf983..62bef9c 100644 --- a/src/GergelyPolonkai/FrontBundle/Resources/views/Default/index.html.twig +++ b/src/GergelyPolonkai/FrontBundle/Resources/views/Default/index.html.twig @@ -2,8 +2,6 @@ {% block content %} {% for post in posts %} -

{{ post.title }}

- -{{ post.content|raw }} +{% include 'GergelyPolonkaiFrontBundle:Blog:postViewer.html.twig' with {'post': post, 'title_links': true} %} {% endfor %} {% endblock content %} diff --git a/src/GergelyPolonkai/FrontBundle/Resources/views/Default/viewCode.html.twig b/src/GergelyPolonkai/FrontBundle/Resources/views/Default/viewCode.html.twig new file mode 100644 index 0000000..6c289c1 --- /dev/null +++ b/src/GergelyPolonkai/FrontBundle/Resources/views/Default/viewCode.html.twig @@ -0,0 +1,11 @@ +{% extends 'GergelyPolonkaiFrontBundle:Default:front_base.html.twig' %} + +{% block content %} +

{{ code_chunk.title }}

+{{ code_chunk.content|geshi_highlight(code_chunk.language) }} +{% if code_chunk.description %} +
+ {{ code_chunk.description }} +
+{% endif %} +{% endblock %} diff --git a/src/GergelyPolonkai/FrontBundle/Service/CryptEncoder.php b/src/GergelyPolonkai/FrontBundle/Service/CryptEncoder.php index 700ffa5..f674d5c 100644 --- a/src/GergelyPolonkai/FrontBundle/Service/CryptEncoder.php +++ b/src/GergelyPolonkai/FrontBundle/Service/CryptEncoder.php @@ -13,11 +13,13 @@ use JMS\DiExtraBundle\Annotation as DI; */ class CryptEncoder implements PasswordEncoderInterface { - public function encodePassword($raw, $salt) { + public function encodePassword($raw, $salt) + { return crypt($raw); } - public function isPasswordValid($encoded, $raw, $salt) { + public function isPasswordValid($encoded, $raw, $salt) + { return (crypt($raw, $encoded) === $encoded); } } diff --git a/src/GergelyPolonkai/FrontBundle/Twig/CodeChunk.php b/src/GergelyPolonkai/FrontBundle/Twig/CodeChunk.php new file mode 100644 index 0000000..4f04801 --- /dev/null +++ b/src/GergelyPolonkai/FrontBundle/Twig/CodeChunk.php @@ -0,0 +1,96 @@ +doctrine = $doctrine; + $this->router = $router; + $this->hiliter = $hiliter; + } + + public function getFilters() + { + return array( + 'insert_code_chunks' => new \Twig_Filter_Method($this, 'insertCodeChunks', array('is_safe' => array('html'))), + ); + } + + public function insertCodeChunks($string) + { + $m = array(); + $chunkRepo = $this->doctrine->getRepository('GergelyPolonkaiFrontBundle:CodeChunk'); + + while ( + preg_match( + '/\\[\\$ code:([^:]+):([^ ]+) \\$\\]/i', + $string, $m, PREG_OFFSET_CAPTURE) + ) { + $start = $m[0][1]; + $fullTag = $m[0][0]; + $len = strlen($fullTag); + + $lang = strtolower($m[1][0]); + $slug = strtolower($m[2][0]); + + $replacement = ''; + $chunk = $chunkRepo->findOneBy(array('language' => $lang, 'slug' => $slug)); + + if ($chunk !== null) { + $link = $this->router->generate('GergelyPolonkaiFrontBundle_viewCode', array('language' => $lang, 'slug' => $slug)); + $replacement = '
+

' . $chunk->getTitle() . '

+' . $this->hiliter->geshiFilter($chunk->getContent(), $lang) . "\n"; + $description = $chunk->getDescription(); + if (($description !== null) && ($description != '')) { + $replacement .= '
+ ' . $description . " +
\n"; + } + $replacement .= '
'; + } + + $string = substr_replace($string, $replacement, $start, $len); + } + + return $string; + } + + public function getName() + { + return "code_chunk"; + } +}