diff --git a/.travis.yml b/.travis.yml index dcb2101..4d5a785 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -# See https://github.com/silverstripe/silverstripe-travis-support for setup details - sudo: false language: php diff --git a/.tx/config b/.tx/config deleted file mode 100644 index 342ae51..0000000 --- a/.tx/config +++ /dev/null @@ -1,8 +0,0 @@ -[main] -host = https://www.transifex.com - -[silverstripe-blog.master-v2] -file_filter = lang/.yml -source_file = lang/en.yml -source_lang = en -type = YML diff --git a/src/Model/BlogController.php b/src/Model/BlogController.php index 9f892d2..47e203a 100644 --- a/src/Model/BlogController.php +++ b/src/Model/BlogController.php @@ -8,6 +8,7 @@ use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\PaginatedList; use SilverStripe\Security\Member; +use SilverStripe\View\Parsers\URLSegmentFilter; class BlogController extends PageController { @@ -90,8 +91,10 @@ class BlogController extends PageController $urlSegment = $this->request->param('URLSegment'); if ($urlSegment) { + $filter = URLSegmentFilter::create(); + return Member::get() - ->filter('URLSegment', $urlSegment) + ->filter('URLSegment', $filter->filter($urlSegment)) ->first(); } @@ -242,8 +245,10 @@ class BlogController extends PageController $dataRecord = $this->dataRecord; $tag = $this->request->param('Tag'); if ($tag) { + $filter = URLSegmentFilter::create(); + return $dataRecord->Tags() - ->filter('URLSegment', [$tag, rawurlencode($tag)]) + ->filter('URLSegment', [$tag, $filter->filter($tag)]) ->first(); } return null; @@ -286,8 +291,10 @@ class BlogController extends PageController $dataRecord = $this->dataRecord; $category = $this->request->param('Category'); if ($category) { + $filter = URLSegmentFilter::create(); + return $dataRecord->Categories() - ->filter('URLSegment', [$category, rawurlencode($category)]) + ->filter('URLSegment', [$category, $filter->filter($category)]) ->first(); } return null; diff --git a/src/Model/BlogMemberExtension.php b/src/Model/BlogMemberExtension.php index ff0c5b9..0b9ce60 100644 --- a/src/Model/BlogMemberExtension.php +++ b/src/Model/BlogMemberExtension.php @@ -24,7 +24,7 @@ class BlogMemberExtension extends DataExtension * @var array */ private static $db = [ - 'URLSegment' => 'Varchar', + 'URLSegment' => 'Varchar(255)', 'BlogProfileSummary' => 'Text' ]; diff --git a/src/Model/BlogPost.php b/src/Model/BlogPost.php index 00b6f5b..c34da5c 100644 --- a/src/Model/BlogPost.php +++ b/src/Model/BlogPost.php @@ -736,6 +736,9 @@ class BlogPost extends Page */ public function getDate() { + if ($this->hasDatabaseField('Date')) { + return $this->getField('Date'); + } return !empty($this->PublishDate) ? $this->PublishDate : null; } diff --git a/src/Widgets/BlogArchiveWidget.php b/src/Widgets/BlogArchiveWidget.php index 672b6f4..934bede 100644 --- a/src/Widgets/BlogArchiveWidget.php +++ b/src/Widgets/BlogArchiveWidget.php @@ -10,6 +10,13 @@ use SilverStripe\Blog\Model\Blog; use SilverStripe\Control\Controller; use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\NumericField; +use SilverStripe\ORM\ArrayList; +use SilverStripe\ORM\DB; +use SilverStripe\ORM\FieldType\DBDate; +use SilverStripe\ORM\FieldType\DBDatetime; +use SilverStripe\ORM\Queries\SQLSelect; +use SilverStripe\Versioned\Versioned; +use SilverStripe\View\ArrayData; use SilverStripe\Widgets\Model\Widget; /** @@ -94,51 +101,46 @@ class BlogArchiveWidget extends Widget /** * Returns a list of months where blog posts are present. * - * @return DataList + * @return ArrayList */ public function getArchive() { - $query = $this->Blog()->getBlogPosts()->dataQuery(); + $format = ($this->ArchiveType == 'Yearly') ? '%Y' : '%Y-%m'; + $publishDate = DB::get_conn()->formattedDatetimeClause('"PublishDate"', $format); + $fields = [ + 'PublishDate' => $publishDate, + 'Total' => "Count('PublishDate')" + ]; - if ($this->ArchiveType == 'Yearly') { - $query->groupBy('DATE_FORMAT("PublishDate", \'%Y\')'); - } else { - $query->groupBy('DATE_FORMAT("PublishDate", \'%Y-%M\')'); - } + $stage = Versioned::get_stage(); + $suffix = ($stage == 'Stage') ? '' : "_{$stage}"; + $query = SQLSelect::create($fields, "BlogPost{$suffix}") + ->addGroupBy($publishDate) + ->addOrderBy('PublishDate Desc') + ->addWhere(['PublishDate < ?' => DBDatetime::now()->Format('Y-m-d')]); - $posts = $this->Blog()->getBlogPosts()->setDataQuery($query); + $posts = $query->execute(); + $result = ArrayList::create(); + while ($next = $posts->next()) { + $date = DBDate::create(); + $date->setValue(strtotime($next['PublishDate'])); + $year = $date->Format('Y'); - if ($this->NumberToDisplay > 0) { - $posts = $posts->limit($this->NumberToDisplay); - } - - $archive = ArrayList::create(); - - if ($posts->count() > 0) { - foreach ($posts as $post) { - /** - * @var BlogPost $post - */ - $date = Date::create(); - $date->setValue($post->PublishDate); - - if ($this->ArchiveType == 'Yearly') { - $year = $date->Format("Y"); - $month = null; - $title = $year; - } else { - $year = $date->Format("Y"); - $month = $date->Format("m"); - $title = $date->FormatI18N("%B %Y"); - } - - $archive->push(ArrayData::create([ - 'Title' => $title, - 'Link' => Controller::join_links($this->Blog()->Link('archive'), $year, $month) - ])); + if ($this->ArchiveType == 'Yearly') { + $month = null; + $title = $year; + } else { + $month = $date->Format('m'); + $title = $date->FormatI18N('%B %Y'); } + + $result->push(ArrayData::create([ + 'Title' => $title, + 'Link' => Controller::join_links($this->Blog()->Link('archive'), $year, $month) + ])); } - return $archive; + $this->extend('updateGetArchive', $result); + return $result; } } diff --git a/tests/BlogFunctionalTest.php b/tests/BlogFunctionalTest.php new file mode 100644 index 0000000..feb419c --- /dev/null +++ b/tests/BlogFunctionalTest.php @@ -0,0 +1,40 @@ +update('URLSegmentFilter', 'default_allow_multibyte', true); + + parent::setUp(); + + i18n::set_locale('fa_IR'); + } + + public function testBlogWithMultibyteUrl() + { + $result = $this->get('آبید'); + + $this->assertEquals(200, $result->getStatusCode()); + } + + public function testMemberProfileWithMultibyteUrlAndName() + { + $result = $this->get('آبید/profile/عبّاس-آبان'); + + $this->assertEquals(200, $result->getStatusCode()); + $this->assertContains('My Blog Post', $result->getBody()); + } + + public function testMemberProfileWithMultibyteUrlAndEnglishName() + { + $result = $this->get('آبید/profile/bob-jones'); + + $this->assertEquals(200, $result->getStatusCode()); + $this->assertContains('My Blog Post', $result->getBody()); + } +} diff --git a/tests/BlogFunctionalTest.yml b/tests/BlogFunctionalTest.yml new file mode 100644 index 0000000..f4c1110 --- /dev/null +++ b/tests/BlogFunctionalTest.yml @@ -0,0 +1,22 @@ +Member: + member_a: + FirstName: عبّاس + Surname: آبان + Email: foo@example.com + member_b: + FirstName: Bob + Surname: Jones + Email: bobjones@example.com + +Blog: + blog_a: + URLSegment: آبید + Title: My Blog + +BlogPost: + blogpost_a: + Title: My Blog Post + URLSegment: آبیدآبید + PublishDate: '2017-08-01 00:00:00' + Parent: =>Blog.blog_a + Authors: =>Member.member_a, =>Member.member_b