<?php
namespace AppBundle\Twig;
use ApiBundle\Api\Util\AssetHelper;
use AppBundle\Common\ArrayToolkit;
use AppBundle\Common\ConvertIpToolkit;
use AppBundle\Common\DeviceToolkit;
use AppBundle\Common\ExtensionManager;
use AppBundle\Common\FileToolkit;
use AppBundle\Common\LoginToolkit;
use AppBundle\Common\MathToolkit;
use AppBundle\Common\NumberToolkit;
use AppBundle\Common\PluginVersionToolkit;
use AppBundle\Common\SimpleValidator;
use AppBundle\Component\DeviceDetector\DeviceDetectorAdapter;
use AppBundle\Component\ShareSdk\WeixinShare;
use AppBundle\Util\CategoryBuilder;
use AppBundle\Util\CdnUrl;
use AppBundle\Util\UploadToken;
use Biz\Account\Service\AccountProxyService;
use Biz\CloudPlatform\CloudAPIFactory;
use Biz\CloudPlatform\Service\ResourceFacadeService;
use Biz\ReviewCenter\Service\ReviewCenterService;
use Biz\Taxonomy\Service\TagService;
use Biz\User\Service\TokenService;
use Codeages\Biz\Framework\Context\Biz;
use Codeages\Biz\Framework\Service\Exception\ServiceException;
use CorporateTrainingBundle\Biz\User\Service\UserService;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Topxia\Service\Common\ServiceKernel;
use Twig\Extension\AbstractExtension;
class WebExtension extends AbstractExtension
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var Biz
*/
protected $biz;
protected $pageScripts;
protected $locale;
protected $defaultCloudSdkHost;
public function __construct($container, Biz $biz)
{
$this->container = $container;
$this->biz = $biz;
}
public function getFilters()
{
return [
new \Twig\TwigFilter('smart_time', [$this, 'smarttimeFilter']),
new \Twig\TwigFilter('date_format', [$this, 'dateformatFilter']),
new \Twig\TwigFilter('time_range', [$this, 'timeRangeFilter']),
new \Twig\TwigFilter('time_diff', [$this, 'timeDiffFilter']),
new \Twig\TwigFilter('remain_time', [$this, 'remainTimeFilter']),
new \Twig\TwigFilter('time_formatter', [$this, 'timeFormatterFilter']),
new \Twig\TwigFilter('location_text', [$this, 'locationTextFilter']),
new \Twig\TwigFilter('tags_html', [$this, 'tagsHtmlFilter'], ['is_safe' => ['html']]),
new \Twig\TwigFilter('file_size', [$this, 'fileSizeFilter']),
new \Twig\TwigFilter('plain_text', [$this, 'plainTextFilter'], ['is_safe' => ['html']]),
new \Twig\TwigFilter('sub_text', [$this, 'subTextFilter'], ['is_safe' => ['html']]),
new \Twig\TwigFilter('mb_substr', [$this, 'mb_substr'], ['is_safe' => ['html']]),
new \Twig\TwigFilter('duration', [$this, 'durationFilter']),
new \Twig\TwigFilter('duration_text', [$this, 'durationTextFilter']),
new \Twig\TwigFilter('tags_join', [$this, 'tagsJoinFilter']),
new \Twig\TwigFilter('navigation_url', [$this, 'navigationUrlFilter']),
new \Twig\TwigFilter('chr', [$this, 'chrFilter']),
new \Twig\TwigFilter('bbCode2Html', [$this, 'bbCode2HtmlFilter']),
new \Twig\TwigFilter('score_text', [$this, 'scoreTextFilter']),
new \Twig\TwigFilter('simple_template', [$this, 'simpleTemplateFilter']),
new \Twig\TwigFilter('fill_question_stem_text', [$this, 'fillQuestionStemTextFilter']),
new \Twig\TwigFilter('fill_question_stem_html', [$this, 'fillQuestionStemHtmlFilter']),
new \Twig\TwigFilter('get_course_id', [$this, 'getCourseidFilter']),
new \Twig\TwigFilter('purify_html', [$this, 'getPurifyHtml']),
new \Twig\TwigFilter('purify_and_trim_html', [$this, 'getPurifyAndTrimHtml']),
new \Twig\TwigFilter('file_type', [$this, 'getFileType']),
new \Twig\TwigFilter('at', [$this, 'atFilter']),
new \Twig\TwigFilter('copyright_less', [$this, 'removeCopyright']),
new \Twig\TwigFilter('array_merge', [$this, 'arrayMerge']),
new \Twig\TwigFilter('space2nbsp', [$this, 'spaceToNbsp']),
new \Twig\TwigFilter('number_to_human', [$this, 'numberFilter']),
new \Twig\TwigFilter('array_column', [$this, 'arrayColumn']),
new \Twig\TwigFilter('rename_locale', [$this, 'renameLocale']),
new \Twig\TwigFilter('cdn', [$this, 'cdn']),
new \Twig\TwigFilter('wrap', [$this, 'wrap']),
new \Twig\TwigFilter('convert_absolute_url', [$this, 'convertAbsoluteUrl']),
new \Twig\TwigFilter('days_of_week', [$this, 'daysOfWeek']),
new \Twig\TwigFilter('filter_keys', [$this, 'filterArrayKeys']),
new \Twig\TwigFilter('exam_score', [$this, 'examScore']),
new \Twig\TwigFilter('learn_time_format', [$this, 'formatLearnTime']),
new \Twig\TwigFilter('group_by', [$this, 'groupBy']),
];
}
public function getFunctions()
{
return [
new \Twig\TwigFunction('theme_global_script', [$this, 'getThemeGlobalScript']),
new \Twig\TwigFunction('file_uri_parse', [$this, 'parseFileUri']),
// file_path 即将废弃,不要再使用
new \Twig\TwigFunction('file_path', [$this, 'getFilePath']),
// default_path 即将废弃,不要再使用
new \Twig\TwigFunction('default_path', [$this, 'getDefaultPath']),
// file_url 即将废弃,不要再使用
new \Twig\TwigFunction('file_url', [$this, 'getFileUrl']),
// system_default_path,即将废弃,不要再使用
new \Twig\TwigFunction('system_default_path', [$this, 'getSystemDefaultPath']),
new \Twig\TwigFunction('fileurl', [$this, 'getFurl']),
new \Twig\TwigFunction('filepath', [$this, 'getFpath']),
new \Twig\TwigFunction('lazy_img', [$this, 'makeLazyImg'], ['is_safe' => ['html']]),
new \Twig\TwigFunction('avatar_path', [$this, 'avatarPath']),
new \Twig\TwigFunction('object_load', [$this, 'loadObject']),
new \Twig\TwigFunction('setting', [$this, 'getSetting']),
new \Twig\TwigFunction('set_price', [$this, 'getSetPrice']),
new \Twig\TwigFunction('percent', [$this, 'calculatePercent']),
new \Twig\TwigFunction('rate_format', [$this, 'rateFormat']),
new \Twig\TwigFunction('category_choices', [$this, 'getCategoryChoices']),
new \Twig\TwigFunction('category_choices_with_category_empty', [$this, 'getCategoryChoicesWithCategoryEmpty']),
new \Twig\TwigFunction('upload_max_filesize', [$this, 'getUploadMaxFilesize']),
new \Twig\TwigFunction('js_paths', [$this, 'getJsPaths']),
new \Twig\TwigFunction('is_plugin_installed', [$this, 'isPluginInstalled']),
new \Twig\TwigFunction('plugin_version', [$this, 'getPluginVersion']),
new \Twig\TwigFunction('version_compare', [$this, 'versionCompare']),
new \Twig\TwigFunction('is_exist_in_subarray_by_id', [$this, 'isExistInSubArrayById']),
new \Twig\TwigFunction('context_value', [$this, 'getContextValue']),
new \Twig\TwigFunction('is_feature_enabled', [$this, 'isFeatureEnabled']),
new \Twig\TwigFunction('parameter', [$this, 'getParameter']),
new \Twig\TwigFunction('upload_token', [$this, 'makeUpoadToken']),
new \Twig\TwigFunction('countdown_time', [$this, 'getCountdownTime']),
//todo covertIP 要删除
new \Twig\TwigFunction('convertIP', [$this, 'getConvertIP']),
new \Twig\TwigFunction('convert_ip', [$this, 'getConvertIP']),
new \Twig\TwigFunction('new_convert_ip', [$this, 'getNewConverIP']),
new \Twig\TwigFunction('isHide', [$this, 'isHideThread']),
new \Twig\TwigFunction('user_coin_amount', [$this, 'userCoinAmount']),
new \Twig\TwigFunction('user_balance', [$this, 'getBalance']),
new \Twig\TwigFunction('blur_user_name', [$this, 'blurUserName']),
new \Twig\TwigFunction('blur_phone_number', [$this, 'blur_phone_number']),
new \Twig\TwigFunction('blur_idcard_number', [$this, 'blur_idcard_number']),
new \Twig\TwigFunction('blur_number', [$this, 'blur_number']),
new \Twig\TwigFunction('sub_str', [$this, 'subStr']),
new \Twig\TwigFunction('convert_encoding_sub_str', [$this, 'convertEncodingSubStr']),
new \Twig\TwigFunction('load_script', [$this, 'loadScript']),
new \Twig\TwigFunction('export_scripts', [$this, 'exportScripts']),
new \Twig\TwigFunction('order_payment', [$this, 'getOrderPayment']),
new \Twig\TwigFunction('classroom_permit', [$this, 'isPermitRole']),
new \Twig\TwigFunction('crontab_next_executed_time', [$this, 'getNextExecutedTime']),
new \Twig\TwigFunction('finger_print', [$this, 'getFingerprint']),
new \Twig\TwigFunction('get_parameters_from_url', [$this, 'getParametersFromUrl']),
new \Twig\TwigFunction('is_trial', [$this, 'isTrial']),
new \Twig\TwigFunction('timestamp', [$this, 'timestamp']),
new \Twig\TwigFunction('get_user_vip_level', [$this, 'getUserVipLevel']),
new \Twig\TwigFunction('is_without_network', [$this, 'isWithoutNetwork']),
new \Twig\TwigFunction('get_admin_roles', [$this, 'getAdminRoles']),
new \Twig\TwigFunction('render_notification', [$this, 'renderNotification']),
new \Twig\TwigFunction('route_exsit', [$this, 'routeExists']),
new \Twig\TwigFunction('is_micro_messenger', [$this, 'isMicroMessenger']),
new \Twig\TwigFunction('wx_js_sdk_config', [$this, 'weixinConfig']),
new \Twig\TwigFunction('plugin_update_notify', [$this, 'pluginUpdateNotify']),
new \Twig\TwigFunction('tag_equal', [$this, 'tagEqual']),
new \Twig\TwigFunction('get_tag', [$this, 'getTag']),
new \Twig\TwigFunction('array_index', [$this, 'arrayIndex']),
new \Twig\TwigFunction('cdn', [$this, 'getCdn']),
new \Twig\TwigFunction('is_show_mobile_page', [$this, 'isShowMobilePage']),
new \Twig\TwigFunction('is_mobile_client', [$this, 'isMobileClient']),
new \Twig\TwigFunction('is_allow_browse', [$this, 'isAllowBrowse']),
new \Twig\TwigFunction('is_ES_copyright', [$this, 'isESCopyright']),
new \Twig\TwigFunction('get_classroom_name', [$this, 'getClassroomName']),
new \Twig\TwigFunction('pop_reward_point_notify', [$this, 'popRewardPointNotify']),
new \Twig\TwigFunction('array_filter', [$this, 'arrayFilter']),
new \Twig\TwigFunction('base_path', [$this, 'basePath']),
new \Twig\TwigFunction('get_login_email_address', [$this, 'getLoginEmailAddress']),
new \Twig\TwigFunction('cloud_sdk_url', [$this, 'getCloudSdkUrl']),
new \Twig\TwigFunction('math_format', [$this, 'mathFormat']),
new \Twig\TwigFunction('parse_user_agent', [$this, 'parseUserAgent']),
new \Twig\TwigFunction('wechat_login_bind_enabled', [$this, 'isWechatLoginBind']),
new \Twig\TwigFunction('can_send_message', [$this, 'canSendMessage']),
new \Twig\TwigFunction('is_hidden_video_header', [$this, 'isHiddenVideoHeader']),
new \Twig\TwigFunction('arrays_key_convert', [$this, 'arraysKeyConvert']),
new \Twig\TwigFunction('make_local_media_file_token', [$this, 'makeLocalMediaFileToken']),
new \Twig\TwigFunction('online_advisory_auth_info', [$this, 'onlineAdvisoryAuthInfo']),
new \Twig\TwigFunction('question_html_filter', [$this, 'questionHtmlFilter']),
new \Twig\TwigFunction('uniqid', [$this, 'uniqid']),
new \Twig\TwigFunction('can_operate_question', [$this, 'canOperateQuestion']),
new \Twig\TwigFunction('sync_mode_dict', [$this, 'getSyncModeDict']),
new \Twig\TwigFunction('show_feedback_bar', [$this, 'showFeedbackBar']),
new \Twig\TwigFunction('is_saas', [$this, 'isSaaS']),
new \Twig\TwigFunction('member_deadline', [$this, 'handleDeadline']),
new \Twig\TwigFunction('get_course_market_url', [$this, 'getCourseMarketUrl']),
new \Twig\TwigFunction('org_msg', [$this, 'getOrgMsg']),
new \Twig\TwigFunction('get_category_name', [$this, 'getCategoryName']),
new \Twig\TwigFunction('get_category_ids_by_categories', [$this, 'getCategoryIdsByCategories']),
new \Twig\TwigFunction('get_review_pending_total_num', [$this, 'getReviewPendingTotalNum']),
new \Twig\TwigFunction('get_remember_me_deadline_range_text', [$this, 'getRememberMeDeadlineRangeText']),
];
}
public function getCourseMarketUrl()
{
return ServiceKernel::instance()->getParameter('security.course_market.url');
}
public function parseUserAgent($userAgent)
{
$deviceDetector = new DeviceDetectorAdapter($userAgent);
return [
'device' => $deviceDetector->getDevice(),
'client' => $deviceDetector->getClient(),
'os' => $deviceDetector->getOs(),
];
}
public function handleDeadline($deadline, $issueDate = 0)
{
if (0 == $deadline) {
return 0;
}
if (0 == $issueDate) {
$time = time();
} else {
$time = $issueDate;
}
if (($deadline - $time) < 0) {
return -1;
}
return floor(($deadline - $time) / 3600 / 24);
}
public function arrayFilter($data, $filterName)
{
if (empty($data) || !is_array($data)) {
return [];
}
return array_filter($data, function ($value) use ($filterName) {
foreach ($filterName as $name) {
if ('' === $value[$name]) {
return false;
}
}
return true;
});
}
public function getReviewPendingTotalNum()
{
$user = $this->getUserService()->getCurrentUser();
$reviewPendingCount = $this->getReviewCenterService()->getPendingTabbar($user['id']);
return array_sum(array_column($reviewPendingCount, 'pendingCount'));
}
public function isShowMobilePage()
{
$wapSetting = $this->getSetting('wap', []);
if (empty($wapSetting['enabled'])) {
return false;
}
$pcVersion = $this->container->get('request_stack')->getMainRequest()->cookies->get('PCVersion', 0);
if ($pcVersion) {
return false;
}
return DeviceToolkit::isMobileClient();
}
public function isMobileClient()
{
return DeviceToolkit::isMobileClient();
}
public function isAllowBrowse()
{
$userAgent = $this->container->get('request_stack')->getMainRequest()->headers->get('User-Agent');
$allowedBrowse = ['MicroMessenger', 'wxwork', 'DingTalk', 'Feishu'];
$allow = false;
foreach ($allowedBrowse as $browse) {
if (false !== strpos($userAgent, $browse)) {
$allow = true;
break;
}
}
return $allow;
}
public function isESCopyright()
{
$copyright = $this->getSetting('copyright');
$request = $this->container->get('request_stack')->getMainRequest();
$host = $request->getHttpHost();
if ($copyright) {
$result = !(
isset($copyright['owned'])
&& isset($copyright['thirdCopyright'])
&& 2 != $copyright['thirdCopyright']
&& isset($copyright['licenseDomains'])
&& in_array($host, explode(';', $copyright['licenseDomains']))
|| (isset($copyright['thirdCopyright']) && 2 == $copyright['thirdCopyright'])
);
return $result;
}
return true;
}
public function getClassroomName()
{
return $this->getSetting('classroom.name', $this->container->get('translator')->trans('site.default.classroom'));
}
public function tagEqual($tags, $targetTagId, $targetTagGroupId)
{
foreach ($tags as $groupId => $tagId) {
if ($groupId == $targetTagGroupId && $tagId == $targetTagId) {
return true;
}
}
return false;
}
public function getTag($tagId)
{
if (empty($tagId)) {
return null;
}
return $this->getTagService()->getTag($tagId);
}
public function arrayIndex($array, $key)
{
if (empty($array) || !is_array($array)) {
return [];
}
return ArrayToolkit::index($array, $key);
}
public function timeFormatterFilter($time)
{
if ($time <= 60) {
return $this->trans('site.twig.extension.time_interval.minute', ['%diff%' => 0]);
}
if ($time <= 3600) {
return $this->trans('site.twig.extension.time_interval.minute', ['%diff%' => round($time / 60)]);
}
return $this->trans('site.twig.extension.time_interval.hour_minute', ['%diff_hour%' => floor($time / 3600), '%diff_minute%' => round($time % 3600 / 60)]);
}
public function pluginUpdateNotify()
{
$count = $this->getAppService()->findAppCount();
$apps = $this->getAppService()->findApps(0, $count);
$apps = array_filter($apps, function ($app) {
return 'EduSoho官方' == $app['developerName'];
});
$notifies = array_reduce(
$apps,
function ($notifies, $app) {
if (!PluginVersionToolkit::dependencyVersion($app['code'], $app['version'])) {
$notifies[$app['type']][] = $app['name'];
} elseif ('TRAININGMAIN' !== $app['code'] && $app['protocol'] < 3) {
$notifies[$app['type']][] = $app['name'];
}
return $notifies;
},
[]
);
return $notifies;
}
public function getAdminRoles()
{
return $this->createService('Role:RoleService')->searchRoles([], 'created', 0, 1000);
}
public function getCdn($type = 'default')
{
$cdn = new CdnUrl();
$cdnUrl = $cdn->get($type);
return $cdnUrl;
}
public function cdn($content)
{
$cdn = new CdnUrl();
$cdnUrl = $cdn->get('content');
if ($cdnUrl) {
$publicUrlPath = $this->container->getParameter('topxia.upload.public_url_path');
$themeUrlPath = $this->container->getParameter('topxia.web_themes_url_path');
$assetUrlPath = $this->container->getParameter('topxia.web_assets_url_path');
$bundleUrlPath = $this->container->getParameter('topxia.web_bundles_url_path');
$staticDistUrlPath = $this->container->getParameter('front_end.web_static_dist_url_path');
preg_match_all('/<img[^>]*src=[\'"]?([^>\'"\s]*)[\'"]?[^>]*>/i', $content, $imgs);
if ($imgs) {
foreach ($imgs[1] as $img) {
if (0 === strpos($img, $publicUrlPath)
|| 0 === strpos($img, $themeUrlPath)
|| 0 === strpos($img, $assetUrlPath)
|| 0 === strpos($img, $bundleUrlPath)
|| 0 === strpos($img, $staticDistUrlPath)) {
$content = str_replace('"'.$img, '"'.$cdnUrl.$img, $content);
}
}
}
}
return $content;
}
public function weixinConfig()
{
$weixinmob_enabled = $this->getSetting('login_bind.weixinmob_enabled');
if (!(bool) $weixinmob_enabled) {
return null;
}
$jsApiTicket = $this->createService('User:TokenService')->getTokenByType('jsapi.ticket');
$key = $this->getSetting('login_bind.weixinmob_key');
$secret = $this->getSetting('login_bind.weixinmob_secret');
if (empty($jsApiTicket)) {
$config = ['key' => $key, 'secret' => $secret];
$weixinshare = new WeixinShare($config);
$token = $weixinshare->getJsApiTicket();
if (empty($token)) {
return [];
}
$jsApiTicket = $this->createService('User:TokenService')->makeToken(
'jsapi.ticket',
['data' => $token, 'duration' => $token['expires_in']]
);
}
$config = [
'appId' => $key,
'timestamp' => time(),
'nonceStr' => uniqid($prefix = 'edusoho'),
'jsApiList' => ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQZone', 'onMenuShareQQ'],
];
$jsapi_ticket = $jsApiTicket['data']['ticket'];
$url = $this->container->get('request_stack')->getMainRequest()->getUri();
$string = 'jsapi_ticket='.$jsapi_ticket.'&noncestr='.$config['nonceStr'].'×tamp='.$config['timestamp'].'&url='.$url;
$config['string'] = $string;
$config['signature'] = sha1($string);
return json_encode($config);
}
public function renderNotification($notification)
{
if ($notification) {
$manager = ExtensionManager::instance();
$notification['message'] = $manager->renderNotification($notification);
}
return $notification;
}
public function routeExists($name)
{
$router = $this->container->get('router');
return (null === $router->getRouteCollection()->get($name)) ? false : true;
}
public function isWithoutNetwork()
{
$network = $this->getSetting('developer.without_network', $default = false);
return (bool) $network;
}
public function getUserVipLevel($userId)
{
return $this->createService('VipPlugin:Vip:VipService')->getMemberByUserId($userId);
}
public function getParametersFromUrl($url)
{
$BaseUrl = parse_url($url);
if (isset($BaseUrl['query'])) {
if (strstr($BaseUrl['query'], '&')) {
$parameter = explode('&', $BaseUrl['query']);
$parameters = [];
foreach ($parameter as $key => $value) {
$parameters[$key] = explode('=', $value);
}
} else {
$parameter = explode('=', $BaseUrl['query']);
$parameters = [];
$parameters[0] = $parameter;
}
} else {
return null;
}
return $parameters;
}
public function spaceToNbsp($content)
{
$content = str_replace(' ', ' ', $content);
return $content;
}
public function isMicroMessenger()
{
return false !== strpos($this->container->get('request_stack')->getMainRequest()->headers->get('User-Agent'), 'MicroMessenger');
}
public function renameLocale($locale)
{
$locale = strtolower($locale);
$locale = str_replace('_', '-', $locale);
return 'zh-cn' == $locale ? '' : '-'.$locale;
}
public function getFingerprint()
{
$user = $this->getUserService()->getCurrentUser();
if (!$user->isLogin()) {
return '';
}
$user = $this->getUserService()->getUser($user['id']);
// @todo 如果配置用户的关键信息,这个方法存在信息泄漏风险,更换新播放器后解决这个问题。
$pattern = $this->getSetting('magic.video_fingerprint');
if ($pattern) {
$fingerprint = $this->parsePattern($pattern, $user);
} else {
$request = $this->container->get('request_stack')->getMainRequest();
$host = $request->getHttpHost();
$fingerprint = "{$host} {$user['nickname']}";
}
return $fingerprint;
}
public function popRewardPointNotify()
{
$session = $this->container->get('session');
if (empty($session)) {
return '';
}
$message = $session->get('Reward-Point-Notify');
$session->remove('Reward-Point-Notify');
return $message;
}
protected function parsePattern($pattern, $user)
{
$profile = $this->getUserService()->getUserProfile($user['id']);
$values = array_merge($user, $profile);
$values = array_filter(
$values,
function ($value) {
return !is_array($value);
}
);
return $this->simpleTemplateFilter($pattern, $values);
}
public function subStr($text, $start, $length)
{
$text = trim($text);
$length = (int) $length;
if (($length > 0) && (mb_strlen($text) > $length)) {
$text = mb_substr($text, $start, $length, 'UTF-8');
}
return $text;
}
public function convertEncodingSubStr($text, $start, $length)
{
$strlen = (strlen($text) + mb_strlen($text, 'UTF-8')) / 2;
if ($strlen <= $length) {
return $text;
}
$text = mb_strcut(mb_convert_encoding($text, 'GBK', 'UTF-8'), 0, $length, 'GBK');
return mb_convert_encoding($text, 'UTF-8', 'GBK').'...';
}
public function userCoinAmount($type, $userId, $startDateTime = null, $endDateTime = null)
{
if (!empty($endDateTime)) {
$condition['created_time_LTE'] = strtotime($endDateTime);
}
if (!empty($startDateTime)) {
$condition['created_time_GTE'] = strtotime($startDateTime);
}
$condition = [
'user_id' => $userId,
'type' => $type,
'amount_type' => 'coin',
];
$amount = $this->getAccountProxyService()->sumColumnByConditions('amount', $condition);
return $amount;
}
public function getBalance($userId)
{
$balance = $this->getAccountProxyService()->getUserBalanceByUserId($userId);
return $balance;
}
/**
* @return AccountProxyService
*/
protected function getAccountProxyService()
{
return $this->createService('Account:AccountProxyService');
}
/**
* @return UserService
*/
private function getUserService()
{
return $this->createService('User:UserService');
}
public function isExistInSubArrayById($currentTarget, $targetArray)
{
foreach ($targetArray as $target) {
if ($currentTarget['id'] == $target['id']) {
return true;
}
}
return false;
}
public function getThemeGlobalScript()
{
$theme = $this->getSetting('theme.uri', 'default');
$filePath = realpath(
$this->container->getParameter('kernel.root_dir')."/../web/themes/{$theme}/js/global-script.js"
);
if ($filePath) {
return 'theme/global-script';
}
return '';
}
public function isPluginInstalled($name)
{
return $this->container->get('kernel')->getPluginConfigurationManager()->isPluginInstalled($name);
}
public function getPluginVersion($name)
{
$plugins = $this->container->get('kernel')->getPlugins();
foreach ($plugins as $plugin) {
if (strtolower($plugin['code']) == strtolower($name)) {
return $plugin['version'];
}
}
return null;
}
public function versionCompare($version1, $version2, $operator)
{
return version_compare($version1, $version2, $operator);
}
public function getJsPaths($excludedCdnResources = [])
{
$cdnUrl = new CdnUrl();
$basePath = $cdnUrl->get();
if (empty($basePath)) {
$basePath = $this->container->get('request_stack')->getMainRequest()->getBasePath();
}
$theme = $this->getSetting('theme.uri', 'default');
$plugins = $this->container->get('kernel')->getPlugins();
$names = [];
$newPluginNames = [];
foreach ($plugins as $plugin) {
if (is_array($plugin)) {
if ('plugin' != $plugin['type']) {
continue;
}
if (isset($plugin['protocol']) && 3 == $plugin['protocol']) {
$newPluginNames[] = $plugin['code'].'plugin';
} else {
$names[] = $plugin['code'];
}
} else {
$names[] = $plugin;
}
}
$names[] = 'customweb';
$names[] = 'customadmin';
$names[] = 'custom';
$names[] = 'topxiaweb';
$names[] = 'topxiaadmin';
$names[] = 'classroom';
$names[] = 'materiallib';
$names[] = 'sensitiveword';
$names[] = 'permission';
$names[] = 'org';
$names[] = 'corporatetraining';
$paths = [
'common' => 'common',
'theme' => "{$basePath}/themes/{$theme}/js",
];
foreach ($names as $name) {
$name = strtolower($name);
if (!empty($excludedCdnResources) && in_array($name, $excludedCdnResources)) {
$paths["{$name}bundle"] = "/bundles/{$name}/js";
} else {
$paths["{$name}bundle"] = "{$basePath}/bundles/{$name}/js";
}
}
foreach ($newPluginNames as $newPluginName) {
$newPluginName = strtolower($newPluginName);
if (!empty($excludedCdnResources) && in_array($newPluginName, $excludedCdnResources)) {
$paths["{$newPluginName}"] = "/bundles/{$newPluginName}/js";
} else {
$paths["{$newPluginName}"] = "{$basePath}/bundles/{$newPluginName}/js";
}
}
// $paths['balloon-video-player'] = 'http://player-cdn.edusoho.net/balloon-video-player';
return $paths;
}
public function getContextValue($context, $key)
{
$keys = explode('.', $key);
$value = $context;
foreach ($keys as $key) {
if (!isset($value[$key])) {
throw new \InvalidArgumentException(sprintf('Key `%s` is not in context with %s', $key, implode(array_keys($context), ', ')));
}
$value = $value[$key];
}
return $value;
}
public function isFeatureEnabled($feature)
{
$features = $this->container->hasParameter('enabled_features') ? $this->container->getParameter(
'enabled_features'
) : [];
return in_array($feature, $features);
}
public function getParameter($name, $default = null)
{
if (!$this->container->hasParameter($name)) {
return $default;
}
return $this->container->getParameter($name);
}
public function makeUpoadToken($group, $type = 'image', $duration = 18000)
{
$maker = new UploadToken();
return $maker->make($group, $type, $duration);
}
public function getConvertIP($ip)
{
if (!empty($ip)) {
$location = ConvertIpToolkit::convertIp($ip);
if ('INNA' === $location) {
return '未知区域';
}
return $location;
}
return '';
}
public function getNewConverIP($ip)
{
if (!empty($ip)) {
$location = ConvertIpToolkit::newConvertIp($ip);
if ('INNA' === $location) {
return '未知区域';
}
$location = array_filter($location);
return implode(' ', $location);
}
return '';
}
public function dateformatFilter($time, $format = '')
{
if (empty($time)) {
return;
}
if (empty($format)) {
return date('Y-m-d H:i', $time);
}
return date($format, $time);
}
public function smarttimeFilter($time)
{
$diff = time() - $time;
if ($diff < 0) {
return $this->trans('site.twig.extension.smarttime.future');
}
if (0 == $diff) {
return $this->trans('site.twig.extension.smarttime.hardly');
}
if ($diff < 60) {
return $this->trans('site.twig.extension.smarttime.previous_second', ['%diff%' => $diff]);
}
if ($diff < 3600) {
return $this->trans('site.twig.extension.smarttime.previous_minute', ['%diff%' => round($diff / 60)]);
}
if ($diff < 86400) {
return $this->trans('site.twig.extension.smarttime.previous_hour', ['%diff%' => round($diff / 3600)]);
}
if ($diff < 2592000) {
return $this->trans('site.twig.extension.smarttime.previous_day', ['%diff%' => round($diff / 86400)]);
}
if ($diff < 31536000) {
return date('m-d', $time);
}
return date('Y-m-d', $time);
}
public function remainTimeFilter($value, $timeType = '')
{
$remainTime = [];
$remain = $value - time();
if ($remain <= 0 && empty($timeType)) {
return $remainTime['second'] = '0'.$this->trans('site.date.minute');
}
if ($remain <= 3600 && empty($timeType)) {
return $remainTime['minutes'] = round($remain / 60).$this->trans('site.date.minute');
}
if ($remain < 86400 && empty($timeType)) {
return $remainTime['hours'] = round($remain / 3600).$this->trans('site.date.hour');
}
$remainTime['day'] = round(($remain < 0 ? 0 : $remain) / 86400).$this->trans('site.date.day');
if (!empty($timeType)) {
return $remainTime[$timeType];
} else {
return $remainTime['day'];
}
}
public function getCountdownTime($value)
{
$countdown = ['days' => 0, 'hours' => 0, 'minutes' => 0, 'seconds' => 0];
$remain = $value - time();
if ($remain <= 0) {
return $countdown;
}
$countdown['days'] = intval($remain / 86400);
$remain = $remain - 86400 * $countdown['days'];
$countdown['hours'] = intval($remain / 3600);
$remain = $remain - 3600 * $countdown['hours'];
$countdown['minutes'] = intval($remain / 60);
$remain = $remain - 60 * $countdown['minutes'];
$countdown['seconds'] = $remain;
return $countdown;
}
public function durationFilter($value)
{
$minutes = intval($value / 60);
$seconds = $value - $minutes * 60;
return sprintf('%02d', $minutes).':'.sprintf('%02d', $seconds);
}
public function durationTextFilter($value)
{
$minutes = intval($value / 60);
$seconds = $value - $minutes * 60;
if (0 === $minutes) {
return $seconds.$this->trans('site.date.second');
}
return $this->trans('site.twig.extension.time_interval.minute_second', ['%diff_minute%' => $minutes, '%diff_second%' => $seconds]);
}
public function timeRangeFilter($start, $end)
{
$range = date('Y-n-d H:i', $start).' - ';
if ($this->container->get('topxia.timemachine')->inSameDay($start, $end)) {
$range .= date('H:i', $end);
} else {
$range .= date('Y年n月d日 H:i', $end);
}
return $range;
}
public function timeDiffFilter($endTime, $diffDay = 0, $startTime = '')
{
$endSecond = strtotime(date('Y-m-d', $endTime));
$startSecond = empty($startTime) ? strtotime(date('Y-m-d', time())) : $startTime;
$diffDay = round(($endSecond - $startSecond) / 86400, 0, PHP_ROUND_HALF_DOWN); // 丢弃小数点
return $diffDay > 0 ? $diffDay : 0;
}
public function tagsJoinFilter($tagIds)
{
if (empty($tagIds) || !is_array($tagIds)) {
return '';
}
$tags = $this->createService('Taxonomy:TagService')->findTagsByIds($tagIds);
$names = ArrayToolkit::column($tags, 'name');
return join($names, ',');
}
public function navigationUrlFilter($url)
{
$url = (string) $url;
if (strpos($url, '://')) {
return $url;
}
if (!empty($url[0]) && ('/' == $url[0])) {
return $url;
}
return $this->container->get('request_stack')->getMainRequest()->getBaseUrl().'/'.$url;
}
/**
* P -> 省全称, p -> 省简称
* C -> 城市全称, c -> 城市简称
* D -> 区全称, d -> 区简称.
*
* @param [type] $districeId [description]
* @param string $format 格式,默认格式'P C D'
*
* @return [type] [description]
*/
public function locationTextFilter($districeId, $format = 'P C D')
{
$text = '';
$names = $this->createService('Taxonomy:LocationService')->getLocationFullName($districeId);
$len = strlen($format);
for ($i = 0; $i < $len; ++$i) {
switch ($format[$i]) {
case 'P':
$text .= $names['province'];
break;
case 'p':
$text .= $this->mb_trim($names['province'], '省');
break;
case 'C':
$text .= $names['city'];
break;
case 'c':
$text .= $this->mb_trim($names['city'], '市');
break;
case 'D':
case 'd':
$text .= $names['district'];
break;
default:
$text .= $format[$i];
break;
}
}
return $text;
}
public function tagsHtmlFilter($tags, $class = '')
{
$links = [];
$tags = $this->createService('Taxonomy:TagService')->findTagsByIds($tags);
foreach ($tags as $tag) {
$url = $this->container->get('router')->generate('course_explore', ['tagId' => $tag['id']]);
$links[] = "<a href=\"{$url}\" class=\"{$class}\">{$tag['name']}</a>";
}
return implode(' ', $links);
}
public function parseFileUri($uri)
{
$kernel = ServiceKernel::instance();
return $kernel->createService('Content:FileService')->parseFileUri($uri);
}
public function getFilePath($uri, $default = '', $absolute = false)
{
$assets = $this->container->get('assets.default_package_util');
$request = $this->container->get('request_stack')->getMainRequest();
if (empty($uri)) {
$url = $assets->getUrl('assets/img/default/'.$default);
// $url = $request->getBaseUrl() . '/assets/img/default/' . $default;
if ($absolute) {
$url = $request->getSchemeAndHttpHost().$url;
}
return $url;
}
if (false !== strpos($uri, 'http://')) {
return $uri;
}
$uri = $this->parseFileUri($uri);
if ('public' == $uri['access']) {
$url = rtrim($this->container->getParameter('topxia.upload.public_url_path'), ' /').'/'.$uri['path'];
$url = ltrim($url, ' /');
$url = $assets->getUrl($url);
if ($absolute) {
$url = $request->getSchemeAndHttpHost().$url;
}
return $url;
}
}
public function getDefaultPath($category, $uri = '', $size = '', $absolute = false)
{
$assets = $this->container->get('assets.default_package_util');
$request = $this->container->get('request_stack')->getMainRequest();
if (empty($uri)) {
$publicUrlpath = 'assets/img/default/';
$url = $assets->getUrl($publicUrlpath.$size.$category);
$defaultSetting = $this->createService('System:SettingService')->get('default', []);
$key = 'default'.ucfirst($category);
$fileName = $key.'FileName';
if (array_key_exists($key, $defaultSetting) && array_key_exists($fileName, $defaultSetting)) {
if (1 == $defaultSetting[$key]) {
$url = $assets->getUrl($publicUrlpath.$size.$defaultSetting[$fileName]);
}
} elseif (array_key_exists($key, $defaultSetting) && $defaultSetting[$key]) {
$uri = $defaultSetting[$size.'Default'.ucfirst($category).'Uri'];
} else {
return $url;
}
if ($absolute) {
$url = $request->getSchemeAndHttpHost().$url;
}
return $url;
}
return $this->parseUri($uri, $absolute);
}
public function avatarPath($user, $type = 'middle', $package = 'user')
{
$avatar = !empty($user[$type.'Avatar']) ? $user[$type.'Avatar'] : null;
if (empty($avatar)) {
$avatar = $this->getSetting('avatar.png');
}
return $this->getFpath($avatar, 'avatar.png', $package);
}
private function parseUri($uri, $absolute = false, $package = 'content')
{
if (false !== strpos($uri, 'http://') || false !== strpos($uri, 'https://')) {
return $uri;
}
$assets = $this->container->get('assets.default_package_util');
$request = $this->container->get('request_stack')->getMainRequest();
if (strpos($uri, '://')) {
$uri = $this->parseFileUri($uri);
$url = '';
if ('public' == $uri['access']) {
$url = $uri['path'];
}
if ('themes' == $uri['access']) {
return $this->addHost('/'.$uri['access'].'/'.$uri['path'], $absolute, $package);
}
} else {
$url = $uri;
}
$url = rtrim($this->container->getParameter('topxia.upload.public_url_path'), ' /').'/'.$url;
return $this->addHost($url, $absolute, $package);
}
public function getSystemDefaultPath($defaultKey, $absolute = false)
{
$assets = $this->container->get('assets.default_package_util');
$defaultSetting = $this->getSetting('default', []);
if (array_key_exists($defaultKey, $defaultSetting)
&& $defaultSetting[$defaultKey]
) {
$path = $defaultSetting[$defaultKey];
return $this->parseUri($path, $absolute);
} else {
$path = $assets->getUrl('assets/img/default/'.$defaultKey);
return $this->addHost($path, $absolute);
}
}
public function makeLazyImg($src, $class = '', $alt = '', $img = 'lazyload_course.png')
{
$imgpath = $path = $this->container->get('assets.default_package_util')->getUrl('assets/img/default/'.$img);
return sprintf('<img src="%s" alt="%s" class="%s" data-echo="%s" />', $imgpath, $alt, $class, $src);
}
public function loadScript($js)
{
$js = is_array($js) ? $js : [$js];
if ($this->pageScripts) {
$this->pageScripts = array_merge($this->pageScripts, $js);
} else {
$this->pageScripts = $js;
}
}
public function exportScripts()
{
if (empty($this->pageScripts)) {
$this->pageScripts = [];
}
return array_values(array_unique($this->pageScripts));
}
public function getFileUrl($uri, $default = '', $absolute = false)
{
$assets = $this->container->get('assets.default_package_util');
$request = $this->container->get('request_stack')->getMainRequest();
if (empty($uri)) {
$url = $assets->getUrl('assets/img/default/'.$default);
if ($absolute) {
$url = $request->getSchemeAndHttpHost().$url;
}
return $url;
}
$url = rtrim($this->container->getParameter('topxia.upload.public_url_path'), ' /').'/'.$uri;
$url = ltrim($url, ' /');
$url = $assets->getUrl($url);
if ($absolute) {
$url = $request->getSchemeAndHttpHost().$url;
}
return $url;
}
public function getFurl($path, $defaultKey = false, $package = 'content')
{
return $this->getPublicFilePath($path, $defaultKey, true, $package);
}
public function getFpath($path, $defaultKey = false, $package = 'content')
{
return $this->getPublicFilePath($path, $defaultKey, false, $package);
}
private function getPublicFilePath($path, $defaultKey = false, $absolute = false, $package = 'content')
{
$assets = $this->container->get('assets.default_package_util');
if (empty($path)) {
$defaultSetting = $this->getSetting('default', []);
if ('user_avatar.png' == $defaultKey) {
$defaultKey = 'avatar.png';
}
if ((('course.png' == $defaultKey && array_key_exists(
'defaultCoursePicture',
$defaultSetting
) && 1 == $defaultSetting['defaultCoursePicture'])
|| ('avatar.png' == $defaultKey && array_key_exists(
'defaultAvatar',
$defaultSetting
) && 1 == $defaultSetting['defaultAvatar']))
&& (array_key_exists($defaultKey, $defaultSetting)
&& $defaultSetting[$defaultKey])
) {
$path = $defaultSetting[$defaultKey];
return $this->parseUri($path, $absolute, $package);
} else {
return $this->addHost('/assets/img/default/'.$defaultKey, $absolute, $package);
}
}
return $this->parseUri($path, $absolute, $package);
}
private function addHost($path, $absolute, $package = 'content')
{
$cdn = new CdnUrl();
$cdnUrl = $cdn->get($package);
if ($cdnUrl) {
$isSecure = $this->container->get('request_stack')->getMainRequest()->isSecure();
$protocal = $isSecure ? 'https:' : 'http:';
$path = $protocal.$cdnUrl.$path;
} elseif ($absolute) {
$request = $this->container->get('request_stack')->getMainRequest();
$path = $request->getSchemeAndHttpHost().$path;
}
return $path;
}
public function basePath($package = 'content')
{
$cdn = new CdnUrl();
$cdnUrl = $cdn->get($package);
if ($cdnUrl) {
$isSecure = $this->container->get('request_stack')->getMainRequest()->isSecure();
$protocal = $isSecure ? 'https:' : 'http:';
$path = $protocal.$cdnUrl;
} else {
$request = $this->container->get('request_stack')->getMainRequest();
$path = $request->getSchemeAndHttpHost();
}
return $path;
}
public function fileSizeFilter($size)
{
$currentValue = $currentUnit = null;
$unitExps = ['B' => 0, 'KB' => 1, 'MB' => 2, 'GB' => 3];
foreach ($unitExps as $unit => $exp) {
$divisor = pow(1024, $exp);
$currentUnit = $unit;
$currentValue = $size / $divisor;
if ($currentValue < 1024) {
break;
}
}
return sprintf('%.2f', $currentValue).$currentUnit;
}
public function numberFilter($number)
{
if ($number <= 1000) {
return $number;
}
$currentValue = $currentUnit = null;
$unitExps = ['千' => 3, '万' => 4, '亿' => 8];
foreach ($unitExps as $unit => $exp) {
$divisor = pow(10, $exp);
$currentUnit = $unit;
$currentValue = $number / $divisor;
if ($currentValue < 10) {
break;
}
}
return sprintf('%.0f', $currentValue).$currentUnit;
}
public function loadObject($type, $id)
{
$kernel = ServiceKernel::instance();
switch ($type) {
case 'user':
return $kernel->createService('User:UserService')->getUser($id);
case 'category':
return $this->getCategoryService()->getCategory($id);
case 'course':
return $kernel->createService('Course:CourseService')->getCourse($id);
case 'file_group':
return $kernel->createService('Content:FileService')->getFileGroup($id);
default:
return null;
}
}
public function plainTextFilter($text, $length = null)
{
$text = strip_tags($text);
$text = str_replace(["\n", "\r", "\t"], '', $text);
$text = str_replace(' ', ' ', $text);
$text = trim($text);
$length = (int) $length;
if (($length > 0) && (mb_strlen($text, 'UTF-8') > $length)) {
$text = mb_substr($text, 0, $length, 'UTF-8');
$text .= '...';
}
return $text;
}
public function subTextFilter($text, $length = null)
{
$text = strip_tags($text);
$text = str_replace(["\n", "\r", "\t"], '', $text);
$text = str_replace(' ', ' ', $text);
$text = trim($text);
$length = (int) $length;
if (($length > 0) && (mb_strlen($text, 'utf-8') > $length)) {
$text = mb_substr($text, 0, $length, 'UTF-8');
$text .= '...';
}
return $text;
}
public function mb_substr($text, $length = null)
{
$text = strip_tags($text);
$text = str_replace(["\n", "\r", "\t"], '', $text);
$text = str_replace(' ', ' ', $text);
$text = trim($text);
$length = (int) $length;
if (($length > 0) && (mb_strlen($text, 'utf-8') > $length)) {
$text = mb_substr($text, 0, $length, 'UTF-8');
}
return $text;
}
public function getFileType($fileName, $string = null)
{
$fileName = explode('.', $fileName);
if ($string) {
$name = strtolower($fileName[count($fileName) - 1]).$string;
}
return $name;
}
public function getOrgMsg($orgId)
{
$orgService = $this->createService('CorporateTrainingBundle:Org:OrgService');
$org = $orgService->getOrg($orgId);
return $org;
}
public function getCategoryName($categoryId)
{
$categoryService = $this->getCategoryService();
if (empty($categoryId)) {
return '';
}
$category = $categoryService->getCategory($categoryId);
if (empty($category)) {
return '';
}
return $category['name'];
}
public function getCategoryIdsByCategories(array $categories)
{
if (empty($categories)) {
return [];
}
return array_column($categories, 'id');
}
public function chrFilter($index)
{
return chr($index);
}
public function isHideThread($id)
{
$need = $this->createService('Group:ThreadService')->sumGoodsCoinsByThreadId($id);
$thread = $this->createService('Group:ThreadService')->getThread($id);
$data = explode('[/hide]', $thread['content']);
foreach ($data as $key => $value) {
$value = ' '.$value;
sscanf($value, '%[^[][hide=reply]%[^$$]', $replyContent, $replyHideContent);
if ($replyHideContent) {
return true;
}
}
if ($need) {
return true;
}
return false;
}
public function bbCode2HtmlFilter($bbCode)
{
$ext = $this;
$bbCode = preg_replace_callback(
'/\[image\](.*?)\[\/image\]/i',
function ($matches) use ($ext) {
$src = $ext->getFileUrl($matches[1]);
return "<img src='{$src}' />";
},
$bbCode
);
$bbCode = preg_replace_callback(
'/\[audio.*?id="(\d+)"\](.*?)\[\/audio\]/i',
function ($matches) {
return "<span class='audio-play-trigger' href='javascript:;' data-file-id=\"{$matches[1]}\" data-file-type=\"audio\"></span>";
},
$bbCode
);
return $bbCode;
}
public function scoreTextFilter($text)
{
$text = number_format($text, 1, '.', '');
if ((int) $text == $text) {
return (string) (int) $text;
}
return $text;
}
public function simpleTemplateFilter($text, $variables)
{
foreach ($variables as $key => $value) {
$text = str_replace('{{'.$key.'}}', $value, $text);
}
return $text;
}
public function fillQuestionStemTextFilter($stem)
{
return preg_replace('/\[\[.+?\]\]+/', '____', $stem);
}
public function fillQuestionStemHtmlFilter($stem)
{
$index = 0;
$stem = preg_replace_callback(
'/\[\[.+?\]\]+/',
function ($matches) use (&$index) {
++$index;
return "<span class='question-stem-fill-blank'>({$index})</span>";
},
$stem
);
return $stem;
}
public function getCourseidFilter($target)
{
$target = explode('/', $target);
$target = explode('-', $target[0]);
return $target[1];
}
public function getPurifyHtml($html, $trusted = false)
{
if (empty($html)) {
return '';
}
$biz = $this->container->get('biz');
return $biz['html_helper']->purify($html, $trusted);
}
public function atFilter($text, $ats = [])
{
if (empty($ats) || !is_array($ats)) {
return $text;
}
$router = $this->container->get('router');
foreach ($ats as $nickname => $userId) {
$path = $router->generate('user_show', ['id' => $userId]);
$html = "<a href=\"{$path}\" data-uid=\"{$userId}\" target=\"_blank\">@{$nickname}</a>";
$text = preg_replace("/@{$nickname}/ui", $html, $text);
}
return $text;
}
public function removeCopyright($source)
{
if ($this->getSetting('copyright.owned', false)) {
$source = str_ireplace('edusoho', '', $source);
}
return $source;
}
public function getSetting($name, $default = null)
{
$names = explode('.', $name);
$name = array_shift($names);
if (empty($name)) {
return $default;
}
$value = $this->createService('System:SettingService')->get($name);
if (!isset($value)) {
return $default;
}
if (empty($names)) {
return $value;
}
$result = $value;
foreach ($names as $name) {
if (!isset($result[$name])) {
return $default;
}
$result = $result[$name];
}
return $result;
}
public function getOrderPayment($order, $default = null)
{
$coinSettings = $this->createService('System:SettingService')->get('coin', []);
if (!isset($coinSettings['price_type'])) {
$coinSettings['price_type'] = 'RMB';
}
if (!isset($coinSettings['coin_enabled'])) {
$coinSettings['coin_enabled'] = 0;
}
if (1 != $coinSettings['coin_enabled'] || 'coin' != $coinSettings['price_type']) {
if ($order['coinAmount'] > 0 && 0 == $order['amount']) {
$default = '余额支付';
} else {
$dictExtension = $this->container->get('codeages_plugin.dict_twig_extension');
$default = $dictExtension->getDictText('payment', $order['payment']);
}
}
return $default;
}
public function isPermitRole($classroomId, $permission, $isStudentOrAuditor = false)
{
$funcName = 'can'.$permission.'Classroom';
if ($isStudentOrAuditor) {
return $this->createService('Classroom:ClassroomService')->$funcName($classroomId, $isStudentOrAuditor);
}
return $this->createService('Classroom:ClassroomService')->$funcName($classroomId);
}
public function calculatePercent($number, $total)
{
if (0 == $number || 0 == $total) {
return '0%';
}
if ($number >= $total) {
return '100%';
}
return round($number / $total * 100).'%';
}
public function rateFormat($rate, $precision = 0)
{
return round($rate, $precision);
}
public function arrayMerge($text, $content)
{
return array_merge($text, $content);
}
public function getSetPrice($price)
{
return NumberToolkit::roundUp($price);
}
public function getCategoryChoices($groupCode, $isFilter = false, $indent = ' ')
{
$builder = new CategoryBuilder();
return $builder->buildChoices($groupCode, $isFilter, $indent);
}
public function getCategoryChoicesWithCategoryEmpty($groupName, $isFilter = false, $indent = ' ')
{
$builder = new CategoryBuilder();
$choices = $builder->buildChoices($groupName, $isFilter, $indent);
$newChoices[-1] = '未分类';
return $newChoices + $choices;
}
public function getNextExecutedTime()
{
return $this->createService('Crontab:CrontabService')->getNextExcutedTime();
}
public function getUploadMaxFilesize($formated = true)
{
$max = FileToolkit::getMaxFilesize();
if ($formated) {
return FileToolkit::formatFileSize($max);
}
return $max;
}
public function isTrial()
{
if (file_exists($this->container->getParameter('kernel.root_dir').'/data/trial.lock')) {
return true;
}
return false;
}
public function timestamp()
{
return time();
}
public function blurUserName($name)
{
return mb_substr($name, 0, 1, 'UTF-8').'**';
}
public function blur_phone_number($phoneNum)
{
$head = substr($phoneNum, 0, 3);
$tail = substr($phoneNum, -4, 4);
return $head.'****'.$tail;
}
public function blur_idcard_number($idcardNum)
{
$head = substr($idcardNum, 0, 4);
$tail = substr($idcardNum, -2, 2);
return $head.'************'.$tail;
}
public function blur_number($string)
{
if (SimpleValidator::email($string)) {
$head = substr($string, 0, 1);
$tail = substr($string, strpos($string, '@'));
return $head.'***'.$tail;
} elseif (SimpleValidator::mobile($string)) {
$head = substr($string, 0, 3);
$tail = substr($string, -4, 4);
return $head.'****'.$tail;
} elseif (SimpleValidator::bankCardId($string)) {
$tail = substr($string, -4, 4);
return '**** **** **** '.$tail;
} elseif (SimpleValidator::idcard($string)) {
$head = substr($string, 0, 4);
$tail = substr($string, -2, 2);
return $head.'************'.$tail;
}
}
public function mathFormat($number, $multiplicator)
{
$number *= $multiplicator;
return $number;
}
protected function createService($alias)
{
return $this->biz->service($alias);
}
protected function getAppService()
{
return $this->createService('CloudPlatform:AppService');
}
public function getPurifyAndTrimHtml($html)
{
$html = strip_tags($html, '');
return preg_replace("/(\s|\ \;| |\xc2\xa0)/", '', $html);
}
public function arrayColumn($array, $column)
{
return ArrayToolkit::column($array, $column);
}
private function trans($key, $parameters = [])
{
return $this->container->get('translator')->trans($key, $parameters);
}
public function mb_trim($string, $charlist = '\\\\s', $ltrim = true, $rtrim = true)
{
$bothEnds = $ltrim && $rtrim;
$charClassInner = preg_replace(
['/[\^\-\]\\\]/S', '/\\\{4}/S'],
['\\\\\\0', '\\'],
$charlist
);
$workHorse = '['.$charClassInner.']+';
$ltrim && $leftPattern = '^'.$workHorse;
$rtrim && $rightPattern = $workHorse.'$';
if ($bothEnds) {
$patternMiddle = $leftPattern.'|'.$rightPattern;
} elseif ($ltrim) {
$patternMiddle = $leftPattern;
} else {
$patternMiddle = $rightPattern;
}
return preg_replace("/$patternMiddle/usSD", '', $string);
}
public function wrap($object, $type)
{
return $this->container->get('web.wrapper')->handle($object, $type);
}
public function convertAbsoluteUrl($html)
{
$html = preg_replace_callback('/src=[\'\"]\/(.*?)[\'\"]/', function ($matches) {
$cdn = new CdnUrl();
$cdnUrl = $cdn->get('content');
if (!empty($cdnUrl)) {
$absoluteUrl = AssetHelper::getScheme().':'.rtrim($cdnUrl, '/').'/'.ltrim($matches[1], '/');
} else {
$absoluteUrl = AssetHelper::uriForPath('/'.ltrim($matches[1], '/'));
}
return "src=\"{$absoluteUrl}\"";
}, $html);
return $html;
}
public function getLoginEmailAddress($email)
{
$dress = explode('@', $email);
$dress = strtolower($dress[1]);
$emailAddressMap = [
'gmail.com' => 'mail.google.com',
'vip.qq.com' => 'mail.qq.com',
'vip.163.com' => 'vip.163.com',
'vip.sina.com' => 'mail.sina.com.cn',
'foxmail.com' => 'mail.qq.com',
'hotmail.com' => 'www.hotmail.com',
'188.com' => 'www.188.com',
'139.com' => 'mail.10086.cn',
'126.com' => 'www.126.com',
'yeah.net' => 'yeah.net',
];
if (!empty($emailAddressMap[$dress])) {
return 'http://'.$emailAddressMap[$dress];
}
return 'http://mail.'.$dress;
}
public function getCloudSdkUrl($type)
{
return $this->getResourceFacadeService()->getFrontPlaySDKPathByType($type);
}
public function isWechatLoginBind()
{
$wechat = $this->isMicroMessenger();
$loginBind = $this->getSetting('login_bind');
return $wechat && !empty($loginBind['enabled']) && !empty($loginBind['weixinmob_enabled']);
}
public function makeLocalMediaFileToken($file)
{
$token = $this->makeToken('local.media', $file['id']);
return $token['token'];
}
/**
* 获取在线咨询授权信息
*
* @return array
*/
public function onlineAdvisoryAuthInfo()
{
$info = [
'isCustom' => 'none',
];
try {
$api = CloudAPIFactory::create('root');
$info = $api->get('/me');
$displayLevel = ['personal', 'basic', 'medium', 'advanced', 'gold', 'custom'];
if (is_array($info) && isset($info['level']) && in_array($info['level'], $displayLevel)) {
$info['isCustom'] = ('custom' == $info['level']) ? '是' : '否';
} else {
$info['isCustom'] = 'none';
}
} catch (\RuntimeException $e) {
}
return $info;
}
public function getSyncModeDict()
{
$dict = [
'closed' => $this->trans('admin.sync-account-docking.btn.closed_btn'),
'dingtalk' => $this->trans('admin.sync-account-docking.btn.dingtalk_btn'),
];
if ($this->isPluginInstalled('WorkWechat')) {
$dict['work_wechat'] = $this->trans('admin.sync-account-docking.btn.work_wechat_btn');
}
if ($this->isPluginInstalled('FeiShu')) {
$dict['feishu'] = $this->trans('admin.sync-account-docking.btn.feishu_btn');
}
if ($this->isPluginInstalled('LDAP')) {
$dict['LDAP'] = 'LDAP';
}
return $dict;
}
protected function makeToken($type, $fileId, $context = [])
{
$times = ('local.media' == $type) ? 100 : 10;
$duration = ('local.media' == $type) ? 7200 : 3600;
$fields = [
'data' => [
'id' => $fileId,
],
'times' => $times,
'duration' => $duration,
'userId' => $this->biz['user']['id'],
];
if (isset($context['watchTimeLimit'])) {
$fields['data']['watchTimeLimit'] = $context['watchTimeLimit'];
}
if (isset($context['hideBeginning'])) {
$fields['data']['hideBeginning'] = $context['hideBeginning'];
}
return $this->getTokenService()->makeToken($type, $fields);
}
public function isHiddenVideoHeader($isHidden = false)
{
$storage = $this->getSetting('storage');
if (!empty($storage) && array_key_exists('video_header', $storage) && $storage['video_header'] && !$isHidden) {
return false;
}
return true;
}
public function canSendMessage($userId)
{
$user = $this->biz['user'];
if (!$user->isLogin()) {
return false;
}
if (in_array('ROLE_ADMIN', $user['roles']) || $user->isSuperAdmin()) {
return true;
}
$toUser = $this->getUserService()->getUser($userId);
if ($user['id'] == $toUser['id']) {
return false;
}
if (in_array('ROLE_ADMIN', $toUser['roles']) || in_array('ROLE_SUPER_ADMIN', $toUser['roles'])) {
return true;
}
$messageSetting = $this->getSetting('message', []);
if (empty($messageSetting['teacherToStudent']) && $this->isTeacher($user['roles']) && $this->isOnlyStudent($toUser['roles'])) {
return false;
}
if (empty($messageSetting['studentToStudent']) && $this->isOnlyStudent($user['roles']) && $this->isOnlyStudent($toUser['roles'])) {
return false;
}
if (empty($messageSetting['studentToTeacher']) && $this->isOnlyStudent($user['roles']) && $this->isTeacher($toUser['roles'])) {
return false;
}
return true;
}
public function daysOfWeek($day)
{
$weekName = ['日', '一', '二', '三', '四', '五', '六'];
if (isset($weekName[$day])) {
return $weekName[$day];
}
return false;
}
public function filterArrayKeys($array, $keys)
{
foreach ($keys as $key) {
unset($array[$key]);
}
return $array;
}
public function examScore($score)
{
return $score > 0 ? $score : 0;
}
public function formatLearnTime($learnTime)
{
if ($learnTime < 3600) {
return round($learnTime / 60).$this->trans('site.data.minute');
}
return round($learnTime / 3600, 1).$this->trans('site.date.hour');
}
public function groupBy($array, $key)
{
return ArrayToolkit::group($array, $key);
}
private function isTeacher($roles)
{
return in_array('ROLE_TEACHER', $roles);
}
private function isOnlyStudent($roles)
{
return in_array('ROLE_USER', $roles) && !in_array('ROLE_TEACHER', $roles) && !in_array('ROLE_ADMIN', $roles) && !in_array('ROLE_SUPER_ADMIN', $roles);
}
public function arraysKeyConvert($arrays, $beforeKey, $afterKey)
{
foreach ($arrays as $key => $value) {
if ($value == $beforeKey) {
$arrays[$key][$afterKey] = $arrays[$key][$beforeKey];
unset($arrays[$key][$beforeKey]);
}
}
return $arrays;
}
public function questionHtmlFilter($html, $allowed = '')
{
if (!isset($html)) {
return '';
}
$html = preg_replace('/(<img .*?src=")(.*?)(".*?>)/is', '[图片]', $html);
$security = $this->getSettingService()->get('security');
if (!empty($security['safe_iframe_domains'])) {
$safeDomains = $security['safe_iframe_domains'];
} else {
$safeDomains = [];
}
$config = [
'cacheDir' => $this->biz['cache_directory'].'/htmlpurifier',
'safeIframeDomains' => $safeDomains,
];
$this->warmUp($config['cacheDir']);
$htmlConfig = \HTMLPurifier_Config::createDefault();
$htmlConfig->set('Cache.SerializerPath', $config['cacheDir']);
$htmlConfig->set('HTML.Allowed', $allowed);
$htmlpurifier = new \HTMLPurifier($htmlConfig);
return $htmlpurifier->purify($html);
}
public function uniqid()
{
return MathToolkit::uniqid();
}
public function canOperateQuestion($user, $question)
{
$currentUser = $this->biz['user'];
if ($currentUser->hasPermission('admin_question_gather_manage')) {
return true;
}
if (in_array('ROLE_SUPER_ADMIN', $user['roles'])) {
return true;
}
if (in_array('ROLE_TRAINING_ADMIN', $user['roles']) && $question['createdUserId'] === $user['id']) {
return true;
}
return false;
}
public function showFeedbackBar($route)
{
if (in_array($route, [
'course_teacher_evaluate_list',
'project_plan_create',
'project_plan_offline_course_homework_list',
'survey_result_statistics',
])) {
return true;
}
$allowedRoutes = [
'course_set_manage',
'course_manage',
'classroom_manage',
'offline_course_manage',
'project_plan_study_data',
'questionnaire_manage',
'offline_activity_manage',
'project_plan',
'survey',
'admin',
];
foreach ($allowedRoutes as $allowedRoute) {
if (0 !== stripos($route, $allowedRoute)) {
continue;
}
if (!in_array($allowedRoute, ['project_plan', 'survey'])) {
return true;
}
if (false !== stripos($route, 'manage')) {
return true;
}
}
if (false !== stripos($route, 'verify_list')) {
return true;
}
return false;
}
public function isSaaS()
{
if ($this->isWithoutNetwork()) {
return false;
}
$site = $this->getSetting('site');
if (empty($site['level']) || ($site['levelExpired'] ?? 0) < time()) {
try {
$api = CloudAPIFactory::create('root');
$info = $api->get('/me');
} catch (\RuntimeException $e) {
$info = [];
}
$site['level'] = $info['level'] ?? '';
$site['levelExpired'] = time() + 7200;
$this->getSettingService()->set('site', $site);
}
return in_array($this->getSetting('site.level'), $this->getSaaSLevels());
}
public function getSaaSLevels()
{
return ['personal', 'basic', 'medium', 'advanced', 'ct-basic', 'ct-standard', 'ct-professional', 'ct-flagship'];
}
public function getRememberMeDeadlineRangeText()
{
$rememberMeLifetime = LoginToolkit::getRememberMeLifetime();
if ($rememberMeLifetime < 60 * 60) {
return (int) ($rememberMeLifetime / 60).$this->trans('site.data.minute');
}
if ($rememberMeLifetime < 24 * 60 * 60) {
return (int) ($rememberMeLifetime / (60 * 60)).$this->trans('site.date.hour');
}
return (int) ($rememberMeLifetime / (24 * 60 * 60)).$this->trans('site.date.day');
}
protected function warmUp($cacheDir)
{
if (!@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
throw new ServiceException('mkdir cache dir error');
}
if (!is_writable($cacheDir)) {
chmod($cacheDir, 0777);
}
}
protected function getSettingService()
{
return $this->biz->service('System:SettingService');
}
/**
* @return ResourceFacadeService
*/
protected function getResourceFacadeService()
{
return $this->createService('CloudPlatform:ResourceFacadeService');
}
/**
* @return TagService
*/
protected function getTagService()
{
return $this->createService('Taxonomy:TagService');
}
/**
* @return TokenService
*/
protected function getTokenService()
{
return $this->createService('User:TokenService');
}
/**
* @return mixed
*/
public function getCategoryService()
{
return $this->createService('Taxonomy:CategoryService');
}
/**
* @return ReviewCenterService
*/
protected function getReviewCenterService()
{
return $this->createService('ReviewCenter:ReviewCenterService');
}
}