<?php
/**
* Copyright (c) 2020 Rhyme Digital LLC (https://rhyme.digital)
*
* @license LGPL-3.0-or-later
*/
namespace Rhyme\WMassArtsHub\Model\Profile;
use Contao\ContentElement;
use Contao\Controller;
use Contao\Environment;
use Contao\FrontendTemplate;
use Contao\Model;
use Contao\Database;
use Contao\PageModel;
use Contao\StringUtil;
use Contao\Model\Collection;
use Contao\Model\QueryBuilder;
use Contao\System;
use Exception;
use Haste\Util\Url;
use Rhyme\WMassArtsHub\Helper\GeneralHelper;
use Rhyme\WMassArtsHub\Helper\ProfileHelper;
use Rhyme\WMassArtsHub\Model\Profile\Discipline;
/**
* Class Item
* @package Rhyme\WMassArtsHub\Model\Profile
*
* @property string $main_image
*
* @method static Collection|Item[]|Item|null findMultipleByIds($val, array $opt=array())
*/
class Item extends Model
{
/**
* @var string
*/
protected static $strTable = 'tl_artshub_profile_item';
/**
* Unique form ID
* @var string
*/
protected $strFormId = 'artshub_profile_item';
/**
* @var array|null
*/
protected $arrCategories;
/**
* List of types (classes) for this model
* @var array
*/
protected static $arrModelTypes = array();
/**
* Generate a product template
*
* @param array $arrConfig
*
* @return string
*
* @throws \InvalidArgumentException
*/
public function generate(array $arrConfig)
{
$this->strFormId = (($arrConfig['module'] instanceof ContentElement) ? 'cte' : 'fmd') . $arrConfig['module']->id . '_profileItem_' . $this->id;
$objTemplate = new FrontendTemplate($arrConfig['template']);
$objTemplate->setData($this->arrData);
$objTemplate->item = $this;
$objTemplate->config = $arrConfig;
$objTemplate->raw = $this->arrData;
$objTemplate->href = $this->generateUrl($arrConfig['jumpTo']);
$objTemplate->enctype = $this->hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
$objTemplate->formId = $this->getFormId();
$objTemplate->action = \ampersand(Environment::get('request') ?: Environment::get('base'), true);
$objTemplate->formSubmit = $this->getFormId();
$objTemplate->item_id = $this->id;
$objTemplate->module_id = $arrConfig['module']->id;
ProfileHelper::addImageMethodsToTemplate($this, $arrConfig['module'], $objTemplate, $arrConfig);
// !HOOK: alter data before output
if (isset($GLOBALS['TL_HOOKS']['generateProfileItem']) && \is_array($GLOBALS['TL_HOOKS']['generateProfileItem'])) {
foreach ($GLOBALS['TL_HOOKS']['generateProfileItem'] as $callback) {
System::importStatic($callback[0])->{$callback[1]}($objTemplate, $this);
}
}
return \trim($objTemplate->parse());
}
/**
* Generate url
*
* @param PageModel $objJumpTo A PageModel instance
*
* @return string
*
* @throws \InvalidArgumentException
*/
public function generateUrl(PageModel $objJumpTo = null)
{
if (null === $objJumpTo) {
global $objPage;
$objJumpTo = $objPage;
}
if (null === $objJumpTo) {
return '';
}
$objJumpTo->loadDetails();
$strUrl = '/' . ($this->arrData['alias'] ?: $this->id);
if (!$GLOBALS['TL_CONFIG']['useAutoItem'] || !in_array('detail', $GLOBALS['TL_AUTO_ITEM'], true)) {
$strUrl = '/detail' . $strUrl;
}
return Url::addQueryString(
'',
Controller::generateFrontendUrl($objJumpTo->row(), $strUrl, $objJumpTo->language)
);
}
/**
* Return the Google Maps link
* @return string
*/
public function getGoogleMapsLink() {
return 'https://www.google.com/maps/search/'.$this->latitude.','.$this->longitude;
}
/**
* Return a formatted array
* @return array
*/
public function getArrayContent($strField) {
return StringUtil::deserialize($this->{$strField}, true);
}
/**
* Get the related Institution Type
* @return Collection|Item|null
* @throws Exception
*/
public function getInstitutionType()
{
try {
return $this->getRelated('primary_type');
} catch (Exception $e) { }
return null;
}
/**
* Get all the additional content as an array
* @return array
*/
public function getAdditionalContent()
{
$arrAdditionalContent = [];
//Year founded
if($this->year_founded > 0) {
$arrAdditionalContent[] = 'Year founded: ' . date('Y', $this->year_founded);
}
//NA Artist
if($this->native_american_artist) {
$arrAdditionalContent[] = 'Is a Native American Artist';
}
//Teaching Artist
if($this->is_teaching_artist) {
$arrAdditionalContent[] = 'Is a Teaching Artist';
}
//Touring Artist
if($this->is_touring_artist) {
$arrAdditionalContent[] = 'Is a Touring Artist';
}
//Events per year
if($this->events_per_year > 0) {
$arrAdditionalContent[] = 'Approx. ' . $this->events_per_year . ' events per year';
}
//Venues
if($this->has_venues) {
$arrAdditionalContent[] = 'Has venues available';
}
//Geographic Reach
$geographicReach = StringUtil::deserialize($this->geographic_reach, true);
if(!empty($geographicReach)) {
$arrReach = [];
foreach($geographicReach as $key) {
$arrReach[] = array_key_exists($key, $GLOBALS['TL_LANG']['MSC']) ? $GLOBALS['TL_LANG']['MSC'][$key] : $key;
}
$arrAdditionalContent[] = 'Geographic Reach: ' . implode(', ', $arrReach);
}
//Seasons active
$seasonsActive = StringUtil::deserialize($this->seasons_active, true);
if(!empty($seasonsActive)) {
$arrSeasons = [];
foreach($seasonsActive as $key) {
$arrSeasons[] = $GLOBALS['TL_LANG']['MSC'][$key];
}
if(\asort($seasonsActive) == ['fall', 'spring', 'summer', 'winter']) {
$arrAdditionalContent[] = 'Seasons active: Year round';
} else {
$arrAdditionalContent[] = 'Seasons active: ' . implode(', ', $arrSeasons);
}
}
return $arrAdditionalContent;
}
/**
* Get the related Primary Disciplines
* @return Discipline
* @throws Exception
*/
public function getPrimaryDiscipline()
{
try {
return $this->getRelated('primary_discipline') ?: null;
} catch (Exception $e) { }
return null;
}
/**
* Get the related Disciplines
* @param bool $blnRemovePrimary
* @return array
* @throws Exception
*/
public function getDisciplines($blnRemovePrimary = false)
{
try {
$objDiscCollection = $this->getRelated('disciplines');
if($blnRemovePrimary) {
$arrDisciplines = [];
while($objDiscCollection->next()) {
if($objDiscCollection->current()->id !== $this->primary_discipline) {
$arrDisciplines[] = $objDiscCollection->current();
}
}
return $arrDisciplines;
}
return $objDiscCollection !== null ? $objDiscCollection->getModels() : [];
} catch (Exception $e) { }
return [];
}
/**
* Get the related Activities
* @return array
* @throws Exception
*/
public function getActivities()
{
try {
$objActCollection = $this->getRelated('activities');
return $objActCollection !== null ? $objActCollection->getModels() : [];
} catch (Exception $e) { }
return [];
}
/**
* Return whether or not this profile has links
* @return bool
*/
public function hasLinks()
{
return strlen($this->website) || strlen($this->facebook) || strlen($this->twitter) || strlen($this->instagram);
}
/**
* Get the address
* @param bool $blnFormatLines
* @return string
*/
public function getAddress($blnFormatLines = false)
{
return ProfileHelper::formatAddress($this->street, $this->street2, $this->city, $this->state, $this->postal, $blnFormatLines);
}
/**
* Get the address
* @param bool $blnFormatLines
* @return string
*/
public function getContactInfo($blnFormatLines = false, $combineAddressInfo = false)
{
$strContact = ProfileHelper::formatContactInfo($this->contact_name, $this->contact_title, $this->phone, $this->email, $this->fax, $blnFormatLines);
$strContactAddress = ProfileHelper::formatAddress($this->mailing_street_1, $this->mailing_street_2, $this->mailing_city, $this->mailing_state, $this->mailing_zip, $blnFormatLines);
$strContactBlock = $strContact . $strContactAddress;
if($combineAddressInfo) {
$strContactBlock = str_replace('</ul>', '', $strContact) . str_replace('<ul>', '', $strContactAddress);
}
return $strContactBlock;
}
/**
* Get some vids
* @return array
*/
public function getVideos() {
$arrVids = StringUtil::deserialize($this->video_urls, true);
foreach($arrVids as $k => $vid) {
if (preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/\s]{11})%i', $vid['link'], $match)) {
$video_id = $match[1];
$arrVids[$k]['thumbnail'] = 'https://img.youtube.com/vi/'.$video_id.'/mqdefault.jpg';
$arrVids[$k]['embedHTML'] = '<iframe src="https://www.youtube.com/embed/'.$video_id.'?rel=0&modestbranding=1" width="640" height ="360" frameborder="0" allowfullscreen></iframe>';
}
if(preg_match('/(https?:\/\/)?(www\.)?(player\.)?vimeo\.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/', $vid['link'], $match)) {
$video_id = $match[1];
$jsonData = json_decode( GeneralHelper::curlGet('http://vimeo.com/api/oembed.json?url=' . $vid['link'] . '&width=640'));
if($jsonData === null) {
unset($arrVids[$k]);
} else {
$arrVids[$k]['thumbnail'] = $jsonData->thumbnail_url_with_play_button;
$arrVids[$k]['embedHTML'] = $jsonData->html;
}
}
}
return $arrVids;
}
/**
* Get the alias key
* @return string
*/
public function getPageTitle()
{
$strType = $this->getInstitutionType() !== null ? $this->getInstitutionType()->name : 'Arts Organization';
return $this->name . ' | ' . $strType . ' | ArtsHub of Western Massachusetts';
}
/**
* Get the alias key
* @return string
*/
public function getPageDescription()
{
$strDesc = strlen($this->description) > 0 ? StringUtil::substr(strip_tags($this->description), 100) : 'Information about ' . $this->name;
return $strDesc . ' Visit the ArtsHub of Western Massachusetts to learn more about '. $this->name .' and other arts organizations in western MA.';
}
/**
* Return the unique form ID for the item
*
* @return string
*/
public function getFormId()
{
return $this->strFormId;
}
/**
* Get the alias key
* @return string
*/
public static function getAliasKey()
{
return 'detail';
}
/**
* Find all published items
*
* @param array $arrOptions
*
* @return Collection|Item[]|null
*/
public static function findPublished(array $arrOptions = array())
{
return static::findPublishedBy(array(), array(), $arrOptions);
}
/**
* Find a single item by its ID or alias
*
* @param mixed $varId The ID or alias
* @param array $arrOptions An optional options array
*
* @return Item|Collection|null
*/
public static function findPublishedByIdOrAlias($varId, array $arrOptions = array())
{
$t = static::$strTable;
$arrColumns = array("($t.id=? OR $t.alias=?)");
$arrValues = array(is_numeric($varId) ? $varId : 0, $varId);
$arrOptions = array_merge(
array(
'limit' => 1,
'return' => 'Model'
),
$arrOptions
);
return static::findPublishedBy($arrColumns, $arrValues, $arrOptions);
}
/**
* Find published items by condition
*
* @param mixed $arrColumns
* @param mixed $arrValues
* @param array $arrOptions
*
* @return Collection|null
*/
public static function findPublishedBy($arrColumns, $arrValues, array $arrOptions = array())
{
$t = static::$strTable;
$arrValues = (array) $arrValues;
if (!is_array($arrColumns)) {
$arrColumns = array(static::$strTable . '.' . $arrColumns . '=?');
}
// Add publish check to $arrColumns as the first item to enable SQL keys
if (BE_USER_LOGGED_IN !== true) {
array_unshift(
$arrColumns,
"$t.published='1'"
);
}
return static::findBy($arrColumns, $arrValues, $arrOptions);
}
/**
* @inheritdoc
*/
public function getCategories($blnPublished = false)
{
$c = Discipline::getTable();
$key = ($blnPublished ? 'published' : 'all');
if (null === $this->arrCategories || !isset($this->arrCategories[$key])) {
if ($blnPublished) {
$options = Discipline::getFindByPidForPublishedPagesOptions($this->id);
$options['table'] = Discipline::getTable();
$query = QueryBuilder::find($options);
$values = (array) $options['value'];
} else {
$query = "SELECT page_id FROM $c WHERE pid=?";
$values = array($this->id);
}
$objCategories = Database::getInstance()->prepare($query)->execute($values);
$this->arrCategories[$key] = $objCategories->fetchEach('page_id');
// Sort categories by the backend drag&drop
$arrOrder = StringUtil::deserialize($this->orderPages);
if (!empty($arrOrder) && is_array($arrOrder)) {
$this->arrCategories[$key] = array_unique(
array_merge(
array_intersect(
$arrOrder,
$this->arrCategories[$key]
),
$this->arrCategories[$key]
)
);
}
}
return $this->arrCategories[$key];
}
/**
* Return collection of published items by categories
*
* @param array $arrCategories
* @param array $arrOptions
*
* @return Collection|Item[]|null
*/
public static function findPublishedByCategories(array $arrCategories, array $arrOptions = array())
{
return static::findPublishedBy(
array('c.page_id IN (' . implode(',', array_map('intval', $arrCategories)) . ')'),
null,
$arrOptions
);
}
/**
* Find a single published item by its ID or alias
*
* @param mixed $varId The ID or alias
* @param array $arrOptions An optional options array
*
* @return Item|null The model or null if the result is empty
*/
public static function findAvailableByIdOrAlias($varId, array $arrOptions = array())
{
$objItem = static::findPublishedByIdOrAlias($varId, $arrOptions);
if (null === $objItem) {
return null;
}
return $objItem;
}
}