Version 4.2.0

This commit is contained in:
Neo committed 2025-12-19 05:44:59 -08:00
1 parent 0dc2aee5ed
commit 96997ddd8e
2074 files changed
+125454 -55780

No files matched your search

+42 -22
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Block Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 19 Feb 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Blocks;
@@ -189,30 +188,39 @@ class _Block extends \IPS\Node\Model implements \IPS\Node\Permissions
if ( $block->type === 'custom' )
{
$functionName = 'content_blocks_' . $block->id;
if ( ! isset( \IPS\Data\Store::i()->$functionName ) )
try
{
$content = $block->content;
$functionName = 'content_blocks_' . $block->id;
if ( ! isset( \IPS\Data\Store::i()->$functionName ) )
{
$content = $block->content;
if( $block->getConfig('editor') == 'php' )
{
ob_start();
eval( $content );
$content = ob_get_clean();
}
\IPS\Data\Store::i()->$functionName = \IPS\Theme::compileTemplate( $content, $functionName, null, true );
}
\IPS\Theme::runProcessFunction( \IPS\Data\Store::i()->$functionName, $functionName );
if( $block->getConfig('editor') == 'php' )
{
ob_start();
eval( $content );
$content = ob_get_clean();
unset( \IPS\Data\Store::i()->$functionName );
}
\IPS\Data\Store::i()->$functionName = \IPS\Theme::compileTemplate( $content, $functionName, null, true );
return call_user_func( 'IPS\\Theme\\'. $functionName );
}
\IPS\Theme::runProcessFunction( \IPS\Data\Store::i()->$functionName, $functionName );
if( $block->getConfig('editor') == 'php' )
catch ( \ParseError $e )
{
unset( \IPS\Data\Store::i()->$functionName );
@ob_end_clean();
\IPS\Log::log( $e, 'block_error' );
return "<span style='background:black;color:white;padding:6px;'>[[Block {$block->key} is throwing an error]]</span>";
}
return call_user_func( 'IPS\\Theme\\'. $functionName );
}
else
{
@@ -632,6 +640,18 @@ EOF;
else
{
$form->add( new \IPS\Helpers\Form\Codemirror( 'block_content', htmlentities( $this->content, \IPS\HTMLENTITIES, 'UTF-8', TRUE ), FALSE, array(), function( $val ) {
if ( \IPS\Request::i()->block_editor == 'php' )
{
try
{
@eval( $val );
}
catch ( \ParseError $e )
{
throw new \DomainException( $e->getMessage() );
}
}
if ( mb_strpos( $val, '{block="' . \IPS\Request::i()->block_key . '"}' ) !== FALSE )
{
throw new \DomainException('block_content_recursive_error');
@@ -1,13 +1,12 @@
<?php
/**
* @brief Block Container Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 19 Feb 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Blocks;
@@ -1,13 +1,12 @@
<?php
/**
* @brief Categories Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 8 April 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms;
@@ -248,27 +247,24 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
return in_array( $id, static::$containerIds );
}
/**
* @brief Cache of categories we've fetched
*/
protected static $cache = array();
/**
* Fetch All Root Nodes
*
* @param string|NULL $permissionCheck The permission key to check for or NULl to not check permissions
* @param \IPS\Member|NULL $member The member to check permissions for or NULL for the currently logged in member
* @param mixed $where Additional WHERE clause
* @param mixed $databaseId Grab categories from a specific database
* @return array
*/
public static function roots( $permissionCheck='view', $member=NULL, $where=array(), $databaseId=null )
public static function roots( $permissionCheck='view', $member=NULL, $where=array() )
{
$permissionCheck = ( \IPS\Dispatcher::hasInstance() AND \IPS\Dispatcher::i()->controllerLocation === 'admin' ) ? NULL : $permissionCheck;
if ( $databaseId === NULL and static::$customDatabaseId !== NULL )
if ( static::$customDatabaseId !== NULL )
{
$databaseId = static::$customDatabaseId;
}
if ( $databaseId !== NULL )
{
$where[] = array('category_database_id=?', $databaseId );
$where[] = array('category_database_id=?', static::$customDatabaseId );
}
return parent::roots( $permissionCheck, $member, $where );
@@ -886,7 +882,14 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
}
}
}
$guestGroup = \IPS\Member\Group::load( \IPS\Settings::i()->guest_group );
if( !$this->can_view_others )
{
$disabled[ $guestGroup->g_id ] = array( 'view', 2, 3, 4, 5, 6, 7 );
}
return $disabled;
}
@@ -1768,7 +1771,7 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
*/
public function metaDescription()
{
return $this->meta_description ?: parent::metaDescription();
return $this->meta_description ?: static::database()->metaDescription();
}
/**
@@ -1778,6 +1781,26 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
*/
public function metaTitle()
{
return $this->page_title ?: parent::metaTitle();
return $this->page_title ?: static::database()->metaTitle();
}
/**
* Check permissions
*
* @param mixed $permission A key which has a value in static::$permissionMap['view'] matching a column ID in core_permission_index
* @param \IPS\Member|\IPS\Member\Group|NULL $member The member or group to check (NULL for currently logged in member)
* @return bool
* @throws \OutOfBoundsException If $permission does not exist in static::$permissionMap
*/
public function can( $permission, $member=NULL )
{
$_member = $member ?: \IPS\Member::loggedIn();
if ( !$_member->member_id and !$this->can_view_others )
{
return FALSE;
}
return parent::can( $permission, $member );
}
}
@@ -1,13 +1,12 @@
<?php
/**
* @brief Abstract class that Controllers should extend
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 16 April 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Databases;
@@ -1,13 +1,12 @@
<?php
/**
* @brief Databases Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 31 March 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms;
@@ -760,7 +759,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
/* Editor Areas */
\IPS\Member::loggedIn()->language()->words['editor__cms_Records' . $this->id ] = $this->_title;
foreach( array( 'pin', 'unpin', 'feature', 'unfeature', 'edit', 'hide', 'unhide', 'view_hidden', 'future_publish', 'view_future', 'move', 'lock', 'unlock', 'reply_to_locked', 'delete' ) as $lang )
foreach( array( 'pin', 'unpin', 'feature', 'unfeature', 'edit', 'hide', 'unhide', 'view_hidden', 'future_publish', 'view_future', 'move', 'lock', 'unlock', 'reply_to_locked', 'delete', 'feature_comments', 'unfeature_comments', 'add_item_message', 'edit_item_message', 'delete_item_message' ) as $lang )
{
\IPS\Member::loggedIn()->language()->words['can_' . $lang . '_content_db_lang_sl_' . $this->id ] = \IPS\Member::loggedIn()->language()->addToStack( 'can_' . $lang . '_record', FALSE, array( 'sprintf' => array( $this->recordWord( 1 ) ) ) );
\IPS\Member::loggedIn()->language()->words['can_' . $lang . '_content_db_lang_su_' . $this->id ] = \IPS\Member::loggedIn()->language()->addToStack( 'can_' . $lang . '_record', FALSE, array( 'sprintf' => array( $this->recordWord( 1, TRUE ) ) ) );
@@ -808,6 +807,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
{
/* If we are enabling search, we will need to index that content */
$rebuildSearchIndex = ( !$this->_new AND isset( $this->changed['search'] ) AND $this->changed['search'] );
$removeSearchIndex = ( !$this->_new AND isset( $this->changed['search'] ) AND !$this->changed['search'] );
parent::save();
@@ -818,7 +818,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
}
/* If this database isn't searchable, make sure its content is not in the search index */
if( !$this->search AND !$this->_new )
if( $removeSearchIndex )
{
\IPS\Content\Search\Index::i()->removeClassFromSearchIndex( 'IPS\cms\Records' . $this->id );
\IPS\Content\Search\Index::i()->removeClassFromSearchIndex( 'IPS\cms\Records\Comment' . $this->id );
@@ -851,7 +851,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
$fieldsClass = '\IPS\cms\Fields' . $this->id;
$class = '\IPS\cms\Categories' . $this->id;
foreach( $class::roots( NULL, NULL, array(), $this->id ) as $id => $cat )
foreach( $class::roots( NULL ) as $id => $cat )
{
$cat->delete();
}
@@ -918,7 +918,8 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
\IPS\Lang::deleteCustom( 'cms', "module__cms_records" . $this->id );
/* Unclaim attachments */
\IPS\File::unclaimAttachments( 'cms_Records_' . $this->id );
\IPS\File::unclaimAttachments( 'cms_Records', NULL, NULL, $this->id );
\IPS\File::unclaimAttachments( 'cms_Records' . $this->id );
/* Remove widgets */
$this->removeWidgets();
@@ -980,7 +981,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
/* Clone these permissions to all categories that do not have permissions */
$class = '\IPS\cms\Categories' . $this->id;
foreach( $class::roots( NULL, NULL, array(), $this->id ) as $category )
foreach( $class::roots( NULL ) as $category )
{
$this->setPermssionsRecursively( $category );
}
@@ -1043,7 +1044,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
foreach( static::databases() as $database )
{
$fieldsClass = 'IPS\cms\Fields' . $database->_id;
foreach( $fieldsClass::data() as $field )
{
if ( $field->type === 'Item' )
@@ -1051,26 +1052,29 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
$extra = $field->extra;
if ( ! empty( $extra['database'] ) )
{
$values[ $database->_id ] = $extra;
$values[ $database->_id ][] = $extra;
}
}
}
\IPS\Data\Store::i()->database_reciprocal_links = $values;
}
}
if ( is_array( $values ) )
{
foreach( $values as $id => $data )
foreach( $values as $id => $fields )
{
if ( $data['database'] == $databaseId and $data['crosslink'] )
foreach( $fields as $fieldid => $data )
{
return TRUE;
if ( $data['database'] == $databaseId and $data['crosslink'] )
{
return TRUE;
}
}
}
}
return FALSE;
}
@@ -1,13 +1,12 @@
<?php
/**
* @brief Database Dispatcher
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 16 April 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Databases;
@@ -166,7 +165,13 @@ class _Dispatcher extends \IPS\Dispatcher
}
$path = trim( preg_replace( '#' . \IPS\cms\Pages\Page::$currentPage->full_path . '#', '', \IPS\Request::i()->path, 1 ), '/' );
/* If we visited the default page in a folder, the full_path will be like folder/page but the request path will just be folder */
if( \IPS\Request::i()->path . '/' . \IPS\cms\Pages\Page::$currentPage->seo_name == \IPS\cms\Pages\Page::$currentPage->full_path )
{
$path = '';
}
$this->databaseId = $database->id;
if ( ! $database->use_categories )
@@ -207,7 +212,8 @@ class _Dispatcher extends \IPS\Dispatcher
try
{
$record = $recordClass::loadFromSlug( $slug );
\IPS\Output::i()->redirect( $record->url(), NULL, 301 );
$this->_redirectToCorrectUrl( $record->url() );
}
catch ( \OutOfRangeException $ex )
{
+79 -17
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Database Field Node
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 2 Apr 2014
* @version SVN_VERSION_NUMBER
*/
/**
@@ -512,7 +511,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
{
$value = $row->truncate( $value, TRUE );
if ( $value )
if ( $value !== '' AND $value !== NULL )
{
$value = $row->formatForDisplay( $value, $formValue, 'listing', $record );
}
@@ -546,7 +545,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
}
}
if ( $value )
if ( $value !== '' AND $value !== NULL )
{
$value = $row->formatForDisplay( $value, $formValue, 'display', $record );
}
@@ -627,6 +626,29 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
{
return $value;
}
else if ( $type === 'thumbs' and $this->type === 'Upload' )
{
if ( isset( $this->extra['thumbsize'] ) )
{
$thumbs = iterator_to_array( \IPS\Db::i()->select( '*', 'cms_database_fields_thumbnails', array( array( 'thumb_field_id=?', $this->id ) ) )->setKeyField('thumb_original_location')->setValueField('thumb_location') );
$images = array();
foreach( $thumbs as $orig => $thumb )
{
try
{
$images[] = \IPS\File::get( static::$uploadStorageExtension, $thumb )->url;
}
catch( \Exception $e ) { }
}
return $images;
}
else
{
return $this->formatForDisplay( $value, $formValue, 'raw', $record );
}
}
$options = $this->display_json;
@@ -757,7 +779,29 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
{
$value .= \IPS\GeoLocation::buildFromJson( $formValue )->map()->render( $options[ $type ]['mapDims'][0], $options[ $type ]['mapDims'][1] );
}
else if ( $this->type === 'Upload' )
{
if ( mb_stristr( $value, ',' ) )
{
$files = explode( ',', $value );
}
else
{
$files = array( $value );
}
if ( count( $files ) )
{
$parsed = array();
foreach( $files AS $file )
{
$file = \IPS\File::get( static::$uploadStorageExtension, (string) $file );
$parsed[] = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->fullyQualifiedUrl( $file->url ) );
}
$value = implode( '', $parsed );
}
}
$value = \IPS\Theme::i()->getTemplate( 'records', 'cms', 'global' )->fieldDefault( $this->_title, $value );
}
@@ -1193,10 +1237,11 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
/**
* Display Value
*
* @param mixed $value The value
* @param mixed $value The value
* @param bool $showSensitiveInformation If TRUE, potentially sensitive data (like passwords) will be displayed - otherwise will be blanked out
* @return string
*/
public function displayValue( $value=NULL )
public function displayValue( $value=NULL, $showSensitiveInformation=FALSE )
{
$database = \IPS\cms\Databases::load( static::$customDatabaseId );
@@ -1315,7 +1360,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
}
}
return \IPS\Lang::wordbreak( $time->localeDate() );
return \IPS\Lang::wordbreak( $this->extra['time'] ? (string) $time : $time->localeDate() );
}
if ( ! is_array( $value ) )
@@ -1388,7 +1433,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
/* Formatters */
try
{
return parent::displayValue( $value );
return parent::displayValue( $value, $showSensitiveInformation );
}
catch( \InvalidArgumentException $ex )
{
@@ -1622,7 +1667,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
'Checkbox' => array_merge( array( 'field_default_value', 'field_truncate' ), $displayDefaults ),
'CheckboxSet' => array_merge( array( 'field_extra', 'field_default_value', 'field_truncate' ), $displayDefaults ),
'Date' => array_merge( array( 'field_default_value', 'field_date_time_override', 'field_date_time_time' ), $displayDefaults ),
'Editor' => array_merge( array( 'field_max_length', 'field_default_value', 'field_truncate' ), $displayDefaults ),
'Editor' => array_merge( array( 'field_max_length', 'field_default_value', 'field_truncate', 'field_allow_attachments' ), $displayDefaults ),
'Email' => array_merge( array( 'field_max_length', 'field_default_value', 'field_unique' ), $displayDefaults ),
'Item' => array_merge( array( 'field_is_multiple', 'field_relational_db', 'field_crosslink' ), $displayDefaults ),
'Member' => array_merge( array( 'field_is_multiple', 'field_unique' ), $displayDefaults ),
@@ -1633,7 +1678,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
'Tel' => array_merge( array( 'field_default_value', 'field_unique' ), $displayDefaults ),
'Text' => array_merge( array( 'field_validator', 'field_format_opts_on', 'field_max_length', 'field_default_value', 'field_html', 'field_truncate', 'field_unique' ), $displayDefaults ),
'TextArea' => array_merge( array( 'field_validator', 'field_format_opts_on', 'field_max_length', 'field_default_value', 'field_html', 'field_truncate', 'field_unique' ), $displayDefaults ),
'Upload' => array_merge( array( 'field_upload_is_image', 'field_upload_is_multiple' ), $displayDefaults ),
'Upload' => array_merge( array( 'field_upload_is_image', 'field_upload_is_multiple', 'field_upload_thumb' ), $displayDefaults ),
'Url' => array_merge( array( 'field_default_value', 'field_unique' ), $displayDefaults ),
'YesNo' => array_merge( array( 'field_default_value' ), $displayDefaults ),
'Youtube' => array( 'media_params', 'media_display_listing_method', 'media_display_display_method', 'field_unique' ),
@@ -1732,24 +1777,35 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
),
'toggles' => array(
'yes' => array( 'field_image_size' ),
'yes' => array( 'field_image_size', 'field_upload_thumb' ),
'no' => array( 'field_allowed_extensions' )
)
), NULL, NULL, NULL, 'field_upload_is_image' ) );
$widthHeight = NULL;
$thumbWidthHeight = array( 0, 0 );
if ( isset( $this->extra['type'] ) and $this->extra['type'] === 'image' )
{
$widthHeight = $this->extra['maxsize'];
if ( isset( $this->extra['thumbsize'] ) )
{
$thumbWidthHeight = $this->extra['thumbsize'];
}
}
$form->add( new \IPS\Helpers\Form\WidthHeight( 'field_image_size', $this->id ? $widthHeight : array( 0, 0 ), FALSE, array( 'resizableDiv' => FALSE, 'unlimited' => array( 0, 0 ) ), NULL, NULL, NULL, 'field_image_size' ) );
$form->add( new \IPS\Helpers\Form\WidthHeight( 'field_upload_thumb', $this->id ? $thumbWidthHeight : array( 0, 0 ), FALSE, array( 'resizableDiv' => FALSE, 'unlimited' => array( 0, 0 ), 'unlimitedLang' => 'field_upload_thumb_none' ), NULL, NULL, NULL, 'field_upload_thumb' ) );
$form->add( new \IPS\Helpers\Form\Text( 'field_allowed_extensions', $this->id ? ( $this->allowed_extensions ?: NULL ) : NULL, FALSE, array(
'autocomplete' => array( 'unique' => 'true' ),
'nullLang' => 'content_any_extensions'
), NULL, NULL, NULL, 'field_allowed_extensions' ) );
/* Editor Specific */
$form->add( new \IPS\Helpers\Form\YesNo( 'field_allow_attachments', $this->id ? $this->allow_attachments : 1, FALSE, array( ), NULL, NULL, NULL, 'field_allow_attachments' ) );
/* Date specific */
$tzValue = 'UTC';
if ( isset( $this->extra['timezone'] ) and $this->extra['timezone'] )
@@ -2462,6 +2518,11 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
if ( isset( $values['field_upload_is_image'] ) and $values['field_upload_is_image'] === 'yes')
{
$values['extra'] = array( 'type' => 'image', 'maxsize' => $values['field_image_size'] );
if ( $values['field_upload_thumb'][0] > 0 )
{
$values['extra']['thumbsize'] = $values['field_upload_thumb'];
}
}
else
{
@@ -2539,7 +2600,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
$this->_oldDefaultValue = $this->default_value;
}
foreach( array( 'field_crosslink', 'field_number_decimals_on', 'field_number_decimals', 'field_format_opts_on', 'field_relational_db', 'field_upload_is_multiple', 'field_default_update_existing', 'field_date_time_override', 'field_date_timezone', 'field_date_time_time', 'field_upload_is_image', 'field_image_size', 'field_title', 'field_display_display_json_badge', 'field_display_display_json_custom', 'field_display_listing_json_badge', 'field_display_listing_json_custom', 'field_display_listing_json_badge_right', 'media_display_listing_method', 'media_display_display_method', 'field_show_map_listing', 'field_show_map_listing_dims', 'field_show_map_display', 'field_show_map_display_dims', 'field_display_display_json_where' ) as $field )
foreach( array( 'field_crosslink', 'field_number_decimals_on', 'field_number_decimals', 'field_format_opts_on', 'field_relational_db', 'field_upload_is_multiple', 'field_default_update_existing', 'field_date_time_override', 'field_date_timezone', 'field_date_time_time', 'field_upload_is_image', 'field_image_size', 'field_upload_thumb', 'field_title', 'field_display_display_json_badge', 'field_display_display_json_custom', 'field_display_listing_json_badge', 'field_display_listing_json_custom', 'field_display_listing_json_badge_right', 'media_display_listing_method', 'media_display_display_method', 'field_show_map_listing', 'field_show_map_listing_dims', 'field_show_map_display', 'field_show_map_display_dims', 'field_display_display_json_where' ) as $field )
{
if ( array_key_exists( $field, $values ) )
{
@@ -2720,6 +2781,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
case 'Editor':
$options['app'] = 'cms';
$options['key'] = 'Records';
$options['allowAttachments'] = $this->allow_attachments;
$options['autoSaveKey'] = 'RecordField_' . ( $record === NULL ? 'new' : $record->_id ) . '_' . $this->id;
$options['attachIds'] = ( $record === NULL ) ? NULL : array( $record->_id, $this->id, static::$customDatabaseId );
break;
@@ -1,13 +1,12 @@
<?php
/**
* @brief Soundcloud input class for Form Builder
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 11 Mar 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Fields;
+4 -5
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Spotify input class for Form Builder
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 11 Mar 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Fields;
+7 -6
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Youtube input class for Form Builder
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 11 Mar 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Fields;
@@ -89,7 +88,9 @@ class _Youtube extends \IPS\Helpers\Form\Text
$params['height'] = 390;
}
return \IPS\Theme::i()->getTemplate( 'records', 'cms', 'global' )->youtube( $url, $params );
$url = \IPS\Http\Url::external( $url )->setQueryString( $params );
return \IPS\Theme::i()->getTemplate( 'records', 'cms', 'global' )->youtube( $url, array( 'width' => $params['width'], 'height' => $params['height'] ) );
}
/**
+9 -5
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Folder Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 07 July 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Media;
@@ -93,6 +92,11 @@ class _Folder extends \IPS\Node\Model
* @brief [Node] Order Database Column
*/
public static $databaseColumnOrder = 'path';
/**
* @brief [Node] Automatically set position for new nodes
*/
public static $automaticPositionDetermination = FALSE;
/**
* @brief [Node] Node Title
+9 -5
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Media Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 15 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms;
@@ -68,6 +67,11 @@ class _Media extends \IPS\Node\Model
* @brief [Node] Parent ID Database Column
*/
public static $databaseColumnOrder = 'filename';
/**
* @brief [Node] Automatically set position for new nodes
*/
public static $automaticPositionDetermination = FALSE;
/**
* @brief [Node] Show forms modally?
+24 -12
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Folder Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 15 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Pages;
@@ -93,6 +92,11 @@ class _Folder extends \IPS\Node\Model
* @brief [Node] Order Database Column
*/
public static $databaseColumnOrder = 'path';
/**
* @brief [Node] Automatically set position for new nodes
*/
public static $automaticPositionDetermination = FALSE;
/**
* @brief [Node] Node Title
@@ -202,7 +206,7 @@ class _Folder extends \IPS\Node\Model
$return['delete'] = array(
'icon' => 'trash-o',
'title' => 'empty',
'link' => $url->setQueryString( array( 'do' => 'delete', 'id' => $this->_id, 'deleteNode' => 0 ) ),
'link' => $url->setQueryString( array( 'do' => 'delete', 'id' => $this->_id ) ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('empty') ),
'hotkey'=> 'd'
);
@@ -374,7 +378,10 @@ class _Folder extends \IPS\Node\Model
*/
public function getItemCount()
{
return (int) \IPS\Db::i()->select( 'COUNT(*)', 'cms_pages', array( 'page_folder_id=?', $this->id ) )->first();
$pages = (int) \IPS\Db::i()->select( 'COUNT(*)', 'cms_pages', array( 'page_folder_id=?', $this->id ) )->first();
$subFolders = (int) \IPS\Db::i()->select( 'COUNT(*)', 'cms_folders', array( 'folder_parent_id=?', $this->id ) )->first();
return $pages + $subFolders;
}
/**
@@ -404,22 +411,27 @@ class _Folder extends \IPS\Node\Model
* Handle submissions of form to delete or move content
*
* @param array $values Values from form
* @param bool $deleteWhenDone Delete the node when done?
* @return void
*/
public function deleteOrMoveFormSubmit( $values, $deleteWhenDone=TRUE )
public function deleteOrMoveFormSubmit( $values )
{
if ( $values['cms_move_pages'] )
{
$folderId = $values['cms_move_pages']->id;
$folderId = $values['cms_move_pages']->_id;
}
else
{
$folderId = 0;
}
\IPS\Db::i()->update( 'cms_pages', array( 'page_folder_id' => $folderId ), array( 'page_folder_id=?', $this->id ) );
\IPS\Db::i()->update( 'cms_folders', array( 'folder_parent_id' => $folderId ), array( 'folder_id=?', $this->id ) );
\IPS\Db::i()->update( 'cms_pages', array( 'page_folder_id' => $folderId ), array( 'page_folder_id=?', $this->_id ) );
\IPS\Db::i()->update( 'cms_folders', array( 'folder_parent_id' => $folderId ), array( 'folder_id=?', $this->_id ) );
\IPS\Db::i()->update( 'cms_folders', array( 'folder_parent_id' => $folderId ), array( 'folder_parent_id=?', $this->_id ) );
unset( \IPS\Data\Store::i()->pages_page_urls );
/* Update pages */
\IPS\cms\Pages\Page::resetPath( $folderId );
/* Delete it */
\IPS\Session::i()->log( 'acplog__node_deleted', array( $this->title => TRUE, $this->titleForLog() => FALSE ) );
+86 -34
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Page Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 15 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Pages;
@@ -73,6 +72,11 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
* @brief [Node] Parent ID Database Column
*/
public static $databaseColumnOrder = 'seo_name';
/**
* @brief [Node] Automatically set position for new nodes
*/
public static $automaticPositionDetermination = FALSE;
/**
* @brief [Node] Show forms modally?
@@ -143,9 +147,6 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
*/
public static $defaultPage = array();
/**
*
*/
/**
* @brief Pre save flag
*/
@@ -187,8 +188,8 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
*/
public static function loadFromUrl( \IPS\Http\Url $url )
{
$qs = array_merge( $url->queryString, $url->hiddenQueryString );
$qs = array_merge( $url->hiddenQueryString, $url->queryString );
if ( isset( $qs['id'] ) )
{
if ( method_exists( get_called_class(), 'loadAndCheckPerms' ) )
@@ -202,7 +203,15 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
}
else if ( isset( $qs['path'] ) )
{
$return = static::load( $qs['path'], 'page_full_path' );
try
{
$return = static::load( $qs['path'], 'page_full_path' );
}
catch( \OutOfRangeException $ex )
{
$return = static::loadFromPath( $qs['path'] );
}
if ( method_exists( $return, 'can' ) )
{
if ( !$return->can( 'view' ) )
@@ -270,7 +279,6 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
return $children;
}
/**
* Returns a page object (or NULL) based on the path
*
@@ -538,8 +546,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
try
{
$page = static::load( \IPS\Settings::i()->cms_error_page );
$page->content = str_replace( '{error_message}', $message, $page->content );
$page->content = str_replace( '{error_code}', $code, $page->content );
$content = $page->getHtmlContent();
$content = str_replace( '{error_message}', $message, $content );
$content = str_replace( '{error_code}', $code, $content );
/* Pages are compiled and cached, which we do not want for the error page as the {error_*} tags are saved with their text content */
$functionName = 'content_pages_' . $page->id;
@@ -548,7 +557,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
unset( \IPS\Data\Store::i()->$functionName );
}
$page->output( $title, $httpStatusCode, $httpHeaders );
$page->output( $title, $httpStatusCode, $httpHeaders, $content );
}
catch( \Exception $ex )
{
@@ -567,7 +576,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
{
$return = array();
$pageType = isset( \IPS\Request::i()->page_type ) ? \IPS\Request::i()->page_type : ( $item ? $item->type : 'html' );
$return['tab_details'] = array( 'content_page_form_tab__details' );
$return['tab_details'] = array( 'content_page_form_tab__details', NULL, NULL, 'ipsForm_horizontal' );
$return['page_name'] = new \IPS\Helpers\Form\Translatable( 'page_name', NULL, TRUE, array( 'app' => 'cms', 'key' => ( $item and $item->id ) ? "cms_page_" . $item->id : NULL, 'maxLength' => 64 ), function( $val )
{
@@ -689,7 +698,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
if ( count( $js ) OR count( $css ) )
{
$return['tab_js_css'] = array( 'content_page_form_tab__includes' );
$return['tab_js_css'] = array( 'content_page_form_tab__includes', NULL, NULL, 'ipsForm_horizontal' );
$return['msg_js_css'] = array( 'cms_page_includes_message', 'ipsMessage ipsMessage_info ipsCmsIncludesMessage' );
if ( count( $js ) )
@@ -788,7 +797,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
}, NULL, NULL, 'page_content' );
}
$return['tab_meta'] = array( 'content_page_form_tab__meta' );
$return['tab_meta'] = array( 'content_page_form_tab__meta', NULL, NULL, 'ipsForm_horizontal' );
$return['page_title'] = new \IPS\Helpers\Form\Text( 'page_title', $item ? $item->title : '', FALSE, array( 'maxLength' => 64 ), NULL, NULL, NULL, 'page_title' );
$return['page_meta_keywords'] = new \IPS\Helpers\Form\TextArea( 'page_meta_keywords', $item ? $item->meta_keywords : '', FALSE, array(), NULL, NULL, NULL, 'page_meta_keywords' );
$return['page_meta_description'] = new \IPS\Helpers\Form\TextArea( 'page_meta_description', $item ? $item->meta_description : '', FALSE, array(), NULL, NULL, NULL, 'page_meta_description' );
@@ -1022,7 +1031,35 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
public function getIncludes()
{
$return = array( 'css' => NULL, 'js' => NULL );
if ( \IPS\Theme::designersModeEnabled() )
{
foreach( array( 'js', 'css' ) as $thing )
{
$includeKey = $thing . '_includes';
if ( count( $this->$includeKey ) )
{
/* Build a file object for each thing */
foreach( $this->$includeKey as $key )
{
try
{
$template = \IPS\cms\Templates::load( $key );
$return[ $thing ][ $key ] = \IPS\Http\Url::createFromString( \IPS\Http\Url::baseUrl() . "/applications/cms/interface/developer/developer.php" )
->setQueryString( 'file', '/themes/cms/' . $template->location . '/' . $template->group . '/' . $template->title );
}
catch( \OutOfRangeException $e )
{
continue;
}
}
}
}
return $return;
}
/* Empty? Lets take a look and see if we need to compile anything */
if ( empty( $this->_data['js_css_objects'] ) )
{
@@ -1063,10 +1100,13 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
}
}
}
/* Save this to prevent it looking for includes on every page refresh */
$this->js_css_objects = json_encode( $return );
$this->save();
if ( ! \IPS\Theme::designersModeEnabled() )
{
/* Save this to prevent it looking for includes on every page refresh */
$this->js_css_objects = json_encode( $return );
$this->save();
}
}
else
{
@@ -1350,6 +1390,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
$pageType = $this->type;
}
/* We shut off the main class and add it per-tab to allow the content field to look good */
$form->class = '';
foreach( static::formElements( $this ) as $name => $field )
{
if ( $pageType !== 'html' and in_array( $name, array( 'page_ipb_wrapper', 'page_show_sidebar', 'page_wrapper_template' ) ) )
@@ -2083,12 +2126,13 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
* Displays a page
*
* @param string|NULL $title The Page title
* @param int $httpStatusCode HTTP Status Code
* @param array $httpHeaders Additional HTTP Headers
* @param int|NULL $httpStatusCode HTTP Status Code
* @param array|NULL $httpHeaders Additional HTTP Headers
* @param string|NULL $content Optional content to use. Useful if dynamic replacements need to be made at runtime
* @throws \ErrorException
* @return void
*/
public function output( $title=NULL, $httpStatusCode=NULL, $httpHeaders=NULL )
public function output( $title=NULL, $httpStatusCode=NULL, $httpHeaders=NULL, $content=NULL )
{
$includes = $this->getIncludes();
@@ -2121,11 +2165,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
/* Populate \IPS\Output::i()->sidebar['widgets'] sidebar/header/footer widgets */
$this->getWidgets();
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'pages', 'cms' )->globalWrap( $nav, $this->getHtmlContent(), $this );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'pages', 'cms' )->globalWrap( $nav, $content ?: $this->getHtmlContent(), $this );
}
\IPS\Output::i()->sidebar['enabled'] = true;
/* Set the meta tags, but do not reset them if they are already set - articles can define custom meta tags and this code
overwrites the ones set by articles if we don't verify they aren't set first */
if ( $this->meta_keywords AND ( !isset( \IPS\Output::i()->metaTags['keywords'] ) OR !\IPS\Output::i()->metaTags['keywords'] ) )
@@ -2138,8 +2180,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
\IPS\Output::i()->metaTags['description'] = $this->meta_description;
}
/* If this is a default page, we may be accessing this from the folder only */
if ( $this->default )
/* If this is a default page, we may be accessing this from the folder only. The isset() check is to ensure canonical
tags for more specific things (like databases) are not overridden. */
if ( $this->default AND !isset( \IPS\Output::i()->linkTags['canonical'] ) )
{
\IPS\Output::i()->linkTags['canonical'] = (string) $this->url();
}
@@ -2166,7 +2209,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
{
/* Set the title */
\IPS\Output::i()->title = ( $title ) ? $title : $this->getHtmlTitle();
\IPS\Output::i()->output = $this->getHtmlContent();
\IPS\Output::i()->output = $content ?: $this->getHtmlContent();
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( \IPS\Output::i()->title );
/* Send straight to the output engine */
@@ -2182,6 +2225,8 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
}
else
{
$this->setTheme();
if ( isset( $includes['css'] ) and is_array( $includes['css'] ) )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, array_values( $includes['css'] ) );
@@ -2200,12 +2245,17 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
/* Meta tags */
\IPS\Output::i()->buildMetaTags();
/* Ensure MFA pop up shows */
$mfa = \IPS\Dispatcher\Front::i()->checkMfa( TRUE );
$mfa = $mfa ?: '';
if ( $this->wrapper_template and $this->wrapper_template !== '_none_' and ! \IPS\Request::i()->isAjax() )
{
try
{
list( $group, $name, $key ) = explode( '__', $this->wrapper_template );
\IPS\Output::i()->sendOutput( \IPS\cms\Theme::i()->getTemplate($group, 'cms', 'page')->$name( $this->getHtmlContent(), $this->getHtmlTitle() ), 200, $this->getContentType(), \IPS\Output::i()->httpHeaders );
$content = $content ?: $this->getHtmlContent();
$content .= $mfa;
\IPS\Output::i()->sendOutput( \IPS\cms\Theme::i()->getTemplate($group, 'cms', 'page')->$name( $content, $this->getHtmlTitle() ), 200, $this->getContentType(), \IPS\Output::i()->httpHeaders );
}
catch( \OutOfRangeException $e )
{
@@ -2218,7 +2268,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( \IPS\Output::i()->title );
/* Send straight to the output engine */
\IPS\Output::i()->sendOutput( $this->getHtmlContent(), ( $httpStatusCode ? $httpStatusCode : 200 ), $this->getContentType(), ( $httpHeaders ? $httpHeaders : \IPS\Output::i()->httpHeaders ) );
$content = $content ?: $this->getHtmlContent();
$content .= $mfa;
\IPS\Output::i()->sendOutput( $content, ( $httpStatusCode ? $httpStatusCode : 200 ), $this->getContentType(), ( $httpHeaders ? $httpHeaders : \IPS\Output::i()->httpHeaders ) );
}
}
+91
View File
@@ -0,0 +1,91 @@
<?php
/**
* @brief Page Model
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 15 Jan 2014
*/
namespace IPS\cms\Pages;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Page Model
*/
class _Router extends \IPS\Patterns\ActiveRecord
{
/**
* Load Pages Thing based on a URL.
* The URL is sometimes complex to figure out, so this will help
*
* @param \IPS\Http\Url $url URL to load from
* @return \IPS\cms\Pages\Page
* @throws \InvalidArgumentException
* @throws \OutOfRangeException
*/
public static function loadFromUrl( \IPS\Http\Url $url )
{
if ( ! isset( $url->queryString['path'] ) )
{
throw new \OutOfRangeException();
}
$path = $url->queryString['path'];
/* First, we need a page */
$page = \IPS\cms\Pages\Page::loadFromPath( $path );
/* What do we have left? */
$whatsLeft = trim( preg_replace( '#' . $page->full_path . '#', '', $path, 1 ), '/' );
if ( $whatsLeft )
{
/* Check databases */
$databases = iterator_to_array( \IPS\Db::i()->select( '*', 'cms_databases', array( 'database_page_id > 0' ) ) );
foreach( $databases as $db )
{
$classToTry = 'IPS\cms\Records' . $db['database_id'];
try
{
$record = $classToTry::loadFromSlug( $whatsLeft, FALSE, FALSE );
return $record;
}
catch( \Exception $ex ) { }
}
/* Check categories */
foreach( $databases as $db )
{
$classToTry = 'IPS\cms\Categories' . $db['database_id'];
try
{
$category = $classToTry::loadFromPath( $whatsLeft );
if ( $category !== NULL )
{
return $category;
}
}
catch( \Exception $ex ) { }
}
}
else
{
/* It's a page */
return $page;
}
/* No idea, sorry */
throw new \InvalidArgumentException;
}
}
+56 -13
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Post Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 8 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Records;
@@ -22,8 +21,10 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
/**
* Post Model
*/
class _Comment extends \IPS\Content\Comment implements \IPS\Content\ReportCenter, \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Reputation, \IPS\Content\Shareable, \IPS\Content\Searchable, \IPS\Content\Embeddable
class _Comment extends \IPS\Content\Comment implements \IPS\Content\ReportCenter, \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Shareable, \IPS\Content\Searchable, \IPS\Content\Embeddable
{
use \IPS\Content\Reactable;
/**
* @brief [ActiveRecord] Multiton Store
*/
@@ -83,11 +84,6 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\ReportCenter
*/
public static $icon = 'comment';
/**
* @brief Reputation Type
*/
public static $reputationType = 'id';
/**
* @brief [Content\Comment] Comment Template
*/
@@ -119,6 +115,29 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\ReportCenter
return array( array( static::$databasePrefix . static::$databaseColumnMap['item'] . '=?', $id ), array( static::$databasePrefix . 'database_id=?', static::$customDatabaseId ) );
}
/**
* Get items with permisison check
*
* @param array $where Where clause
* @param string $order MySQL ORDER BY clause (NULL to order by date)
* @param int|array $limit Limit clause
* @param string $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index
* @param mixed $includeHiddenItems Include hidden comments? NULL to detect if currently logged in member has permission, -1 to return public content only, TRUE to return unapproved content and FALSE to only return unapproved content the viewing member submitted
* @param int $queryFlags Select bitwise flags
* @param \IPS\Member $member The member (NULL to use currently logged in member)
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
* @param bool $joinComments If true, will join comment data (set to TRUE if your $where clause depends on this data)
* @param bool $joinReviews If true, will join review data (set to TRUE if your $where clause depends on this data)
* @return \IPS\Patterns\ActiveRecordIterator|int
*/
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenItems=\IPS\Content\Hideable::FILTER_AUTOMATIC, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL )
{
$class = '\IPS\cms\Records' . static::$customDatabaseId;
$where = $class::getItemsWithPermissionWhere( $where, $permissionKey, $member, $joinContainer );
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins );
}
/**
* Get HTML for search result display
*
@@ -133,9 +152,10 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\ReportCenter
* @param bool $asItem Displaying results as items?
* @param bool $canIgnoreComments Can ignore comments in the result stream? Activity stream can, but search results cannot.
* @param array $template Optional custom template
* @param array $reactions Reaction Data
* @return string
*/
public static function searchResult( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments=FALSE, $template=NULL )
public static function searchResult( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments=FALSE, $template=NULL, $reactions=array() )
{
/* Ensure that the comment title is formatted correctly */
try
@@ -154,7 +174,7 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\ReportCenter
}
catch ( \Exception $ex ) { }
return parent::searchResult( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments, $template );
return parent::searchResult( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments, $template, $reactions );
}
/**
@@ -243,4 +263,27 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\ReportCenter
{
return array( 'comment_database_id=?', static::$customDatabaseId );
}
/**
* Reaction Type
*
* @return string
*/
public static function reactionType()
{
$databaseId = static::$customDatabaseId;
return "comment_id_{$databaseId}";
}
/**
* Get content for embed
*
* @param array $params Additional parameters to add to URL
* @return string
*/
public function embedContent( $params )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'embed.css', 'cms', 'front' ) );
return \IPS\Theme::i()->getTemplate( 'global', 'cms' )->embedRecordComment( $this, $this->item(), $this->url()->setQueryString( $params ) );
}
}
@@ -1,13 +1,12 @@
<?php
/**
* @brief Forum Post Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 8 April 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Records;
@@ -72,11 +71,6 @@ class _CommentTopicSync extends \IPS\cms\Records\Comment
*/
public static $icon = 'comment';
/**
* @brief Reputation Type
*/
public static $reputationType = 'pid';
/**
* @brief [Content\Comment] Comment Template
*/
@@ -172,4 +166,14 @@ class _CommentTopicSync extends \IPS\cms\Records\Comment
{
return array( array( static::$databasePrefix . static::$databaseColumnMap['item'] . '=?', $id ) );
}
/**
* Reaction Type
*
* @return string
*/
public static function reactionType()
{
return 'pid';
}
}
+266 -31
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Records Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 8 April 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms;
@@ -28,15 +27,17 @@ class _Records extends \IPS\Content\Item implements
\IPS\Content\Tags,
\IPS\Content\Followable,
\IPS\Content\Shareable,
\IPS\Content\Reputation,
\IPS\Content\ReportCenter,
\IPS\Content\ReadMarkers,
\IPS\Content\Views,
\IPS\Content\Ratings,
\IPS\Content\Searchable,
\IPS\Content\FuturePublishing,
\IPS\Content\Embeddable
\IPS\Content\Embeddable,
\IPS\Content\MetaData
{
use \IPS\Content\Reactable;
/**
* @brief Multiton Store
*/
@@ -131,11 +132,6 @@ class _Records extends \IPS\Content\Item implements
* @brief Icon
*/
public static $icon = 'file-text';
/**
* @brief Reputation Type
*/
public static $reputationType = NULL;
/**
* @brief Include In Sitemap (We do not want to include in Content sitemap, as we have a custom extension
@@ -758,7 +754,7 @@ class _Records extends \IPS\Content\Item implements
{
$this->record_approved = -1;
}
else
else if ( $this->record_approved !== 0 )
{
$this->record_approved = 1;
}
@@ -1034,6 +1030,71 @@ class _Records extends \IPS\Content\Item implements
\IPS\File::claimAttachments( 'RecordField_' . ( $isNew ? 'new' : $this->_id ) . '_' . $row->id, $this->primary_id_field, $id, static::$customDatabaseId );
}
if ( $row->can( ( $isNew ? 'add' : 'edit' ) ) and $row->type == 'Upload' )
{
if ( $row->extra['type'] == 'image' and isset( $row->extra['thumbsize'] ) )
{
$dims = $row->extra['thumbsize'];
$field = 'field_' . $row->id;
$extra = $row->extra;
$thumbs = iterator_to_array( \IPS\Db::i()->select( '*', 'cms_database_fields_thumbnails', array( array( 'thumb_field_id=?', $row->id ) ) )->setKeyField('thumb_original_location')->setValueField('thumb_location') );
if ( $this->$field )
{
foreach( explode( ',', $this->$field ) as $img )
{
try
{
$original = \IPS\File::get( 'cms_Records', $img );
try
{
$thumb = $original->thumbnail( 'cms_Records', $dims[0], $dims[1] );
if ( isset( $thumbs[ (string) $original ] ) )
{
\IPS\Db::i()->delete( 'cms_database_fields_thumbnails', array( array( 'thumb_original_location=? and thumb_field_id=?', (string) $original, $row->id ) ) );
try
{
\IPS\File::get( 'cms_Records', $thumbs[ (string) $original ] )->delete();
}
catch ( \Exception $e ) { }
}
\IPS\Db::i()->insert( 'cms_database_fields_thumbnails', array(
'thumb_original_location' => (string) $original,
'thumb_location' => (string) $thumb,
'thumb_field_id' => $row->id,
'thumb_database_id' => static::$customDatabaseId
) );
}
catch ( \Exception $e ) { }
}
catch ( \Exception $e ) { }
}
/* Remove any thumbnails if the original has been removed */
$orphans = iterator_to_array( \IPS\Db::i()->select( '*', 'cms_database_fields_thumbnails', array( array( 'thumb_field_id=?', $row->id ), array( \IPS\Db::i()->in( 'thumb_original_location', explode( ',', $this->$field ), TRUE ) ) ) ) );
if ( count( $orphans ) )
{
foreach( $orphans as $thumb )
{
try
{
\IPS\File::get( 'cms_Records', $thumb['thumb_location'] )->delete();
}
catch ( \Exception $e ) { }
}
\IPS\Db::i()->delete( 'cms_database_fields_thumbnails', array( array( 'thumb_field_id=?', $row->id ), array( \IPS\Db::i()->in( 'thumb_original_location', explode( ',', $this->$field ), TRUE ) ) ) );
}
}
}
}
if ( $row->can( ( $isNew ? 'add' : 'edit' ) ) and $row->type == 'Item' )
{
\IPS\Db::i()->delete( 'cms_database_fields_reciprocal_map', array( 'map_origin_database_id=? and map_field_id=? and map_origin_item_id=?', static::$customDatabaseId, $row->id, $this->_id ) );
@@ -1303,6 +1364,70 @@ class _Records extends \IPS\Content\Item implements
return $fields;
}
/**
* Returns the content images
*
* @param int|null $limit Number of attachments to fetch, or NULL for all
*
* @return array|NULL If array, then array( 'core_Attachment' => 'month_x/foo.gif', ... );
* @throws \BadMethodCallException
*/
public function contentImages( $limit = NULL )
{
$idColumn = static::$databaseColumnId;
$attachments = array();
$internal = \IPS\Db::i()->select( 'attachment_id', 'core_attachments_map', array( 'location_key=? and id1=? and id3=?', 'cms_Records', $this->$idColumn, static::$customDatabaseId ) );
/* Attachments */
foreach( \IPS\Db::i()->select( '*', 'core_attachments', array( array( 'attach_id IN(?)', $internal ), array( 'attach_is_image=1' ) ), 'attach_id ASC', $limit ) as $row )
{
$attachments[] = array( 'core_Attachment' => $row['attach_location'] );
}
/* Record image */
if ( $this->record_image )
{
$attachments[] = array( 'cms_Records' => $this->record_image );
}
/* Any upload fields */
$categoryClass = 'IPS\cms\Categories' . static::$customDatabaseId;
$container = $categoryClass::load( $this->category_id );
$fieldsClass = 'IPS\cms\Fields' . static::$customDatabaseId;
$fieldValues = $this->fieldValues();
$customFields = $fieldsClass::fields( $fieldValues, 'edit', $container, 0, $this );
foreach( $customFields as $key => $field )
{
$fieldName = mb_substr( $field->name, 8 );
if ( get_class( $field ) == 'IPS\Helpers\Form\Upload' )
{
if ( is_array( $fieldValues[ $fieldName ] ) )
{
foreach( $fieldValues[ $fieldName ] as $fileName )
{
$obj = \IPS\File::get( 'cms_Records', $filename );
if ( $obj->isImage() )
{
$attachments[] = array( 'cms_Records' => $fileName );
}
}
}
else
{
$obj = \IPS\File::get( 'cms_Records', $fieldValues[ $fieldName ] );
if ( $obj->isImage() )
{
$attachments[] = array( 'cms_Records' => $fieldValues[ $fieldName ] );
}
}
}
}
return count( $attachments ) ? $attachments : NULL;
}
/**
* Get the post key or create one if one doesn't exist
@@ -1741,10 +1866,11 @@ class _Records extends \IPS\Content\Item implements
/**
* Are comments supported by this class?
*
* @param \IPS\Member\NULL $member The member to check for or NULL fto not check permission
* @return int
* @param \IPS\Member|NULL $member The member to check for or NULL to not check permission
* @param \IPS\Node\Model|NULL $container The container to check in, or NULL for any container
* @return bool
*/
public static function supportsComments( \IPS\Member $member = NULL )
public static function supportsComments( \IPS\Member $member = NULL, \IPS\Node\Model $container = NULL )
{
return parent::supportsComments() and static::database()->options['comments'];
}
@@ -1752,10 +1878,11 @@ class _Records extends \IPS\Content\Item implements
/**
* Are reviews supported by this class?
*
* @param \IPS\Member\NULL $member The member to check for or NULL to not check permission
* @return int
* @param \IPS\Member|NULL $member The member to check for or NULL to not check permission
* @param \IPS\Node\Model|NULL $container The container to check in, or NULL for any container
* @return bool
*/
public static function supportsReviews( \IPS\Member $member = NULL )
public static function supportsReviews( \IPS\Member $member = NULL, \IPS\Node\Model $container = NULL )
{
return parent::supportsReviews() and static::database()->options['reviews'];
}
@@ -1816,12 +1943,13 @@ class _Records extends \IPS\Content\Item implements
* @param string $action The action
* @param \IPS\Member|NULL $member The member doing the action (NULL for currently logged in member)
* @param string|NULL $reason Reason (for hides)
* @param bool $immediately Delete Immediately
* @return void
* @throws \OutOfRangeException|\InvalidArgumentException|\RuntimeException
*/
public function modAction( $action, \IPS\Member $member = NULL, $reason = NULL )
public function modAction( $action, \IPS\Member $member = NULL, $reason = NULL, $immediately = FALSE )
{
parent::modAction( $action, $member, $reason );
parent::modAction( $action, $member, $reason, $immediately );
if ( $this->useForumComments() and ( $action === 'lock' or $action === 'unlock' ) )
{
@@ -1845,9 +1973,10 @@ class _Records extends \IPS\Content\Item implements
* @param \IPS\DateTime|NULL $cutoff If an \IPS\DateTime object is provided, only comments posted AFTER that date will be included
* @param mixed $extraWhereClause Additional where clause(s) (see \IPS\Db::build for details)
* @param bool|NULL $bypassCache Used in cases where comments may have already been loaded i.e. splitting comments on an item.
* @param bool $includeDeleted Include deleted content.
* @return array|NULL|\IPS\Content\Comment If $limit is 1, will return \IPS\Content\Comment or NULL for no results. For any other number, will return an array.
*/
public function comments( $limit=NULL, $offset=NULL, $order='date', $orderDirection='asc', $member=NULL, $includeHiddenComments=NULL, $cutoff=NULL, $extraWhereClause=NULL, $bypassCache=FALSE )
public function comments( $limit=NULL, $offset=NULL, $order='date', $orderDirection='asc', $member=NULL, $includeHiddenComments=NULL, $cutoff=NULL, $extraWhereClause=NULL, $bypassCache=FALSE, $includeDeleted=FALSE )
{
if ( $this->useForumComments() )
{
@@ -1866,7 +1995,7 @@ class _Records extends \IPS\Content\Item implements
$offset = ( ( $_pageValue - 1 ) * static::getCommentsPerPage() ) + 1;
}
return $recordClass::load( $this->record_topicid )->comments( $limit, $offset, $order, $orderDirection, $member, $includeHiddenComments, $cutoff );
return $recordClass::load( $this->record_topicid )->comments( $limit, $offset, $order, $orderDirection, $member, $includeHiddenComments, $cutoff, $extraWhereClause, $bypassCache, $includeDeleted );
}
else
{
@@ -1883,7 +2012,7 @@ class _Records extends \IPS\Content\Item implements
$where = array( array( 'comment_database_id=?', static::$customDatabaseId ) );
}
return parent::comments( $limit, $offset, $order, $orderDirection, $member, $includeHiddenComments, $cutoff, $where );
return parent::comments( $limit, $offset, $order, $orderDirection, $member, $includeHiddenComments, $cutoff, $where, $bypassCache, $includeDeleted );
}
/**
@@ -1921,13 +2050,14 @@ class _Records extends \IPS\Content\Item implements
* @param bool|NULL $includeHiddenReviews Include hidden comments or not? NULL to base of currently logged in member's permissions
* @param \IPS\DateTime|NULL $cutoff If an \IPS\DateTime object is provided, only comments posted AFTER that date will be included
* @param mixed $extraWhereClause Additional where clause(s) (see \IPS\Db::build for details)
* @param bool $includeDeleted Include deleted content
* @return array|NULL|\IPS\Content\Comment If $limit is 1, will return \IPS\Content\Comment or NULL for no results. For any other number, will return an array.
*/
public function reviews( $limit=NULL, $offset=NULL, $order=NULL, $orderDirection='desc', $member=NULL, $includeHiddenReviews=NULL, $cutoff=NULL, $extraWhereClause=NULL )
public function reviews( $limit=NULL, $offset=NULL, $order=NULL, $orderDirection='desc', $member=NULL, $includeHiddenReviews=NULL, $cutoff=NULL, $extraWhereClause=NULL, $includeDeleted=FALSE )
{
$where = array( array( 'review_database_id=?', static::$customDatabaseId ) );
return parent::reviews( $limit, $offset, $order, $orderDirection, $member, $includeHiddenReviews, $cutoff, $where );
return parent::reviews( $limit, $offset, $order, $orderDirection, $member, $includeHiddenReviews, $cutoff, $where, $includeDeleted );
}
/**
@@ -1940,11 +2070,11 @@ class _Records extends \IPS\Content\Item implements
$tabs = array();
if ( static::database()->options['reviews'] )
{
$tabs['reviews'] = \IPS\Member::loggedIn()->language()->pluralize( \IPS\Member::loggedIn()->language()->get( 'cms_review_count' ), array( $this->mapped('num_reviews') ) );
$tabs['reviews'] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_review_count', TRUE, array( 'pluralize' => array( $this->mapped('num_reviews') ) ) );
}
if ( static::database()->options['comments'] )
{
$tabs['comments'] = \IPS\Member::loggedIn()->language()->pluralize( \IPS\Member::loggedIn()->language()->get( 'cms_comment_count' ), array( $this->mapped( 'num_comments' ) ) );
$tabs['comments'] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_comment_count', TRUE, array( 'pluralize' => array( $this->mapped('num_comments') ) ) );
}
return $tabs;
@@ -2048,6 +2178,25 @@ class _Records extends \IPS\Content\Item implements
parent::processAfterEdit( $values );
}
/**
* Callback to execute when tags are edited
*
* @return void
*/
protected function processAfterTagUpdate()
{
parent::processAfterTagUpdate();
if ( \IPS\Application::appIsEnabled('forums') and $this->_forum_record and $this->_forum_forum and ! $this->hidden() and ! $this->record_future_date )
{
try
{
$this->syncTopic();
}
catch( \Exception $ex ) { }
}
}
/**
* Process the comment form
@@ -2128,7 +2277,7 @@ class _Records extends \IPS\Content\Item implements
$topic->unhide( $member );
}
}
else if ( $this->_forum_forum and $this->_forum_comments )
else if ( $this->_forum_forum )
{
$this->syncTopic();
}
@@ -2173,7 +2322,7 @@ class _Records extends \IPS\Content\Item implements
{
$topic->unhide( $member );
}
elseif ( $this->_forum_forum and $this->_forum_comments and ! $this->isFutureDate() )
elseif ( $this->_forum_forum and ! $this->isFutureDate() )
{
$this->syncTopic();
}
@@ -2405,6 +2554,22 @@ class _Records extends \IPS\Content\Item implements
return parent::commentPageCount();
}
/**
* Log for deletion later
*
* \IPS\Member|NULL $member The member or NULL for currently logged in
* @return void
*/
public function logDelete( $member = NULL )
{
parent::logDelete( $member );
if ( $topic = $this->topic() and $this->_forum_delete )
{
$topic->logDelete( $member );
}
}
/**
* Delete Record
@@ -2939,6 +3104,7 @@ class _Records extends \IPS\Content\Item implements
'featured' => (bool) $this->mapped('featured'),
'url' => (string) $this->url(),
'rating' => $this->averageRating(),
'image' => $this->record_image ? (string) \IPS\File::get( 'cms_Records', $this->record_image )->url : null
);
}
@@ -2965,6 +3131,23 @@ class _Records extends \IPS\Content\Item implements
* @return \IPS\Patterns\ActiveRecordIterator|int
*/
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenItems=\IPS\Content\Hideable::FILTER_AUTOMATIC, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL, $skipPermission=FALSE, $joinTags=TRUE, $joinAuthor=TRUE, $joinLastCommenter=TRUE, $showMovedLinks=FALSE )
{
$where = static::getItemsWithPermissionWhere( $where, $permissionKey, $member, $joinContainer, $skipPermission );
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins, $skipPermission, $joinTags, $joinAuthor, $joinLastCommenter, $showMovedLinks );
}
/**
* WHERE clause for getItemsWithPermission
*
* @param array $where Current WHERE clause
* @param string $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index
* @param \IPS\Member $member The member (NULL to use currently logged in member)
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
* @param mixed $skipPermission If you are getting records from a specific container, pass the container to reduce the number of permission checks necessary or pass TRUE to skip container-based permission. You must still specify this in the $where clause
* @return array
*/
public static function getItemsWithPermissionWhere( $where, $permissionKey, $member, &$joinContainer, $skipPermission=FALSE )
{
/* Don't show records from categories in which records only show to the poster */
if ( $skipPermission !== TRUE and in_array( $permissionKey, array( 'view', 'read' ) ) )
@@ -2987,7 +3170,59 @@ class _Records extends \IPS\Content\Item implements
}
}
}
/* Return */
return $where;
}
/**
* Reaction Type
*
* @return string
*/
public static function reactionType()
{
$databaseId = static::database()->_id;
return "record_id_{$databaseId}";
}
/**
* Supported Meta Data Types
*
* @return array
*/
public static function supportedMetaDataTypes()
{
return array( 'core_FeaturedComments', 'core_ContentMessages' );
}
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins, $skipPermission, $joinTags, $joinAuthor, $joinLastCommenter, $showMovedLinks );
/**
* Get content for embed
*
* @param array $params Additional parameters to add to URL
* @return string
*/
public function embedContent( $params )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'embed.css', 'cms', 'front' ) );
return \IPS\Theme::i()->getTemplate( 'global', 'cms' )->embedRecord( $this, $this->container(), $this->url()->setQueryString( $params ) );
}
/**
* Give a content item the opportunity to filter similar content
*
* @note Intentionally blank but can be overridden by child classes
* @return array|NULL
*/
public function similarContentFilter()
{
if( $this->record_topicid )
{
return array(
array( '!(tag_meta_app=? and tag_meta_area=? and tag_meta_id=?)', 'forums', 'forums', $this->record_topicid )
);
}
return NULL;
}
}
+31 -11
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Post Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 8 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Records;
@@ -22,8 +21,10 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
/**
* Post Model
*/
class _Review extends \IPS\Content\Review implements \IPS\Content\ReportCenter, \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Reputation, \IPS\Content\Shareable, \IPS\Content\Searchable, \IPS\Content\Embeddable
class _Review extends \IPS\Content\Review implements \IPS\Content\ReportCenter, \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Shareable, \IPS\Content\Searchable, \IPS\Content\Embeddable
{
use \IPS\Content\Reactable;
/**
* @brief [ActiveRecord] Multiton Store
*/
@@ -84,11 +85,6 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\ReportCenter,
*/
public static $icon = 'comment';
/**
* @brief Reputation Type
*/
public static $reputationType = 'review_id';
/**
* @brief [Content\Comment] Comment Template
*/
@@ -191,4 +187,28 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\ReportCenter,
{
return array( 'review_database_id=?', static::$customDatabaseId );
}
/**
* Reaction Type
*
* @return string
* @todo This was implemented improperly before - look into upgrade routine to fix
*/
public static function reactionType()
{
$databaseId = static::$customDatabaseId;
return "review_id_{$databaseId}";
}
/**
* Get content for embed
*
* @param array $params Additional parameters to add to URL
* @return string
*/
public function embedContent( $params )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'embed.css', 'cms', 'front' ) );
return \IPS\Theme::i()->getTemplate( 'global', 'cms' )->embedRecordReview( $this, $this->item(), $this->url()->setQueryString( $params ) );
}
}
@@ -1,13 +1,12 @@
<?php
/**
* @brief Revisions Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 29 April 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Records;
@@ -1,13 +1,12 @@
<?php
/**
* @brief Categories Selector Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 20 July 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Selector;
@@ -1,13 +1,12 @@
<?php
/**
* @brief Databases Selector Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 20 July 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Selector;
@@ -1,13 +1,12 @@
<?php
/**
* @brief Templates Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 25 Feb 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Templates;
@@ -1,13 +1,12 @@
<?php
/**
* @brief Templates Model
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 25 Feb 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms;
@@ -185,23 +184,23 @@ class _Templates extends \IPS\Patterns\ActiveRecord
{
$idField = 'template_key';
}
if ( ! is_numeric( $id ) and ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) )
{
$templates = \IPS\cms\Theme::i()->getRawTemplates( NULL, NULL, NULL, \IPS\cms\Theme::RETURN_AS_OBJECT );
if ( isset( $templates[ $id ] ) )
{
return $templates[ $id ];
}
}
try
{
return parent::load( $id, $idField, $extraWhereClause );
}
catch( \OutOfRangeException $ex )
{
if ( ! is_numeric( $id ) and ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) )
{
$templates = \IPS\cms\Theme::i()->getRawTemplates( NULL, NULL, NULL, \IPS\cms\Theme::RETURN_ONLY_TEMPLATE | \IPS\cms\Theme::RETURN_AS_OBJECT );
if ( isset( $templates[ $id ] ) )
{
return $templates[ $id ];
}
}
throw $ex;
}
}
@@ -1,13 +1,12 @@
<?php
/**
* @brief Designer's Mode Theme
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 28 Nov 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Theme\Advanced;
+4 -5
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Magic Template Class for IN_DEV mode
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 18 Feb 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\Theme;
+6 -7
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief IN_DEV Skin Set
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 16 Apr 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms;
@@ -281,7 +280,7 @@ class _Theme extends \IPS\Theme
$where = array();
$templates = array();
if ( ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) AND ! ( $returnType ^ static::RETURN_DATABASE_ONLY ) )
if ( ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) AND ! ( $returnType & static::RETURN_DATABASE_ONLY ) )
{
$fixedLocations = array( 'admin', 'front', 'global' );
$results = array();
@@ -350,7 +349,7 @@ class _Theme extends \IPS\Theme
if ( in_array( $key, $seenKeys ) )
{
$key .= filemtime( static::_getHtmlPath( 'cms', $location->getFilename(), $file->getFilename() ) . '/' . $template->getFilename() );
$key .= filemtime( static::_getHtmlPath( 'cms', $location->getFilename(), $file->getFilename() ) . '/' . $template->getFilename() ) . uniqid();
}
$seenKeys[] = $key;
+21 -6
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief CMS Widgets
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Content
* @since 13 Oct 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms;
@@ -74,7 +73,7 @@ class _Widget extends \IPS\Widget
if( $key )
{
$where[] = array( 'block_plugin=?', (string) $key );
$where[] = array( 'block_key=?', (string) $key );
}
if( $app )
@@ -107,6 +106,22 @@ class _Widget extends \IPS\Widget
}
}
foreach( \IPS\Db::i()->select( '*', 'core_widget_areas' ) as $item )
{
$widgets = json_decode( $item['widgets'], TRUE );
foreach( $widgets as $widget )
{
if ( $widget['app'] === 'cms' and $widget['key'] === 'Blocks' and isset( $widget['unique'] ) and isset( $widget['configuration'] ) and isset( $widget['configuration']['cms_widget_custom_block'] ) )
{
if ( in_array( $widget['configuration']['cms_widget_custom_block'], array_keys( $blocks ) ) )
{
$uniqueIds[] = $widget['unique'];
}
}
}
}
if ( count( $uniqueIds ) )
{
$widgetRow = \IPS\Db::i()->select( '*', 'core_widgets', array( '`key`=? and app=?', 'Blocks', 'cms' ) )->first();