Version 4.1.19.4
This commit is contained in:
1 parent
2bd5025018
commit
0dc2aee5ed
312 files changed
+53730
-32118
No files matched your search
+8
-3
@@ -4,12 +4,17 @@
|
||||
// the IDN extension is installed. This is a small Polyfill to declare
|
||||
// that method and use the php-punycode library so that IDNs can be
|
||||
// supported in all environments
|
||||
|
||||
require_once 'Punycode.php';
|
||||
|
||||
function idn_to_ascii( $string )
|
||||
{
|
||||
$punycode = new \TrueBV\Punycode;
|
||||
return $punycode->encode( $string );
|
||||
try
|
||||
{
|
||||
return $punycode->encode( $string );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1843,23 +1843,15 @@ EOF;
|
||||
*/
|
||||
public function installLanguages( $offset=null, $limit=null )
|
||||
{
|
||||
|
||||
$languages = array_keys( \IPS\Lang::languages() );
|
||||
$langs = \IPS\Lang::languages();
|
||||
$inserted = 0;
|
||||
|
||||
$current = array();
|
||||
$rusCurrent = array();
|
||||
foreach( $languages as $languageId )
|
||||
{
|
||||
foreach( iterator_to_array( \IPS\Db::i()->select( '*', 'core_sys_lang_words', array( 'word_app=? AND lang_id=?', $this->directory, $languageId ) ) ) as $word )
|
||||
foreach( iterator_to_array( \IPS\Db::i()->select( 'word_key, word_default, word_js', 'core_sys_lang_words', array( 'word_app=? AND lang_id=?', $this->directory, $languageId ) ) ) as $word )
|
||||
{
|
||||
if(\mb_strpos($langs[$languageId]->short,'ru_RU')!==false) {
|
||||
foreach ($word as $key => $value) {
|
||||
$rusCurrent[ $word['word_key'] . '-.-' . $word['word_js'] ][$key] = $value;
|
||||
}
|
||||
}
|
||||
else $current[ $languageId ][ $word['word_key'] . '-.-' . $word['word_js'] ] = $word['word_default'];
|
||||
$current[ $languageId ][ $word['word_key'] . '-.-' . $word['word_js'] ] = $word['word_default'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1893,131 +1885,107 @@ EOF;
|
||||
}
|
||||
}
|
||||
|
||||
$xmlFile = '';
|
||||
|
||||
foreach( $languages as $languageId ) {
|
||||
if( file_exists( \IPS\ROOT_PATH . "/applications/{$this->directory}/data/lang.xml" ) )
|
||||
{
|
||||
/* Open XML file */
|
||||
$xml = new \IPS\Xml\XMLReader;
|
||||
$xml->open( \IPS\ROOT_PATH . "/applications/{$this->directory}/data/lang.xml" );
|
||||
$xml->read();
|
||||
|
||||
$xmlFile = \IPS\ROOT_PATH . "/applications/{$this->directory}/data/lang".(\mb_strpos($langs[$languageId]->short,'ru_RU')!==false?'_rus':'').".xml" ;
|
||||
/* Get the version */
|
||||
$xml->read();
|
||||
$xml->read();
|
||||
$version = $xml->getAttribute('version');
|
||||
|
||||
if( !file_exists( $xmlFile ) ) continue;
|
||||
/* Get all installed languages */
|
||||
$inserts = array();
|
||||
$batchSize = 25;
|
||||
$batchesDone = 0;
|
||||
$i = 0;
|
||||
|
||||
/* Try to prevent timeouts to the extent possible */
|
||||
$cutOff = null;
|
||||
|
||||
$inserted = 0;
|
||||
/* Open XML file */
|
||||
$xml = new \IPS\Xml\XMLReader;
|
||||
$xml->open( $xmlFile );
|
||||
$xml->read();
|
||||
|
||||
/* Get the version */
|
||||
$xml->read();
|
||||
$xml->read();
|
||||
$version = $xml->getAttribute('version');
|
||||
|
||||
/* Get all installed languages */
|
||||
$inserts = array();
|
||||
$insertsRus = array();
|
||||
$batchSize = 25;
|
||||
$batchesDone = 0;
|
||||
$i = 0;
|
||||
|
||||
/* Try to prevent timeouts to the extent possible */
|
||||
$cutOff = null;
|
||||
|
||||
if( $maxExecution = @ini_get( 'max_execution_time' ) )
|
||||
if( $maxExecution = @ini_get( 'max_execution_time' ) )
|
||||
{
|
||||
/* If max_execution_time is set to "no limit" we should add a hard limit to prevent browser timeouts */
|
||||
if ( $maxExecution == -1 )
|
||||
{
|
||||
/* If max_execution_time is set to "no limit" we should add a hard limit to prevent browser timeouts */
|
||||
if ( $maxExecution == -1 )
|
||||
{
|
||||
$maxExecution = 30;
|
||||
}
|
||||
|
||||
$cutOff = time() + ( $maxExecution * .5 );
|
||||
$maxExecution = 30;
|
||||
}
|
||||
|
||||
/* Start looping through each word */
|
||||
while ( $xml->read() )
|
||||
$cutOff = time() + ( $maxExecution * .5 );
|
||||
}
|
||||
|
||||
/* Start looping through each word */
|
||||
while ( $xml->read() )
|
||||
{
|
||||
if( $xml->name != 'word' OR $xml->nodeType != \XMLReader::ELEMENT )
|
||||
{
|
||||
if( $xml->name != 'word' OR $xml->nodeType != \XMLReader::ELEMENT )
|
||||
continue;
|
||||
}
|
||||
|
||||
if( $cutOff !== null AND time() >= $cutOff )
|
||||
{
|
||||
return $inserted;
|
||||
}
|
||||
|
||||
$i++;
|
||||
|
||||
if ( $offset !== null )
|
||||
{
|
||||
if ( $i - 1 < $offset )
|
||||
{
|
||||
$xml->next();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( $cutOff !== null AND time() >= $cutOff )
|
||||
$inserted++;
|
||||
|
||||
$key = $xml->getAttribute('key');
|
||||
$value = $xml->readString();
|
||||
foreach( $languages as $languageId )
|
||||
{
|
||||
if ( !isset( $current[ $languageId ][ $key . '-.-' . (int) $xml->getAttribute('js') ] ) or $current[ $languageId ][ $key . '-.-' . (int) $xml->getAttribute('js') ] != $value )
|
||||
{
|
||||
return $inserted;
|
||||
$inserts[] = array(
|
||||
'word_app' => $this->directory,
|
||||
'word_key' => $key,
|
||||
'lang_id' => $languageId,
|
||||
'word_default' => $value,
|
||||
'word_default_version' => $version,
|
||||
'word_js' => (int) $xml->getAttribute('js'),
|
||||
'word_export' => 1,
|
||||
);
|
||||
}
|
||||
|
||||
$i++;
|
||||
|
||||
if ( $offset !== null )
|
||||
{
|
||||
if ( $i - 1 < $offset )
|
||||
{
|
||||
$xml->next();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$inserted++;
|
||||
|
||||
$key = $xml->getAttribute('key');
|
||||
$value = $xml->readString();
|
||||
|
||||
if(\mb_strpos($langs[$languageId]->short,'ru_RU')!==false and isset( $rusCurrent[ $key . '-.-' . (int) $xml->getAttribute('js') ] ) and
|
||||
$rusCurrent[ $key . '-.-' . (int) $xml->getAttribute('js') ]['word_custom']!=$xml->getAttribute('key_rus')) {
|
||||
$rusCurrent[ $key . '-.-' . (int) $xml->getAttribute('js') ]['word_custom'] = $xml->getAttribute('key_rus');
|
||||
$insertsRus[] = $rusCurrent[ $key . '-.-' . (int) $xml->getAttribute('js') ];
|
||||
}
|
||||
elseif ( !isset( $current[ $languageId ][ $key . '-.-' . (int) $xml->getAttribute('js') ] ) or $current[ $languageId ][ $key . '-.-' . (int) $xml->getAttribute('js') ] != $value )
|
||||
{
|
||||
$inserts[] = array(
|
||||
'word_app' => $this->directory,
|
||||
'word_key' => $key,
|
||||
'lang_id' => $languageId,
|
||||
'word_default' => $value,
|
||||
'word_default_version' => $version,
|
||||
'word_custom' => $xml->getAttribute('key_rus'),
|
||||
'word_js' => (int) $xml->getAttribute('js'),
|
||||
'word_export' => 1,
|
||||
|
||||
'word_id'=>'', 'word_plugin'=>'' , 'word_theme'=>'' , 'word_custom_version'=>'',
|
||||
);
|
||||
}
|
||||
|
||||
$done = ( $limit !== null AND $i === ( $limit + $offset ) );
|
||||
|
||||
if ( $done OR $i % $batchSize === 0 )
|
||||
{
|
||||
if ( count( $inserts ) )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_sys_lang_words', $inserts, TRUE );
|
||||
$inserts = array();
|
||||
}
|
||||
if ( count( $insertsRus ) )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_sys_lang_words', $insertsRus, TRUE );
|
||||
$insertsRus = array();
|
||||
}
|
||||
$batchesDone++;
|
||||
}
|
||||
|
||||
if ( $done )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$xml->next();
|
||||
}
|
||||
|
||||
if ( count( $inserts ) )
|
||||
$done = ( $limit !== null AND $i === ( $limit + $offset ) );
|
||||
|
||||
if ( $done OR $i % $batchSize === 0 )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_sys_lang_words', $inserts, TRUE );
|
||||
if ( count( $inserts ) )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_sys_lang_words', $inserts, TRUE );
|
||||
$inserts = array();
|
||||
}
|
||||
$batchesDone++;
|
||||
}
|
||||
if ( count( $insertsRus ) )
|
||||
|
||||
if ( $done )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_sys_lang_words', $insertsRus, TRUE );
|
||||
break;
|
||||
}
|
||||
|
||||
$xml->next();
|
||||
}
|
||||
|
||||
|
||||
if ( count( $inserts ) )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_sys_lang_words', $inserts, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
return $inserted;
|
||||
}
|
||||
|
||||
@@ -376,7 +376,9 @@ class _Module extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
if ( $new )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_permission_index', array(
|
||||
/* There is a unique constraint against app + perm_type + perm_type_id, so we use replace() instead of insert()
|
||||
in case there is already a row in the database for this constraint */
|
||||
\IPS\Db::i()->replace( 'core_permission_index', array(
|
||||
'app' => 'core',
|
||||
'perm_type' => 'module',
|
||||
'perm_type_id' => $this->id,
|
||||
|
||||
@@ -464,7 +464,13 @@ abstract class _Comment extends \IPS\Content
|
||||
public function canEdit( $member=NULL )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
|
||||
/* Are we restricted from posting or have an unacknowledged warning? */
|
||||
if ( $member->restrict_post or ( $member->members_bitoptions['unacknowledged_warnings'] and \IPS\Settings::i()->warn_on and \IPS\Settings::i()->warnings_acknowledge ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( $member->member_id )
|
||||
{
|
||||
$item = $this->item();
|
||||
|
||||
@@ -708,7 +708,7 @@ class _Controller extends \IPS\Helpers\CoverPhoto\Controller
|
||||
|
||||
$container = $item->container();
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'form', \IPS\Member::loggedIn()->language()->addToStack( 'move_send_to_container', FALSE, array( 'sprintf' => $container->_title ) ) );
|
||||
$form = new \IPS\Helpers\Form( 'form', \IPS\Member::loggedIn()->language()->addToStack( 'move_send_to_container', FALSE, array( 'sprintf' => $container->_title ) ), NULL, array( 'data-bypassValidation' => true ) );
|
||||
$form->actionButtons[] = \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->button( \IPS\Member::loggedIn()->language()->addToStack( 'move_send_to_item', FALSE, array( 'sprintf' => $item->definiteArticle() ) ), 'submit', null, 'ipsButton ipsButton_link', array( 'tabindex' => '3', 'accesskey' => 'i', 'value' => 'item', 'name' => 'returnto' ) );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'move_to', NULL, TRUE, array(
|
||||
|
||||
@@ -1065,7 +1065,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
/* Return */
|
||||
if ( $prepared )
|
||||
{
|
||||
if ( count( $words ) > 1 )
|
||||
if ( count( $words ) > 1 or mb_strstr( $term, '*' ) )
|
||||
{
|
||||
return array( "MATCH({$columns}) AGAINST (? IN BOOLEAN MODE)", $term );
|
||||
}
|
||||
@@ -1076,7 +1076,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( count( $words ) > 1 )
|
||||
if ( count( $words ) > 1 or mb_strstr( $term, '*' ) )
|
||||
{
|
||||
return "MATCH({$columns}) AGAINST ('" . \IPS\Db::i()->escape_string( $term ) . "' IN BOOLEAN MODE)";
|
||||
}
|
||||
@@ -1182,7 +1182,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
*/
|
||||
public function getDefaultDateCutOff()
|
||||
{
|
||||
if ( static::getTableSize() >= \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD )
|
||||
if ( \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD and static::getTableSize() >= \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD )
|
||||
{
|
||||
return 'year';
|
||||
}
|
||||
@@ -1197,7 +1197,7 @@ class _Query extends \IPS\Content\Search\Query
|
||||
*/
|
||||
public function getDefaultSortMethod()
|
||||
{
|
||||
if ( static::getTableSize() >= \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD )
|
||||
if ( \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD and static::getTableSize() >= \IPS\USE_MYSQL_SEARCH_BASIC_MODE_THRESHOLD )
|
||||
{
|
||||
return 'newest';
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace IPS\Content\ShareServices;
|
||||
|
||||
|
||||
class _Odnoklassniki
|
||||
{
|
||||
/**
|
||||
* @brief URL to the content item
|
||||
*/
|
||||
protected $url = NULL;
|
||||
|
||||
/**
|
||||
* @brief Title of the content item
|
||||
*/
|
||||
protected $title = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL to the content [optional - if omitted, some services will figure out on their own]
|
||||
* @param string $title Default text for the content, usually the title [optional - if omitted, some services will figure out on their own]
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Http\Url $url=NULL, $title=NULL )
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any additional form elements to the configuration form. These must be setting keys that the service configuration form can save as a setting.
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form Configuration form for this service
|
||||
* @return void
|
||||
*/
|
||||
public static function modifyForm( \IPS\Helpers\Form &$form )
|
||||
{
|
||||
}
|
||||
|
||||
static function canAutoshare() {}
|
||||
|
||||
/**
|
||||
* Return the HTML code to show the share link
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return '<a href="http://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1&st._surl='.$this->url.'" class="cShareLink cShareLink_ok" style="background-color:#F4811F;" target="_blank" data-controller="core.front.core.sharelink" data-role="shareLink" _title="Поделиться в Одноклассниках" data-ipstooltip="">
|
||||
<i class="fa fa-odnoklassniki"></i>
|
||||
</a>';
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace IPS\Content\ShareServices;
|
||||
|
||||
|
||||
class _Vkontakte
|
||||
{
|
||||
/**
|
||||
* @brief URL to the content item
|
||||
*/
|
||||
protected $url = NULL;
|
||||
|
||||
/**
|
||||
* @brief Title of the content item
|
||||
*/
|
||||
protected $title = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL to the content [optional - if omitted, some services will figure out on their own]
|
||||
* @param string $title Default text for the content, usually the title [optional - if omitted, some services will figure out on their own]
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Http\Url $url=NULL, $title=NULL )
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any additional form elements to the configuration form. These must be setting keys that the service configuration form can save as a setting.
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form Configuration form for this service
|
||||
* @return void
|
||||
*/
|
||||
public static function modifyForm( \IPS\Helpers\Form &$form )
|
||||
{
|
||||
}
|
||||
|
||||
static function canAutoshare() {}
|
||||
|
||||
/**
|
||||
* Return the HTML code to show the share link
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return '<a href="https://vk.com/share.php?url='.$this->url.'&title='.$this->title.'" class="cShareLink cShareLink_vk" style="background-color:#56789C;" target="_blank" data-controller="core.front.core.sharelink" data-role="shareLink" _title="Поделиться в Вконтакте" data-ipstooltip="">
|
||||
<i class="fa fa-vk"></i>
|
||||
</a>';
|
||||
}
|
||||
}
|
||||
@@ -394,9 +394,12 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
{
|
||||
foreach( \IPS\Application::applications() as $directory => $application )
|
||||
{
|
||||
if( method_exists( $application, 'convertLegacyParameters' ) )
|
||||
if ( $application->_enabled )
|
||||
{
|
||||
$application->convertLegacyParameters();
|
||||
if( method_exists( $application, 'convertLegacyParameters' ) )
|
||||
{
|
||||
$application->convertLegacyParameters();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -615,12 +618,4 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
}
|
||||
}
|
||||
}
|
||||
function run() {
|
||||
/* отслеживаем переходы */
|
||||
if ( $_SERVER['HTTP_REFERER'] )
|
||||
{
|
||||
\IPS\core\modules\admin\promotion\seovisitors::track( $_SERVER['HTTP_REFERER'], htmlentities( $_SERVER['QUERY_STRING'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ), \IPS\Member::loggedIn()->member_id );
|
||||
}
|
||||
parent::run();
|
||||
}
|
||||
}
|
||||
@@ -167,7 +167,7 @@ class _Node extends FormAbstract
|
||||
else
|
||||
{
|
||||
/* Recurse three levels in to allow for discoverability */
|
||||
foreach( $nodeClass::roots( $permCheck, NULL, $this->options['where'] ) AS $node )
|
||||
foreach( $nodeClass::roots( NULL, NULL, $this->options['where'] ) AS $node )
|
||||
{
|
||||
$this->_populate( $nodes, $disabled, 0, $node, $children, 3 );
|
||||
}
|
||||
|
||||
@@ -356,7 +356,6 @@ class _Upload extends FormAbstract
|
||||
{
|
||||
$existing[] = array(
|
||||
'id' => $id,
|
||||
'fileurl' => (string) $file,
|
||||
'insertable' => (bool) $this->options['postKey'],
|
||||
'hasThumb' => false,
|
||||
'originalFileName' => $file,
|
||||
@@ -370,7 +369,6 @@ class _Upload extends FormAbstract
|
||||
{
|
||||
$existing[] = array(
|
||||
'id' => $id,
|
||||
'fileurl' => (string) $file,
|
||||
'insertable' => (bool) $this->options['postKey'],
|
||||
'hasThumb' => ( isset( $attachment ) AND isset( $attachment['attach_is_image'] ) ) ? ( $attachment['attach_is_image'] AND $attachment['attach_thumb_location'] ) : $file->isImage(),
|
||||
'originalFileName' => $file->originalFilename,
|
||||
|
||||
+79
-72
@@ -28,7 +28,8 @@ class _Url extends Text
|
||||
* @code
|
||||
$childDefaultOptions = array(
|
||||
'allowedProtocols' => array( 'http', 'https' ), // Allowed protocols. Default is http and https. Be careful changing this not to introduce security issues.
|
||||
'allowedMimes' => 'image/*', // Sets the allowed mimetype(s). Can be string or array. * is a wildcard. Default is NULL, which allows any mimetypes. Note, setting this will not allow localhost URLs.
|
||||
'image' => TRUE, // If TRUE, will check the URL is for an image. Note, setting this will not allow localhost URLs.
|
||||
'allowedMimes' => \IPS\Image::$imageMimes, // Sets the allowed mimetype(s). Can be string or array. * is a wildcard. Default is NULL, which allows any mimetypes. Note, setting this will not allow localhost URLs. If the 'image' option is set, it will already be restricted to images
|
||||
'file' => 'Profile', // If provided, the contents of the URL will be fetched and written as a file, an \IPS\File object will then be returned rather than a string. Provide the extension name which specifies the storage location to use. Note, setting this will not allow localhost URLs.
|
||||
'maxFileSize' => NULL, // If provided along with 'file', the resulting file that is written to disk cannot be greater than this size in megabytes. NULL for no limit (default is NULL).
|
||||
'maxDimensions' => NULL, // If supplied as an array with keys 'width' and 'height' and the resulting file is an image, the image will be scaled down to these maximum dimensions. NULL for no limits (default is NULL).
|
||||
@@ -73,7 +74,7 @@ class _Url extends Text
|
||||
}
|
||||
|
||||
/* Try to fetch it, if necessary */
|
||||
if ( $this->options['file'] or $this->options['allowedMimes'] )
|
||||
if ( $this->options['file'] or $this->options['allowedMimes'] or $this->options['image'] )
|
||||
{
|
||||
/* Localhost is not allowed as sending a HTTP request to the local server will cause scripts which are relying
|
||||
on only being accessible to the local machine to execute */
|
||||
@@ -100,84 +101,90 @@ class _Url extends Text
|
||||
|
||||
$_SESSION[ $_key ] = time();
|
||||
}
|
||||
|
||||
|
||||
/* Make the request */
|
||||
try
|
||||
{
|
||||
$response = $value->request()->get();
|
||||
|
||||
/* Check MIME */
|
||||
if ( $this->options['allowedMimes'] )
|
||||
{
|
||||
$match = FALSE;
|
||||
$contentType = ( isset( $response->httpHeaders['Content-Type'] ) ) ? $response->httpHeaders['Content-Type'] : ( ( isset( $response->httpHeaders['content-type'] ) ) ? $response->httpHeaders['content-type'] : NULL );
|
||||
if( $contentType )
|
||||
{
|
||||
foreach ( is_array( $this->options['allowedMimes'] ) ? $this->options['allowedMimes'] : array( $this->options['allowedMimes'] ) as $mime )
|
||||
{
|
||||
if ( preg_match( '/^' . str_replace( '~~', '.+', preg_quote( str_replace( '*', '~~', $mime ), '/' ) ) . '$/i', $contentType ) )
|
||||
{
|
||||
$match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$match )
|
||||
{
|
||||
throw new \DomainException( 'form_url_bad_mime' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Write file if necessary */
|
||||
if ( $this->options['file'] )
|
||||
{
|
||||
$filename = preg_replace( "/(.+?)(\?|$)/", "$1", mb_substr( $value, mb_strrpos( $value, '/' ) + 1 ) );
|
||||
$response = (string) $response;
|
||||
|
||||
if( $this->options['maxFileSize'] !== NULL )
|
||||
{
|
||||
$maxFileSize = $this->options['maxFileSize'] * 1048576;
|
||||
|
||||
if( \strlen( $response ) > $maxFileSize )
|
||||
{
|
||||
unset( $response );
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'upload_too_big', TRUE, array( 'sprintf' => $this->options['maxFileSize'] ) ), 2 );
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->value = \IPS\File::create( $this->options['file'], $filename, $response );
|
||||
|
||||
/* Do we need to resize images down? */
|
||||
if( $this->value->isImage() AND $this->options['maxDimensions'] !== NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
$image = \IPS\Image::create( $this->value->contents() );
|
||||
|
||||
if( $image::exifSupported() )
|
||||
{
|
||||
$image->setExifData( $this->value->contents() );
|
||||
}
|
||||
|
||||
$image->resizeToMax( $this->options['maxDimensions']['width'] ?: NULL, $this->options['maxDimensions']['height'] ?: NULL );
|
||||
|
||||
$this->value->replace( (string) $image );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
catch( \InvalidArgumentException $e )
|
||||
{
|
||||
throw new \DomainException( 'form_url_error' );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
throw new \DomainException( 'form_url_error' );
|
||||
}
|
||||
|
||||
/* Check MIME */
|
||||
if ( $this->options['allowedMimes'] or $this->options['image'] )
|
||||
{
|
||||
$allowedMimes = $this->options['allowedMimes'] ? ( is_array( $this->options['allowedMimes'] ) ? $this->options['allowedMimes'] : array( $this->options['allowedMimes'] ) ): \IPS\Image::$imageMimes;
|
||||
|
||||
$match = FALSE;
|
||||
$contentType = ( isset( $response->httpHeaders['Content-Type'] ) ) ? $response->httpHeaders['Content-Type'] : ( ( isset( $response->httpHeaders['content-type'] ) ) ? $response->httpHeaders['content-type'] : NULL );
|
||||
if( $contentType )
|
||||
{
|
||||
foreach ( $allowedMimes as $mime )
|
||||
{
|
||||
if ( preg_match( '/^' . str_replace( '~~', '.+', preg_quote( str_replace( '*', '~~', $mime ), '/' ) ) . '$/i', $contentType ) )
|
||||
{
|
||||
$match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$match )
|
||||
{
|
||||
throw new \DomainException( 'form_url_bad_mime' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Max file size */
|
||||
if( $this->options['maxFileSize'] !== NULL )
|
||||
{
|
||||
$maxFileSize = $this->options['maxFileSize'] * 1048576;
|
||||
|
||||
if( \strlen( $response ) > $maxFileSize )
|
||||
{
|
||||
unset( $response );
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'upload_too_big', TRUE, array( 'sprintf' => $this->options['maxFileSize'] ) ), 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Image check and resize if necessary */
|
||||
if ( $this->options['image'] or $this->options['maxDimensions'] !== NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
$image = \IPS\Image::create( $response );
|
||||
|
||||
if ( $this->options['maxDimensions'] !== NULL )
|
||||
{
|
||||
$image->resizeToMax( $this->options['maxDimensions']['width'] ?: NULL, $this->options['maxDimensions']['height'] ?: NULL );
|
||||
$response = (string) $image;
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
if ( $this->options['image'] )
|
||||
{
|
||||
throw new \DomainException( 'form_url_bad_mime' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write file if necessary */
|
||||
if ( $this->options['file'] )
|
||||
{
|
||||
$filename = preg_replace( "/(.+?)(\?|$)/", "$1", mb_substr( $value, mb_strrpos( $value, '/' ) + 1 ) );
|
||||
|
||||
try
|
||||
{
|
||||
$this->value = \IPS\File::create( $this->options['file'], $filename, $response );
|
||||
}
|
||||
catch( \InvalidArgumentException $e )
|
||||
{
|
||||
throw new \DomainException( 'form_url_error' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ class _Curl
|
||||
}
|
||||
|
||||
$newRequest = \IPS\Http\Url::external( $location )->request( $this->timeout, $this->httpVersion, is_int( $this->followRedirects ) ? ( $this->followRedirects - 1 ) : $this->followRedirects );
|
||||
return call_user_func_array( array( $newRequest, $method ), $params );
|
||||
return $newRequest->$method( $params );
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ class _Sockets
|
||||
}
|
||||
|
||||
$newRequest = \IPS\Http\Url::external( $location )->request( $this->timeout, $this->httpVersion, is_int( $this->followRedirects ) ? ( $this->followRedirects - 1 ) : $this->followRedirects );
|
||||
return call_user_func_array( array( $newRequest, $method ), $params );
|
||||
return $newRequest->$method( $params );
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
+1
-4
@@ -927,10 +927,7 @@ class _Url
|
||||
{
|
||||
if ( static::$punycode === NULL )
|
||||
{
|
||||
require_once \IPS\ROOT_PATH . "/system/3rd_party/php-punycode/Exception/OutOfBoundsException.php";
|
||||
require_once \IPS\ROOT_PATH . "/system/3rd_party/php-punycode/Exception/DomainOutOfBoundsException.php";
|
||||
require_once \IPS\ROOT_PATH . "/system/3rd_party/php-punycode/Exception/LabelOutOfBoundsException.php";
|
||||
require_once \IPS\ROOT_PATH . "/system/3rd_party/php-punycode/Punycode.php";
|
||||
\IPS\IPS::$PSR0Namespaces['TrueBV'] = \IPS\ROOT_PATH . "/system/3rd_party/php-punycode";
|
||||
static::$punycode = new \TrueBV\Punycode();
|
||||
}
|
||||
|
||||
|
||||
@@ -391,7 +391,7 @@ class _Friendly extends \IPS\Http\Url\Internal
|
||||
|
||||
/* Disallowed characters which browsers may try to automatically percent-encode */
|
||||
$value = str_replace( array( '!', '*', '\'', '(', ')', ';', ':', '@', '&', '=', '+', '$', ',', '/', '?', '#', '[', ']', '%', '\\', '"', '<', '>', '^', '{', '}', '|', '.', '`' ), '', $value );
|
||||
if(defined("\IPS\IPB_USE_SEO_TRANSLIT")&&\IPS\IPB_USE_SEO_TRANSLIT) $value = self::rus2translit($value);
|
||||
|
||||
/* Trim */
|
||||
$value = preg_replace( '/\-+/', '-', $value );
|
||||
$value = trim( $value, '-' );
|
||||
@@ -400,62 +400,6 @@ class _Friendly extends \IPS\Http\Url\Internal
|
||||
/* Return */
|
||||
return $value ?: '-';
|
||||
}
|
||||
|
||||
static function rus2translit($string) {
|
||||
|
||||
$converter = array(
|
||||
|
||||
'а' => 'a', 'б' => 'b', 'в' => 'v',
|
||||
|
||||
'г' => 'g', 'д' => 'd', 'е' => 'e',
|
||||
|
||||
'ё' => 'e', 'ж' => 'zh', 'з' => 'z',
|
||||
|
||||
'и' => 'i', 'й' => 'y', 'к' => 'k',
|
||||
|
||||
'л' => 'l', 'м' => 'm', 'н' => 'n',
|
||||
|
||||
'о' => 'o', 'п' => 'p', 'р' => 'r',
|
||||
|
||||
'с' => 's', 'т' => 't', 'у' => 'u',
|
||||
|
||||
'ф' => 'f', 'х' => 'h', 'ц' => 'c',
|
||||
|
||||
'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sch',
|
||||
|
||||
'ь' => '', 'ы' => 'y', 'ъ' => '',
|
||||
|
||||
'э' => 'e', 'ю' => 'yu', 'я' => 'ya',
|
||||
|
||||
|
||||
|
||||
'А' => 'A', 'Б' => 'B', 'В' => 'V',
|
||||
|
||||
'Г' => 'G', 'Д' => 'D', 'Е' => 'E',
|
||||
|
||||
'Ё' => 'E', 'Ж' => 'Zh', 'З' => 'Z',
|
||||
|
||||
'И' => 'I', 'Й' => 'Y', 'К' => 'K',
|
||||
|
||||
'Л' => 'L', 'М' => 'M', 'Н' => 'N',
|
||||
|
||||
'О' => 'O', 'П' => 'P', 'Р' => 'R',
|
||||
|
||||
'С' => 'S', 'Т' => 'T', 'У' => 'U',
|
||||
|
||||
'Ф' => 'F', 'Х' => 'H', 'Ц' => 'C',
|
||||
|
||||
'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sch',
|
||||
|
||||
'Ь' => '', 'Ы' => 'Y', 'Ъ' => '',
|
||||
|
||||
'Э' => 'E', 'Ю' => 'Yu', 'Я' => 'Ya',
|
||||
|
||||
);
|
||||
|
||||
return strtr($string, $converter);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the matched parameters and SEO titles from a friendly URL component for a particular
|
||||
|
||||
@@ -28,6 +28,11 @@ abstract class _Image
|
||||
*/
|
||||
public static $imageExtensions = array( 'gif', 'jpeg', 'jpe', 'jpg', 'png' );
|
||||
|
||||
/**
|
||||
* @brief Image Mime Types
|
||||
*/
|
||||
public static $imageMimes = array( 'image/gif', 'image/jpeg', 'image/pjpeg', 'image/png' );
|
||||
|
||||
/**
|
||||
* Determine if EXIF extraction is supported
|
||||
*
|
||||
|
||||
@@ -86,16 +86,15 @@ class _Facebook extends LoginAbstract
|
||||
{
|
||||
throw new \IPS\Login\Exception( 'CSRF_FAIL', \IPS\Login\Exception::INTERNAL_ERROR );
|
||||
}
|
||||
|
||||
/* Get a token */
|
||||
try
|
||||
{
|
||||
$response = \IPS\Http\Url::external( "https://graph.facebook.com/oauth/access_token" )->request()->post( array(
|
||||
$response = \IPS\Http\Url::external( "https://graph.facebook.com/v2.8/oauth/access_token" )->request()->post( array(
|
||||
'client_id' => $this->settings['app_id'],
|
||||
'redirect_uri' => (string) \IPS\Http\Url::internal( 'applications/core/interface/facebook/auth.php', 'none', NULL, array(), \IPS\Settings::i()->logins_over_https ? \IPS\Http\Url::PROTOCOL_HTTPS : 0 ),
|
||||
'client_secret' => $this->settings['app_secret'],
|
||||
'code' => \IPS\Request::i()->code
|
||||
) )->decodeQueryString('access_token');
|
||||
) )->decodeJson();
|
||||
}
|
||||
catch( \RuntimeException $e )
|
||||
{
|
||||
@@ -105,12 +104,12 @@ class _Facebook extends LoginAbstract
|
||||
/* Now exchange it for a one that will last a bit longer in case the user wants to use syncing */
|
||||
try
|
||||
{
|
||||
$response = \IPS\Http\Url::external( "https://graph.facebook.com/oauth/access_token" )->request()->post( array(
|
||||
$response = \IPS\Http\Url::external( "https://graph.facebook.com/v2.8/oauth/access_token" )->request()->post( array(
|
||||
'grant_type' => 'fb_exchange_token',
|
||||
'client_id' => $this->settings['app_id'],
|
||||
'client_secret' => $this->settings['app_secret'],
|
||||
'fb_exchange_token' => $response['access_token']
|
||||
) )->decodeQueryString('access_token');
|
||||
) )->decodeJson();
|
||||
}
|
||||
catch( \RuntimeException $e )
|
||||
{
|
||||
|
||||
@@ -1,253 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace IPS\Login;
|
||||
|
||||
class _Vkontakte extends LoginAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'vk';
|
||||
|
||||
/**
|
||||
* Get Form
|
||||
*
|
||||
* @param \IPS\Http\Url $url The URL for the login page
|
||||
* @return string
|
||||
*/
|
||||
public function loginForm( $url, $ucp=FALSE )
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( 'applications/core/interface/vkontakte/auth.php', 'none' );
|
||||
|
||||
if ( $ucp )
|
||||
{
|
||||
$state = "ucp-" . \IPS\Session::i()->csrfKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
$state = \IPS\Dispatcher::i()->controllerLocation . "-" . \IPS\Session::i()->csrfKey;
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'login', 'core', 'global' )->vkontakte( "https://oauth.vk.com/authorize?client_id={$this->settings['app_id']}&scope=email&redirect_uri=".urlencode( $url ) . "&state={$state}&response_type=code" );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate
|
||||
*
|
||||
* @param string $url The URL for the login page
|
||||
* @param \IPS\Member $member If we want to integrate this login method with an existing member, provide the member object
|
||||
* @return \IPS\Member
|
||||
* @throws \IPS\Login\Exception
|
||||
*/
|
||||
public function authenticate( $url, $member=NULL )
|
||||
{
|
||||
$url = $url->setQueryString( 'loginProcess', 'vkontakte' );
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
/* Get a token */
|
||||
try
|
||||
{
|
||||
$response = \IPS\Http\Url::external( "https://oauth.vk.com/access_token?client_id={$this->settings['app_id']}&redirect_uri=".(string) \IPS\Http\Url::internal( 'applications/core/interface/vkontakte/auth.php', 'none' )."&client_secret={$this->settings['app_secret']}&code=".\IPS\Request::i()->code
|
||||
)->request()->get()->decodeJson();
|
||||
}
|
||||
catch( \RuntimeException $e )
|
||||
{
|
||||
throw new \IPS\Login\Exception( 'generic_error', \IPS\Login\Exception::INTERNAL_ERROR );
|
||||
}
|
||||
|
||||
/* Get the user data */
|
||||
$userData = $response;
|
||||
if(!isset($userData['email'])) throw new \IPS\Login\Exception( 'В вашем аккаунте ВК отсутствует email, укажите его!', \IPS\Login\Exception::INTERNAL_ERROR );
|
||||
/* Find or create member */
|
||||
$newMember = FALSE;
|
||||
if ( $member === NULL )
|
||||
{
|
||||
$member = \IPS\Member::load( $userData['email'], 'email' );
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
|
||||
$member = new \IPS\Member;
|
||||
if ( \IPS\Settings::i()->reg_auth_type == 'admin' or \IPS\Settings::i()->reg_auth_type == 'admin_user' )
|
||||
{
|
||||
$member->members_bitoptions['validating'] = TRUE;
|
||||
}
|
||||
$member->member_group_id = \IPS\Settings::i()->member_group;
|
||||
$member->email = $userData['email'];
|
||||
$member->profilesync = json_encode( array( 'vkontakte' => array( 'photo' => TRUE, 'cover' => FALSE, 'status' => TRUE ) ) );
|
||||
$newMember = TRUE;
|
||||
|
||||
$name1 = \IPS\Http\Url::external( "https://api.vk.com/method/users.get?user_id={$userData['user_id']}&v=5.29&access_token={$response['access_token']}&fields=first_name,last_name,screen_name,bdate,nickname" )->request()->get()->decodeJson();
|
||||
|
||||
$member->name = $name1['response'][0]['nickname'];
|
||||
|
||||
if ( empty($member->name) AND $this->settings['real_name'] )
|
||||
{
|
||||
$name = $name1['response'][0]['first_name'].' '.$name1['response'][0]['last_name'];
|
||||
$existingUsername = \IPS\Member::load( $name, 'name' );
|
||||
|
||||
if ( !$existingUsername->member_id )
|
||||
{
|
||||
$member->name = $name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$member->vk_uid = $userData['user_id'];
|
||||
$member->vk_token = $response['access_token'];
|
||||
$member->save();
|
||||
|
||||
/* Sync */
|
||||
if ( $newMember )
|
||||
{
|
||||
if ( \IPS\Settings::i()->reg_auth_type == 'admin_user' )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_validating', array( 'user_verified' => 1 ), array( 'member_id=?', $member->member_id ) );
|
||||
}
|
||||
|
||||
$sync = new \IPS\core\ProfileSync\VK( $member );
|
||||
|
||||
$sync->sync();
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return $member;
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
throw new \IPS\Login\Exception( 'generic_error', \IPS\Login\Exception::INTERNAL_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
public static function link( \IPS\Member $member, $details )
|
||||
{
|
||||
try {
|
||||
$userData = \IPS\Http\Url::external( "https://api.vk.com/method/users.get?uid={$details[1]}&access_token={$details[0]}&fields=first_name,last_name,screen_name,bdate,nickname" )->request()->get()->decodeJson();
|
||||
$userData = $userData['response'][0];
|
||||
$member->vk_id = $details[1];
|
||||
$member->vk_token = $details[0];
|
||||
$member->save();
|
||||
}catch(\Exception $e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Settings Form
|
||||
*
|
||||
* @param string $url URL to redirect user to after successful submission
|
||||
* @return array List of settings to save - settings will be stored to core_login_handlers.login_settings DB field
|
||||
* @code
|
||||
return array( 'savekey' => new \IPS\Helpers\Form\[Type]( ... ), ... );
|
||||
* @endcode
|
||||
*/
|
||||
public function acpForm()
|
||||
{
|
||||
$where = array( array( 'template_group=?', 'login' ) );
|
||||
|
||||
$where[] = array( 'template_app=?', 'core' );
|
||||
|
||||
$where[] = array( 'template_location=?', 'global' );
|
||||
|
||||
$results = array();
|
||||
$selects = \IPS\Db::i()->select( 'template_name', 'core_theme_templates', $where );
|
||||
$selects->rewind();
|
||||
while($selects->valid())
|
||||
{
|
||||
$results[ $selects->current() ] = $selects->current();
|
||||
$selects->next();
|
||||
}
|
||||
|
||||
$results = array_unique( $results );
|
||||
//if(\IPS\IN_DEV) {
|
||||
|
||||
if(!in_array('vkontakte',$results)) {
|
||||
|
||||
ob_start();?>
|
||||
<ips:template parameters="$url" />
|
||||
<a href='{$url}' class='ipsButton ipsButton_verySmall ipsButton_fullWidth ipsSocial ipsSocial_vk' style="background-color:#56789C;">
|
||||
<span class='ipsSocial_icon'><i class='fa fa-vk'></i></span>
|
||||
<span class='ipsSocial_text'>{lang="login_vkontakte"}</span>
|
||||
</a>
|
||||
<?
|
||||
$html = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$params = array();
|
||||
|
||||
/* Parse the header tag */
|
||||
preg_match( '/^<ips:template parameters="(.+?)?" \/>\n/', $html, $params );
|
||||
|
||||
/* Strip it */
|
||||
$html = ( isset($params[0]) ) ? str_replace( $params[0], '', $html ) : $html;
|
||||
$id=0;
|
||||
\IPS\Db::i()->insert( 'core_theme_templates', array( 'template_set_id' => $id,
|
||||
'template_app' => 'core',
|
||||
'template_added_to' => $id,
|
||||
'template_location' => 'global',
|
||||
'template_group' => 'login',
|
||||
'template_name' => 'vkontakte',
|
||||
'template_data' => ( isset( $params[1] ) ) ? $params[1] : '',
|
||||
'template_content' => $html,
|
||||
'template_updated' => time(),
|
||||
'template_unique_key' => md5( $id . ';' . 'core' . ';' . 'global' . ';' . 'login' . ';' . ( 'vkontakte' ) ),
|
||||
'template_removable' => $id ) );
|
||||
\IPS\Theme::load( \IPS\Theme::i()->defaultTheme() )->compileTemplates( 'core' );
|
||||
|
||||
}
|
||||
|
||||
/*}elseif(!in_array('vkontakte',$results)) {
|
||||
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
'help' => array(
|
||||
'link' => \IPS\Http\Url::internal( '&app=core&module=settings&controller=login&do=form&id=vkontakte' ),
|
||||
'title' => 'Шаблоны не синхронизированы. Включите DEV-режим и перезагрузите страницу!',
|
||||
),
|
||||
);
|
||||
}*/
|
||||
|
||||
return array(
|
||||
'app_id' => new \IPS\Helpers\Form\Text( 'login_vkontakte_app', ( isset( $this->settings['app_id'] ) ) ? $this->settings['app_id'] : '', TRUE ),
|
||||
'app_secret' => new \IPS\Helpers\Form\Text( 'login_vkontakte_secret', ( isset( $this->settings['app_secret'] ) ) ? $this->settings['app_secret'] : '', TRUE ),
|
||||
'real_name' => new \IPS\Helpers\Form\YesNo( 'login_real_name', ( isset( $this->settings['real_name'] ) ) ? $this->settings['real_name'] : FALSE, TRUE )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Settings
|
||||
*
|
||||
* @return bool
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function testSettings()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a member sign in with this login handler?
|
||||
* Used to ensure when a user disassociates a social login that they have some other way of logging in
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public function canProcess( \IPS\Member $member )
|
||||
{
|
||||
return ( $member->vk_id and $member->vk_token );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a member change their email/password with this login handler?
|
||||
*
|
||||
* @param string $type 'email' or 'password'
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public function canChange( $type, \IPS\Member $member )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -237,6 +237,8 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
*/
|
||||
public function addVote( \IPS\Poll\Vote $vote, \IPS\Member $member = NULL )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
/* Delete existing vote */
|
||||
if ( $existingVote = $this->getVote( $member ) )
|
||||
{
|
||||
@@ -248,6 +250,9 @@ class _Poll extends \IPS\Patterns\ActiveRecord implements \SplSubject
|
||||
$vote->save();
|
||||
$this->notify();
|
||||
|
||||
// Associate the vote with the member id in the cache
|
||||
$this->_voteCache[ $member->member_id ] = $vote;
|
||||
|
||||
/* Log */
|
||||
if ( $vote->member_choices !== NULL )
|
||||
{
|
||||
|
||||
@@ -149,6 +149,7 @@ class _Parser
|
||||
{
|
||||
if ( !function_exists('idn_to_ascii') )
|
||||
{
|
||||
\IPS\IPS::$PSR0Namespaces['TrueBV'] = \IPS\ROOT_PATH . "/system/3rd_party/php-punycode";
|
||||
require_once \IPS\ROOT_PATH . "/system/3rd_party/php-punycode/polyfill.php";
|
||||
}
|
||||
require_once \IPS\ROOT_PATH . "/system/3rd_party/HTMLPurifier/HTMLPurifier.auto.php";
|
||||
|
||||
@@ -808,9 +808,9 @@ class _Theme extends \IPS\Node\Model
|
||||
*/
|
||||
public static function overloadHooks( $class, $namespace="IPS\\Theme" )
|
||||
{
|
||||
if ( isset( \IPS\IPS::$hooks[ "\\IPS\\Theme\\class_{$app}_{$location}_{$group}" ] ) AND \IPS\RECOVERY_MODE === FALSE )
|
||||
if ( isset( \IPS\IPS::$hooks[ "\\IPS\\Theme\\{$class}" ] ) AND \IPS\RECOVERY_MODE === FALSE )
|
||||
{
|
||||
foreach ( \IPS\IPS::$hooks[ "\\IPS\\Theme\\class_{$app}_{$location}_{$group}" ] as $id => $data )
|
||||
foreach ( \IPS\IPS::$hooks[ "\\IPS\\Theme\\{$class}" ] as $id => $data )
|
||||
{
|
||||
if ( file_exists( \IPS\ROOT_PATH . '/' . $data['file'] ) )
|
||||
{
|
||||
@@ -4243,8 +4243,7 @@ EOF;
|
||||
{
|
||||
$content = $content . "\n<p id='elCopyright'>
|
||||
<span id='elCopyright_userLine'>{lang=\"copyright_line_value\"}</span>
|
||||
<a rel='nofollow' title='Community Software by Invision Power Services, Inc.' href='https://www.invisionpower.com/'>Community Software by Invision Power Services, Inc.</a><br />
|
||||
<a id='ruscopy' title='Русская поддержка сайтов на IPS Community Suite' href='http://ipbmafia.ru'>Русская версия</a>
|
||||
<a rel='nofollow' title='Community Software by Invision Power Services, Inc.' href='https://www.invisionpower.com/'>Community Software by Invision Power Services, Inc.</a><br><a href='http://ipbmafia.ru' style='display:none'>Поддержка IPS Community Suite 4 в России</a>
|
||||
</p>";
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user