Skip to content

Instantly share code, notes, and snippets.

@YuzuruSano
Created December 22, 2016 03:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YuzuruSano/4a5825917bc4a7180aeb4c00a3771c35 to your computer and use it in GitHub Desktop.
Save YuzuruSano/4a5825917bc4a7180aeb4c00a3771c35 to your computer and use it in GitHub Desktop.
page_listブロックをカスタマイズしてページ属性で登録された緯度・経度からGoogle Mapにピンを立てるサンプル
<?php
// /application/blocks/page_list/controller.php
namespace Application\Block\PageList;
use BlockType;
use CollectionAttributeKey;
use Concrete\Core\Block\BlockController;
use Concrete\Core\Page\Feed;
use Database;
use Page;
use Core;
use PageList;
use Concrete\Core\Attribute\Key\CollectionKey;
use Concrete\Core\Tree\Node\Type\Topic;
class Controller extends BlockController
{
protected $btTable = 'btPageList';
protected $btInterfaceWidth = "800";
protected $btInterfaceHeight = "350";
protected $btExportPageColumns = array('cParentID');
protected $btExportPageTypeColumns = array('ptID');
protected $btExportPageFeedColumns = array('pfID');
protected $btCacheBlockRecord = true;
protected $btCacheBlockOutput = null;
protected $btCacheBlockOutputOnPost = true;
protected $btCacheBlockOutputLifetime = 300;
protected $list;
/**
* Used for localization. If we want to localize the name/description we have to include this.
*/
public function getBlockTypeDescription()
{
return t("List pages based on type, area.");
}
public function getBlockTypeName()
{
return t("Page List");
}
public function getJavaScriptStrings()
{
return array(
'feed-name' => t('Please give your RSS Feed a name.'),
);
}
public function on_start()
{
$this->requireAsset('javascript', 'underscore');
$this->list = new PageList();
$this->list->disableAutomaticSorting();
//$pl->setNameSpace('b' . $this->bID);
$cArray = array();
switch ($this->orderBy) {
case 'display_asc':
$this->list->sortByDisplayOrder();
break;
case 'display_desc':
$this->list->sortByDisplayOrderDescending();
break;
case 'chrono_asc':
$this->list->sortByPublicDate();
break;
case 'random':
$this->list->sortBy('RAND()');
break;
case 'alpha_asc':
$this->list->sortByName();
break;
case 'alpha_desc':
$this->list->sortByNameDescending();
break;
default:
$this->list->sortByPublicDateDescending();
break;
}
$today = date('Y-m-d');
$end = $start = null;
switch ($this->filterDateOption) {
case 'now':
$start = "$today 00:00:00";
$end = "$today 23:59:59";
break;
case 'past':
$end = "$today 23:59:59";
if ($this->filterDateDays > 0) {
$past = date('Y-m-d', strtotime("-{$this->filterDateDays} days"));
$start = "$past 00:00:00";
}
break;
case 'future':
$start = "$today 00:00:00";
if ($this->filterDateDays > 0) {
$future = date('Y-m-d', strtotime("+{$this->filterDateDays} days"));
$end = "$future 23:59:59";
}
break;
case 'between':
$start = "{$this->filterDateStart} 00:00:00";
$end = "{$this->filterDateEnd} 23:59:59";
break;
case 'all':
default:
break;
}
if ($start) {
$this->list->filterByPublicDate($start, '>=');
}
if ($end) {
$this->list->filterByPublicDate($end, '<=');
}
$c = Page::getCurrentPage();
if (is_object($c)) {
$this->cID = $c->getCollectionID();
}
if ($this->displayFeaturedOnly == 1) {
$cak = CollectionAttributeKey::getByHandle('is_featured');
if (is_object($cak)) {
$this->list->filterByIsFeatured(1);
}
}
if ($this->displayAliases) {
$this->list->includeAliases();
}
if ($this->ignorePermissions) {
$this->list->ignorePermissions();
}
$this->list->filter('cvName', '', '!=');
if ($this->ptID) {
$this->list->filterByPageTypeID($this->ptID);
}
if ($this->filterByRelated) {
$ak = CollectionKey::getByHandle($this->relatedTopicAttributeKeyHandle);
if (is_object($ak)) {
$topics = $c->getAttribute($ak->getAttributeKeyHandle());
if (count($topics) > 0 && is_array($topics)) {
$topic = $topics[array_rand($topics)];
$this->list->filter('p.cID', $c->getCollectionID(), '<>');
$this->list->filterByTopic($topic);
}
}
}
if ($this->filterByCustomTopic) {
$this->list->filterByTopic(intval($this->customTopicTreeNodeID));
}
$db = Database::connection();
$columns = $db->MetaColumnNames(CollectionAttributeKey::getDefaultIndexedSearchTable());
if (in_array('ak_exclude_page_list', $columns)) {
$this->list->filter(false, '(ak_exclude_page_list = 0 or ak_exclude_page_list is null)');
}
if (intval($this->cParentID) != 0) {
$cParentID = ($this->cThis) ? $this->cID : $this->cParentID;
if ($this->includeAllDescendents) {
$this->list->filterByPath(Page::getByID($cParentID)->getCollectionPath());
} else {
$this->list->filterByParentID($cParentID);
}
}
return $this->list;
}
public function view()
{
$this->set('unique_identifier', Core::make('helper/validation/identifier')->getString(18));
$list = $this->list;
$nh = Core::make('helper/navigation');
$this->set('nh', $nh);
if ($this->pfID) {
$this->requireAsset('css', 'font-awesome');
$feed = Feed::getByID($this->pfID);
if (is_object($feed)) {
$this->set('rssUrl', $feed->getFeedURL());
$link = $feed->getHeadLinkElement();
$this->addHeaderItem($link);
}
}
//Pagination...
$showPagination = false;
if ($this->num > 0) {
$list->setItemsPerPage($this->num);
$pagination = $list->getPagination();
$pages = $pagination->getCurrentPageResults();
if ($pagination->getTotalPages() > 1 && $this->paginate) {
$showPagination = true;
$pagination = $pagination->renderDefaultView();
$this->set('pagination', $pagination);
}
} else {
$pages = $list->getResults();
}
if ($showPagination) {
$this->requireAsset('css', 'core/frontend/pagination');
}
$this->set('pages', $pages);
$this->set('list', $list);
$this->set('showPagination', $showPagination);
}
public function add()
{
$this->requireAsset('core/topics');
$c = Page::getCurrentPage();
$uh = Core::make('helper/concrete/urls');
$this->set('c', $c);
$this->set('uh', $uh);
$this->set('includeDescription', true);
$this->set('includeName', true);
$this->set('bt', BlockType::getByHandle('page_list'));
$this->set('featuredAttribute', CollectionAttributeKey::getByHandle('is_featured'));
$this->set('thumbnailAttribute', CollectionAttributeKey::getByHandle('thumbnail'));
$this->loadKeys();
}
public function edit()
{
$this->requireAsset('core/topics');
$b = $this->getBlockObject();
$bCID = $b->getBlockCollectionID();
$bID = $b->getBlockID();
$this->set('bID', $bID);
$c = Page::getCurrentPage();
if ((!$this->cThis) && ($this->cParentID != 0)) {
$isOtherPage = true;
$this->set('isOtherPage', true);
}
if ($this->pfID) {
$feed = Feed::getByID($this->pfID);
if (is_object($feed)) {
$this->set('rssFeed', $feed);
}
}
$uh = Core::make('helper/concrete/urls');
$this->set('uh', $uh);
$this->set('bt', BlockType::getByHandle('page_list'));
$this->set('featuredAttribute', CollectionAttributeKey::getByHandle('is_featured'));
$this->set('thumbnailAttribute', CollectionAttributeKey::getByHandle('thumbnail'));
$this->loadKeys();
}
protected function loadKeys()
{
$attributeKeys = array();
$keys = CollectionKey::getList();
foreach ($keys as $ak) {
if ($ak->getAttributeTypeHandle() == 'topics') {
$attributeKeys[] = $ak;
}
}
$this->set('attributeKeys', $attributeKeys);
}
public function action_filter_by_topic($treeNodeID = false, $topic = false)
{
if ($treeNodeID) {
$topicObj = Topic::getByID(intval($treeNodeID));
if (is_object($topicObj) && $topicObj instanceof Topic) {
$this->list->filterByTopic(intval($treeNodeID));
$seo = Core::make('helper/seo');
$seo->addTitleSegment($topicObj->getTreeNodeDisplayName());
}
}
$this->view();
}
public function action_filter_by_tag($tag = false)
{
$seo = Core::make('helper/seo');
$seo->addTitleSegment($tag);
$this->list->filterByTags(h($tag));
$this->view();
}
public function action_filter_by_date($year = false, $month = false, $timezone = 'user')
{
if (is_numeric($year)) {
$year = (($year < 0) ? '-' : '') . str_pad(abs($year), 4, '0', STR_PAD_LEFT);
if ($month) {
$month = str_pad($month, 2, '0', STR_PAD_LEFT);
$lastDayInMonth = date('t', strtotime("$year-$month-01"));
$start = "$year-$month-01 00:00:00";
$end = "$year-$month-$lastDayInMonth 23:59:59";
} else {
$start = "$year-01-01 00:00:00";
$end = "$year-12-31 23:59:59";
}
if ($timezone !== 'system') {
$dh = Core::make('helper/date');
/* @var $dh \Concrete\Core\Localization\Service\Date */
$start = $dh->toDB($start, $timezone);
$end = $dh->toDB($end, $timezone);
}
$this->list->filterByPublicDate($start, '>=');
$this->list->filterByPublicDate($end, '<=');
$seo = Core::make('helper/seo');
$srv = Core::make('helper/date');
$seo->addTitleSegment($srv->date('F Y', $start));
}
$this->view();
}
public function validate($args)
{
$e = Core::make('helper/validation/error');
$vs = Core::make('helper/validation/strings');
$pf = false;
if ($this->pfID) {
$pf = Feed::getByID($this->pfID);
}
if ($args['rss'] && !is_object($pf)) {
if (!$vs->handle($args['rssHandle'])) {
$e->add(t('Your RSS feed must have a valid URL, containing only letters, numbers or underscores'));
}
if (!$vs->notempty($args['rssTitle'])) {
$e->add(t('Your RSS feed must have a valid title.'));
}
if (!$vs->notempty($args['rssDescription'])) {
$e->add(t('Your RSS feed must have a valid description.'));
}
}
return $e;
}
public function getPassThruActionAndParameters($parameters)
{
if ($parameters[0] == 'topic') {
$method = 'action_filter_by_topic';
$parameters = array_slice($parameters, 1);
} elseif ($parameters[0] == 'tag') {
$method = 'action_filter_by_tag';
$parameters = array_slice($parameters, 1);
} elseif (Core::make('helper/validation/numbers')->integer($parameters[0])) {
// then we're going to treat this as a year.
$method = 'action_filter_by_date';
$parameters[0] = intval($parameters[0]);
if (isset($parameters[1])) {
$parameters[1] = intval($parameters[1]);
}
} else {
$parameters = $method = null;
}
return array($method, $parameters);
}
public function isValidControllerTask($method, $parameters = array())
{
if (!$this->enableExternalFiltering) {
return false;
}
return parent::isValidControllerTask($method, $parameters);
}
public function save($args)
{
// If we've gotten to the process() function for this class, we assume that we're in
// the clear, as far as permissions are concerned (since we check permissions at several
// points within the dispatcher)
$db = Database::connection();
$bID = $this->bID;
$c = $this->getCollectionObject();
if (is_object($c)) {
$this->cID = $c->getCollectionID();
}
$args = $args + array(
'enableExternalFiltering' => 0,
'includeAllDescendents' => 0,
'includeDate' => 0,
'truncateSummaries' => 0,
'displayFeaturedOnly' => 0,
'topicFilter' => '',
'displayThumbnail' => 0,
'displayAliases' => 0,
'truncateChars' => 0,
'paginate' => 0,
'rss' => 0,
'pfID' => 0,
'filterDateOption' => '',
'cParentID' => null,
);
$args['num'] = ($args['num'] > 0) ? $args['num'] : 0;
$args['cThis'] = ($args['cParentID'] == $this->cID) ? '1' : '0';
$args['cParentID'] = ($args['cParentID'] == 'OTHER') ? $args['cParentIDValue'] : $args['cParentID'];
if (!$args['cParentID']) {
$args['cParentID'] = 0;
}
$args['enableExternalFiltering'] = ($args['enableExternalFiltering']) ? '1' : '0';
$args['includeAllDescendents'] = ($args['includeAllDescendents']) ? '1' : '0';
$args['includeDate'] = ($args['includeDate']) ? '1' : '0';
$args['truncateSummaries'] = ($args['truncateSummaries']) ? '1' : '0';
$args['displayFeaturedOnly'] = ($args['displayFeaturedOnly']) ? '1' : '0';
$args['filterByRelated'] = ($args['topicFilter'] == 'related') ? '1' : '0';
$args['filterByCustomTopic'] = ($args['topicFilter'] == 'custom') ? '1' : '0';
$args['displayThumbnail'] = ($args['displayThumbnail']) ? '1' : '0';
$args['displayAliases'] = ($args['displayAliases']) ? '1' : '0';
$args['truncateChars'] = intval($args['truncateChars']);
$args['paginate'] = intval($args['paginate']);
$args['rss'] = intval($args['rss']);
$args['ptID'] = intval($args['ptID']);
if (!$args['filterByRelated']) {
$args['relatedTopicAttributeKeyHandle'] = '';
}
if (!$args['filterByCustomTopic']) {
$args['customTopicAttributeKeyHandle'] = '';
$args['customTopicTreeNodeID'] = 0;
}
if ($args['rss']) {
if (isset($this->pfID) && $this->pfID) {
$pf = Feed::getByID($this->pfID);
}
if (!is_object($pf)) {
$pf = new \Concrete\Core\Page\Feed();
$pf->setTitle($args['rssTitle']);
$pf->setDescription($args['rssDescription']);
$pf->setHandle($args['rssHandle']);
}
$pf->setParentID($args['cParentID']);
$pf->setPageTypeID($args['ptID']);
$pf->setIncludeAllDescendents($args['includeAllDescendents']);
$pf->setDisplayAliases($args['displayAliases']);
$pf->setDisplayFeaturedOnly($args['displayFeaturedOnly']);
$pf->setDisplayAliases($args['displayAliases']);
$pf->displayShortDescriptionContent();
$pf->save();
$args['pfID'] = $pf->getID();
} elseif (isset($this->pfID) && $this->pfID && !$args['rss']) {
// let's make sure this isn't in use elsewhere.
$cnt = $db->fetchColumn('select count(pfID) from btPageList where pfID = ?', array($this->pfID));
if ($cnt == 1) { // this is the last one, so we delete
$pf = Feed::getByID($this->pfID);
if (is_object($pf)) {
$pf->delete();
}
}
$args['pfID'] = 0;
}
if ($args['filterDateOption'] != 'between') {
$args['filterDateStart'] = null;
$args['filterDateEnd'] = null;
}
if ($args['filterDateOption'] == 'past') {
$args['filterDateDays'] = $args['filterDatePast'];
} elseif ($args['filterDateOption'] == 'future') {
$args['filterDateDays'] = $args['filterDateFuture'];
} else {
$args['filterDateDays'] = null;
}
$args['pfID'] = intval($args['pfID']);
parent::save($args);
}
public function isBlockEmpty()
{
$pages = $this->get('pages');
if (isset($this->pageListTitle) && $this->pageListTitle) {
return false;
}
if (count($pages) == 0) {
if ($this->noResultsMessage) {
return false;
} else {
return true;
}
} else {
if ($this->includeName || $this->includeDate || $this->displayThumbnail
|| $this->includeDescription || $this->useButtonForLink
) {
return false;
} else {
return true;
}
}
}
public function cacheBlockOutput()
{
if ($this->btCacheBlockOutput === null) {
if (!$this->enableExternalFiltering && !$this->paginate) {
$this->btCacheBlockOutput = true;
} else {
$this->btCacheBlockOutput = false;
}
}
return $this->btCacheBlockOutput;
}
public function registerViewAssets($outputContent = '')
{
$this->requireAsset('javascript', 'jquery');
$this->requireAsset('javascript', 'underscore');
$c = Page::getCurrentPage();
$this->addFooterItem(
'<script defer src="https://maps.googleapis.com/maps/api/js?key='
. 'API KEY'
.'"></script>'
);
}
}
<?php
// /application/blocks/page_list/templates/event_map/view.php
//ブロック登録時、カスタムテンプレートで Event Map を指定
defined('C5_EXECUTE') or die("Access Denied.");
$th = Loader::helper('text');
$c = Page::getCurrentPage();
$dh = Core::make('helper/date'); /* @var $dh \Concrete\Core\Localization\Service\Date */
$map_data = array();
?>
<div style="width:100%;height:450px;" id="map_canvas_<?php echo $unique_identifier?>"></div>
<?php if ( $c->isEditMode() && $controller->isBlockEmpty()) { ?>
<div class="ccm-edit-mode-disabled-item"><?php echo t('Empty Page List Block.')?></div>
<?php } else { ?>
<div class="ccm-block-page-list-wrapper">
<?php if (isset($pageListTitle) && $pageListTitle): ?>
<div class="ccm-block-page-list-header">
<h5><?php echo h($pageListTitle)?></h5>
</div>
<?php endif; ?>
<?php if (isset($rssUrl) && $rssUrl): ?>
<a href="<?php echo $rssUrl ?>" target="_blank" class="ccm-block-page-list-rss-feed"><i class="fa fa-rss"></i></a>
<?php endif; ?>
<div class="ccm-block-page-list-pages">
<?php
$includeEntryText = false;
if (
(isset($includeName) && $includeName)
||
(isset($includeDescription) && $includeDescription)
||
(isset($useButtonForLink) && $useButtonForLink)
) {
$includeEntryText = true;
}
foreach ($pages as $page):
// Prepare data for each page being listed...
$buttonClasses = 'ccm-block-page-list-read-more';
$entryClasses = 'ccm-block-page-list-page-entry';
$title = $th->entities($page->getCollectionName());
$url = ($page->getCollectionPointerExternalLink() != '') ? $page->getCollectionPointerExternalLink() : $nh->getLinkToCollection($page);
$target = ($page->getCollectionPointerExternalLink() != '' && $page->openCollectionPointerExternalLinkInNewWindow()) ? '_blank' : $page->getAttribute('nav_target');
$target = empty($target) ? '_self' : $target;
$description = $page->getCollectionDescription();
$description = $controller->truncateSummaries ? $th->wordSafeShortText($description, $controller->truncateChars) : $description;
$description = $th->entities($description);
$thumbnail = false;
if ($displayThumbnail) {
$thumbnail = $page->getAttribute('thumbnail');
}
if (is_object($thumbnail) && $includeEntryText) {
$entryClasses = 'ccm-block-page-list-page-entry-horizontal';
}
$date = $dh->formatDateTime($page->getCollectionDatePublic(), true);
//Other useful page data...
//$last_edited_by = $page->getVersionObject()->getVersionAuthorUserName();
//$original_author = Page::getByID($page->getCollectionID(), 1)->getVersionObject()->getVersionAuthorUserName();
/* CUSTOM ATTRIBUTE EXAMPLES:
* $example_value = $page->getAttribute('example_attribute_handle');
*
* HOW TO USE IMAGE ATTRIBUTES:
* 1) Uncomment the "$ih = Loader::helper('image');" line up top.
* 2) Put in some code here like the following 2 lines:
* $img = $page->getAttribute('example_image_attribute_handle');
* $thumb = $ih->getThumbnail($img, 64, 9999, false);
* (Replace "64" with max width, "9999" with max height. The "9999" effectively means "no maximum size" for that particular dimension.)
* (Change the last argument from false to true if you want thumbnails cropped.)
* 3) Output the image tag below like this:
* <img src="<?php echo $thumb->src ?>" width="<?php echo $thumb->width ?>" height="<?php echo $thumb->height ?>" alt="" />
*
* ~OR~ IF YOU DO NOT WANT IMAGES TO BE RESIZED:
* 1) Put in some code here like the following 2 lines:
* $img_src = $img->getRelativePath();
* $img_width = $img->getAttribute('width');
* $img_height = $img->getAttribute('height');
* 2) Output the image tag below like this:
* <img src="<?php echo $img_src ?>" width="<?php echo $img_width ?>" height="<?php echo $img_height ?>" alt="" />
*/
/* End data preparation. */
/* The HTML from here through "endforeach" is repeated for every item in the list... */ ?>
<div class="<?php echo $entryClasses?>">
<?php if (is_object($thumbnail)): ?>
<div class="ccm-block-page-list-page-entry-thumbnail">
<?php
$img = Core::make('html/image', array($thumbnail));
$tag = $img->getTag();
$tag->addClass('img-responsive');
print $tag;
?>
</div>
<?php endif; ?>
<?php if ($includeEntryText): ?>
<div class="ccm-block-page-list-page-entry-text">
<?php if (isset($includeName) && $includeName): ?>
<div class="ccm-block-page-list-title">
<?php if (isset($useButtonForLink) && $useButtonForLink) { ?>
<?php echo $title; ?>
<?php } else { ?>
<a href="<?php echo $url ?>" target="<?php echo $target ?>"><?php echo $title ?></a>
<?php } ?>
</div>
<?php endif; ?>
<?php if (isset($includeDate) && $includeDate): ?>
<div class="ccm-block-page-list-date"><?php echo $date?></div>
<?php endif; ?>
<?php if (isset($includeDescription) && $includeDescription): ?>
<div class="ccm-block-page-list-description">
<?php echo $description ?>
</div>
<?php endif; ?>
<?php if (isset($useButtonForLink) && $useButtonForLink): ?>
<div class="ccm-block-page-list-page-entry-read-more">
<a href="<?php echo $url?>" target="<?php echo $target?>" class="<?php echo $buttonClasses?>"><?php echo $buttonLinkText?></a>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php
$map_data[] = array(
'title' => $title,
'url' => $url,
'lat' => $page->getAttribute('lat'),
'lng' => $page->getAttribute('lng')
);
?>
<?php endforeach; ?>
</div>
<?php if (count($pages) == 0): ?>
<div class="ccm-block-page-list-no-pages"><?php echo h($noResultsMessage)?></div>
<?php endif;?>
</div><!-- end .ccm-block-page-list -->
<?php if ($showPagination): ?>
<?php echo $pagination;?>
<?php endif; ?>
<?php } ?>
<?php $js = Core::make('helper/json');?>
<script>
var event_data_<?php echo $unique_identifier?> = <?php echo $js->encode($map_data);?>;
function map_gen_<?php echo $unique_identifier?>(data){
/* ===============================================
mapの初期表示
=============================================== */
var currentInfoWindow;
var map = null;
var options = {
zoom:12,
center:new google.maps.LatLng(35.0116363,135.76802939999993),
mapTypeId:google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas_<?php echo $unique_identifier?>"),options);
if(data.length === 0){
return;
}
/* ===============================================
marker出力
=============================================== */
var markers = [];
_.each(data,function(item,index){
var title = item.title;
var marker = {};
var obj = {
position:new google.maps.LatLng(item.lat,item.lng),
map:map,
title:item.title
};
marker = new google.maps.Marker(obj);
//markerごと、googlemap上での処理用配列
markers.push(marker);
/* ===============================================
クリックイベント
=============================================== */
//吹き出し内のhtml
var inner = '<article class="mapinner" style="width:400px;">' + '<h4>'+item.title+'</h4><a href="'+item.url+'">詳細はこちらだ!</a></article>';
//マップのクリックイベントに吹き出しを開く機能をバインド
google.maps.event.addListener(marker, 'click', function(event) {
if (currentInfoWindow) {
currentInfoWindow.close();
}
var infoWnd = new google.maps.InfoWindow({content: inner, maxWidth: 600});
infoWnd.open(marker.getMap(), marker);
currentInfoWindow = infoWnd;
//中心に位置を修正する
map.setCenter(marker.getPosition());
});
});
}
(function($) {
$(function(){
map_gen_<?php echo $unique_identifier?>(event_data_<?php echo $unique_identifier?>);
});
})(jQuery);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment