mirror of
https://github.com/typecho/typecho.git
synced 2025-03-20 09:59:41 +01:00
Merge commit '9d1b01a8736ab1ce39e9e2e666a2f992eba28b0f' into dev
This commit is contained in:
commit
38562bab48
27
.github/workflows/Typecho-release-Ci.yml
vendored
27
.github/workflows/Typecho-release-Ci.yml
vendored
@ -1,14 +1,14 @@
|
||||
name: Typecho Build Release Ci
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
@ -17,27 +17,14 @@ jobs:
|
||||
chmod 755 build/usr/uploads/
|
||||
rm -rf build/admin/src
|
||||
cd build && zip -q -r typecho.zip * && mv typecho.zip ../ && cd -
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ github.ref }}
|
||||
draft: true
|
||||
prerelease: false
|
||||
- name: Upload Release Asset
|
||||
id: upload-release-asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: shogo82148/actions-upload-release-asset@v1
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: ./typecho.zip
|
||||
asset_name: typecho.zip
|
||||
asset_content_type: application/zip
|
||||
- name: Trigger langs build
|
||||
- name: Trigger language build
|
||||
run: |
|
||||
curl -XPOST -H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \
|
||||
-H "Accept: application/vnd.github.everest-preview+json" \
|
||||
|
@ -9,8 +9,8 @@ $defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaul
|
||||
class="i-caret-right"></i> <?php _e('自定义字段'); ?></a></label>
|
||||
<table class="typecho-list-table mono">
|
||||
<colgroup>
|
||||
<col width="25%"/>
|
||||
<col width="10%"/>
|
||||
<col width="20%"/>
|
||||
<col width="15%"/>
|
||||
<col width="55%"/>
|
||||
<col width="10%"/>
|
||||
</colgroup>
|
||||
@ -37,12 +37,14 @@ $defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaul
|
||||
value="int"<?php if ('int' == $field['type']): ?> selected<?php endif; ?>><?php _e('整数'); ?></option>
|
||||
<option
|
||||
value="float"<?php if ('float' == $field['type']): ?> selected<?php endif; ?>><?php _e('小数'); ?></option>
|
||||
<option
|
||||
value="json"<?php if ('json' == $field['type']): ?> selected<?php endif; ?>><?php _e('JSON 结构'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
|
||||
<textarea name="fieldValues[]" id="fieldvalue" class="text-s w-100"
|
||||
rows="2"><?php echo htmlspecialchars($field[$field['type'] . '_value']); ?></textarea>
|
||||
rows="2"><?php echo htmlspecialchars($field[($field['type'] == 'json' ? 'str' : $field['type']) . '_value']); ?></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
|
||||
|
@ -131,7 +131,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
|
||||
<div class="comment-meta">
|
||||
<strong class="comment-author"><?php $comments->author(true); ?></strong>
|
||||
<?php if($comments->mail): ?>
|
||||
<br /><span><a href="mailto:<?php $comments->mail(); ?>"><?php $comments->mail(); ?></a></span>
|
||||
<br /><span><a href="<?php $comments->mail(true); ?>"><?php $comments->mail(); ?></a></span>
|
||||
<?php endif; ?>
|
||||
<?php if($comments->ip): ?>
|
||||
<br /><span><?php $comments->ip(); ?></span>
|
||||
|
10
install.php
10
install.php
@ -1031,8 +1031,7 @@ function install_step_2_perform()
|
||||
->addRule('dbFile', 'required', _t('确认您的配置'))
|
||||
->addRule('dbFile', function (string $path) {
|
||||
$pattern = "/^(\/[._a-z0-9-]+)*[a-z0-9]+\.[a-z0-9]{2,}$/i";
|
||||
if (strstr(PHP_OS, 'WIN'))
|
||||
{
|
||||
if (strstr(PHP_OS, 'WIN')) {
|
||||
$pattern = "/(\/[._a-z0-9-]+)*[a-z0-9]+\.[a-z0-9]{2,}$/i";
|
||||
}
|
||||
return !!preg_match($pattern, $path);
|
||||
@ -1077,7 +1076,12 @@ function install_step_2_perform()
|
||||
$installDb->addServer($dbConfig, \Typecho\Db::READ | \Typecho\Db::WRITE);
|
||||
$installDb->query('SELECT 1=1');
|
||||
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
|
||||
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装: "%s"', $e->getMessage()));
|
||||
$code = $e->getCode();
|
||||
if (('Mysql' == $type && 1049 == $code) || ('Pgsql' == $type && 7 == $code)) {
|
||||
install_raise_error(_t('数据库: "%s"不存在,请手动创建后重试', $config['dbDatabase']));
|
||||
} else {
|
||||
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装: "%s"', $e->getMessage()));
|
||||
}
|
||||
} catch (\Typecho\Db\Exception $e) {
|
||||
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ namespace Typecho {
|
||||
$isPlugin = false;
|
||||
|
||||
// detect if class is predefined
|
||||
if (strpos($className, '\\') !== false) {
|
||||
if ($isNamespace) {
|
||||
$isPlugin = strpos(ltrim($className, '\\'), PLUGIN_NAMESPACE . '\\') !== false;
|
||||
|
||||
if ($isPlugin) {
|
||||
|
@ -96,7 +96,8 @@ class Validate
|
||||
*/
|
||||
public static function email(string $str): bool
|
||||
{
|
||||
return filter_var($str, FILTER_VALIDATE_EMAIL) !== false;
|
||||
$email = filter_var($str, FILTER_SANITIZE_EMAIL);
|
||||
return !!filter_var($str, FILTER_VALIDATE_EMAIL) && ($email === $str);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,10 +111,8 @@ class Validate
|
||||
*/
|
||||
public static function url(string $str): bool
|
||||
{
|
||||
return filter_var(
|
||||
$str,
|
||||
FILTER_VALIDATE_URL
|
||||
) !== false;
|
||||
$url = Common::safeUrl($str);
|
||||
return !!filter_var($str, FILTER_VALIDATE_URL) && ($url === $str);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,7 +217,7 @@ abstract class Element extends Layout
|
||||
public function value($value): Element
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->inputValue($value);
|
||||
$this->inputValue($value ?? '');
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class Checkbox extends Element
|
||||
*/
|
||||
protected function inputValue($value)
|
||||
{
|
||||
$values = is_array($value) ? $value : [$value];
|
||||
$values = is_null($value) ? [] : (is_array($value) ? $value : [$value]);
|
||||
|
||||
foreach ($this->options as $option) {
|
||||
$option->removeAttribute('checked');
|
||||
|
@ -918,7 +918,7 @@ class Archive extends Contents
|
||||
*/
|
||||
public function related(int $limit = 5, ?string $type = null): Contents
|
||||
{
|
||||
$type = strtolower($type);
|
||||
$type = strtolower($type ?? '');
|
||||
|
||||
switch ($type) {
|
||||
case 'author':
|
||||
|
@ -306,6 +306,18 @@ class Comments extends Base implements QueryInterface
|
||||
echo Common::subStr(strip_tags($this->content), 0, $length, $trim);
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出邮箱地址
|
||||
*
|
||||
* @param bool $link
|
||||
* @return void
|
||||
*/
|
||||
public function mail(bool $link = false)
|
||||
{
|
||||
$mail = htmlspecialchars($this->mail);
|
||||
echo $link ? 'mailto:' . $mail : $mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询对象
|
||||
*
|
||||
|
@ -346,41 +346,42 @@ class Contents extends Base implements QueryInterface
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $value
|
||||
* @param mixed $value
|
||||
* @param integer $cid
|
||||
* @return integer|bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function setField(string $name, string $type, string $value, int $cid)
|
||||
public function setField(string $name, string $type, $value, int $cid)
|
||||
{
|
||||
if (
|
||||
empty($name) || !$this->checkFieldName($name)
|
||||
|| !in_array($type, ['str', 'int', 'float'])
|
||||
|| !in_array($type, ['str', 'int', 'float', 'json'])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($type === 'json') {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
|
||||
$exist = $this->db->fetchRow($this->db->select('cid')->from('table.fields')
|
||||
->where('cid = ? AND name = ?', $cid, $name));
|
||||
|
||||
$rows = [
|
||||
'type' => $type,
|
||||
'str_value' => 'str' == $type || 'json' == $type ? $value : null,
|
||||
'int_value' => 'int' == $type ? intval($value) : 0,
|
||||
'float_value' => 'float' == $type ? floatval($value) : 0
|
||||
];
|
||||
|
||||
if (empty($exist)) {
|
||||
return $this->db->query($this->db->insert('table.fields')
|
||||
->rows([
|
||||
'cid' => $cid,
|
||||
'name' => $name,
|
||||
'type' => $type,
|
||||
'str_value' => 'str' == $type ? $value : null,
|
||||
'int_value' => 'int' == $type ? intval($value) : 0,
|
||||
'float_value' => 'float' == $type ? floatval($value) : 0
|
||||
]));
|
||||
$rows['cid'] = $cid;
|
||||
$rows['name'] = $name;
|
||||
|
||||
return $this->db->query($this->db->insert('table.fields')->rows($rows));
|
||||
} else {
|
||||
return $this->db->query($this->db->update('table.fields')
|
||||
->rows([
|
||||
'type' => $type,
|
||||
'str_value' => 'str' == $type ? $value : null,
|
||||
'int_value' => 'int' == $type ? intval($value) : 0,
|
||||
'float_value' => 'float' == $type ? floatval($value) : 0
|
||||
])
|
||||
->rows($rows)
|
||||
->where('cid = ? AND name = ?', $cid, $name));
|
||||
}
|
||||
}
|
||||
@ -872,7 +873,8 @@ class Contents extends Base implements QueryInterface
|
||||
->where('cid = ?', $this->cid));
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$fields[$row['name']] = $row[$row['type'] . '_value'];
|
||||
$value = 'json' == $row['type'] ? json_decode($row['str_value'], true) : $row[$row['type'] . '_value'];
|
||||
$fields[$row['name']] = $value;
|
||||
}
|
||||
|
||||
return new Config($fields);
|
||||
|
@ -229,8 +229,14 @@ class Edit extends Contents implements ActionInterface
|
||||
if (preg_match("/^fields\[(.+)\]$/", $name, $matches)) {
|
||||
$name = $matches[1];
|
||||
} else {
|
||||
$inputName = 'fields[' . $name . ']';
|
||||
if (preg_match("/^(.+)\[\]$/", $name, $matches)) {
|
||||
$name = $matches[1];
|
||||
$inputName = 'fields[' . $name . '][]';
|
||||
}
|
||||
|
||||
foreach ($item->inputs as $input) {
|
||||
$input->setAttribute('name', 'fields[' . $name . ']');
|
||||
$input->setAttribute('name', $inputName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,8 +668,8 @@ class Edit extends Contents implements ActionInterface
|
||||
}
|
||||
|
||||
$customFields = $this->request->getArray('fields');
|
||||
if (!empty($customFields)) {
|
||||
$fields = array_merge($fields, $customFields);
|
||||
foreach ($customFields as $key => $val) {
|
||||
$fields[$key] = [is_array($val) ? 'json' : 'str', $val];
|
||||
}
|
||||
|
||||
return $fields;
|
||||
|
@ -71,7 +71,9 @@ class Config extends BaseOptions
|
||||
|
||||
if (!empty($inputs)) {
|
||||
foreach ($inputs as $key => $val) {
|
||||
$form->getInput($key)->value($this->options->{$key});
|
||||
if (isset($this->options->{$key})) {
|
||||
$form->getInput($key)->value($this->options->{$key});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user