Added code chunk viewing and inserting possibility

Signed-off-by: Gergely Polonkai (W00d5t0ck) <polesz@w00d5t0ck.info>
This commit is contained in:
Gergely Polonkai (W00d5t0ck) 2012-09-05 12:59:21 +02:00
parent bcf6368db2
commit a41ddec070
16 changed files with 399 additions and 20 deletions

View File

@ -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");
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Application\Migrations;
use Doctrine\DBAL\Migrations\AbstractMigration,
Doctrine\DBAL\Schema\Schema;
/**
* Auto-generated Migration: Please modify to your need!
*/
class Version20120905113054 extends AbstractMigration
{
public function up(Schema $schema)
{
// this up() migration is autogenerated, please modify it to your needs
$this->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");
}
}

View File

@ -13,7 +13,7 @@ use GergelyPolonkai\FrontBundle\Entity\Post;
* Description of AdminController
*
* @author polonkai.gergely
*
*
* @Route("/admin")
*/
class AdminController extends Controller

View File

@ -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,
);
}
}

View File

@ -0,0 +1,192 @@
<?php
namespace GergelyPolonkai\FrontBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as GedmoORM;
/**
* Description of CodeChunk
*
* @author polonkai.gergely
*
* @ORM\Entity
* @ORM\Table(name="code_chunks")
*/
class CodeChunk
{
/**
*
* @var integer $id
*
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
*
* @var string $language
*
* @ORM\Column(type="string", length=20, nullable=false)
*/
private $language;
/**
*
* @var string $title
*
* @ORM\Column(type="string", length=100, nullable=false)
*/
private $title;
/**
*
* @var string $slug
*
* @GedmoORM\Slug(fields={"title"})
* @ORM\Column(type="string", length=100, nullable=false)
*/
private $slug;
/**
*
* @var string $description
*
* @ORM\Column(type="text", nullable=true)
*/
private $description;
/**
*
* @var string $content
*
* @ORM\Column(type="text", nullable=false)
*/
private $content;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -10,4 +10,4 @@
<input type="password" name="_password" />
<button type="submit">Login</button>
</form>
{% endblock %}
{% endblock %}

View File

@ -5,4 +5,4 @@
{{ form_widget(form) }}
<button type="submit">Save</button>
</form>
{% endblock content %}
{% endblock content %}

View File

@ -0,0 +1,3 @@
<h3>{% if title_links %}<a href="{{ path('GergelyPolonkaiFront_blogViewPost', {year: post.createdAt|date('Y'), month: post.createdAt|date('m'), day: post.createdAt|date('d'), slug: post.slug}) }}">{% endif %}{{ post.title }}{% if title_links %}</a>{% endif %}</h3>
<p class="article-date">{{ post.createdAt|date('m-d-Y :: H:i') }} by {{ post.user.name }}</p>
{{ post.content|insert_code_chunks }}

View File

@ -1,6 +1,5 @@
{% extends 'GergelyPolonkaiFrontBundle:Default:front_base.html.twig' %}
{% block content %}
<h3>{{ post.title }}</h3>
<p class="article-date">{{ post.createdAt|date('m-d-Y :: H:i') }} by {{ post.user.name }}</p>
{{ post.content|raw }}
{% include 'GergelyPolonkaiFrontBundle:Blog:postViewer.html.twig' with {'post': post, 'title_links': false} %}
{% endblock content %}

View File

@ -2,8 +2,6 @@
{% block content %}
{% for post in posts %}
<h3><a href="{{ path('GergelyPolonkaiFront_blogViewPost', {year: post.createdAt|date('Y'), month: post.createdAt|date('m'), day: post.createdAt|date('d'), slug: post.slug}) }}">{{ post.title }}</a></h3>
<p class="article-date">{{ post.createdAt|date('m-d-Y :: H:i') }} by {{ post.user.name }}</p>
{{ post.content|raw }}
{% include 'GergelyPolonkaiFrontBundle:Blog:postViewer.html.twig' with {'post': post, 'title_links': true} %}
{% endfor %}
{% endblock content %}

View File

@ -0,0 +1,11 @@
{% extends 'GergelyPolonkaiFrontBundle:Default:front_base.html.twig' %}
{% block content %}
<h3>{{ code_chunk.title }}</h3>
{{ code_chunk.content|geshi_highlight(code_chunk.language) }}
{% if code_chunk.description %}
<div class="code-description">
{{ code_chunk.description }}
</div>
{% endif %}
{% endblock %}

View File

@ -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);
}
}

View File

@ -0,0 +1,96 @@
<?php
namespace GergelyPolonkai\FrontBundle\Twig;
use Symfony\Bridge\Doctrine\RegistryInterface;
use JMS\DiExtraBundle\Annotation as DI;
use Symfony\Component\Routing\Router;
/**
* Description of CodeChunk
*
* @author polonkai.gergely
*
* @DI\Service
* @DI\Tag("twig.extension")
*/
class CodeChunk extends \Twig_Extension
{
/**
* @var Symfony\Bridge\Doctrine\RegistryInterface $doctrine
*/
private $doctrine;
/**
*
* @var Symfony\Component\Routing\Router $router
*/
private $router;
private $hiliter;
/**
* @DI\InjectParams({
* "doctrine" = @DI\Inject("doctrine"),
* "router" = @DI\Inject("router"),
* "hiliter" = @DI\Inject("gergely_polonkai_geshi.geshi_highlighter")
* })
*/
public function __construct(RegistryInterface $doctrine, Router $router, $hiliter)
{
$this->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 = '<div class="code-chunk">
<p class="code-title"><a href="' . $link . '">' . $chunk->getTitle() . '</a></p>
' . $this->hiliter->geshiFilter($chunk->getContent(), $lang) . "\n";
$description = $chunk->getDescription();
if (($description !== null) && ($description != '')) {
$replacement .= ' <div class="code-description">
' . $description . "
</div>\n";
}
$replacement .= '</div>';
}
$string = substr_replace($string, $replacement, $start, $len);
}
return $string;
}
public function getName()
{
return "code_chunk";
}
}