Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions DEVTOOLS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Additional development tools

Various components used within Textpattern (such as the bundled themes and language translations) are maintained in other repositories. Textpattern has a simple development toolset built on [Node.js](https://nodejs.org/) to pull the distribution files of those repositories into the core as required.

You can install Node.js using the [installer](https://nodejs.org/en/download/) or [package manager](https://nodejs.org/en/download/package-manager/).

Install required dev tools:

```ShellSession
npm install
```

Pull the following components from the CLI:

```ShellSession
npm run get-default-theme
npm run get-classic-admin-theme
npm run get-hive-admin-theme
npm run get-pophelp
npm run get-textpacks
npm run get-dependencies
```

To request a specific tag or branch:

```ShellSession
npm run get-default-theme 4.9.0
npm run get-classic-admin-theme 4.9.0
npm run get-classic-admin-theme 4.9.x
npm run get-hive-admin-theme 4.9.x
npm run get-textpacks 4.9.x
```

Release tools:

Usage: `npm run txp-gitdist <version> [dest-dir]` (`dest-dir` defaults to a temporary location).

```ShellSession
npm run txp-index
npm run txp-checksums ./textpattern
npm run txp-gitdist 1.2.3 ../my-dest-dir
```
122 changes: 72 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,93 +1,115 @@
# Textpattern CMS

[![Textpattern Logo](https://textpattern.io/assets/img/branding/carver/carver-128px.svg)](http://textpattern.com/)
[![Crowdin](https://badges.crowdin.net/textpattern-cms-textpacks/localized.svg)](https://crowdin.com/project/textpattern-cms-textpacks)
[![Known Vulnerabilities](https://snyk.io/test/github/textpattern/textpattern/badge.svg)](https://snyk.io/test/github/textpattern/textpattern/)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/textpattern)](https://github.com/sponsors/textpattern)

**A flexible, elegant and easy-to-use content management system.**
<img src="https://textpattern.com/assets/img/branding/carver/carver.svg" alt="Textpattern Logo" width="128" height="128">

Textpattern is [free and open source](#legal) software.
**A flexible, elegant, fast and easy-to-use content management system written in PHP.** Textpattern is [free and open source](#legal) software.

* [System requirements](#system-requirements)
* [Download Textpattern](#download-textpattern)
* [Install Textpattern](#install-textpattern)
* [Upgrade Textpattern](#upgrade-textpattern)
* [Help and Support](#help-and-support)
* [Development](#development)
* [Contributing](#contributing)
* [Thank you](#thank-you)
* [Legal](#legal)

![Textpattern CMS screenshots](https://textpattern.com/assets/img/com/readme-device-screens.png)

## System requirements

Textpattern is installed to a web server with PHP and MySQL.

Ensure the server meets or exceeds the
[system requirements](http://textpattern.com/about/119/system-requirements)
before you continue.
Ensure the server meets or exceeds the [system requirements](https://textpattern.com/system-requirements) before you continue.

## Download Textpattern

### Production release
The current production release is version 4.9.0. It can be downloaded from the Textpattern website or GitHub in .zip, .tar.gz, and .tar.xz varieties.

The current production release is version 4.6.2. It can be downloaded from the
Textpattern website as a
[.zip](http://textpattern.com/latest.zip) or
[.tar.gz](http://textpattern.com/latest.tar.gz) archive.
If you want to use the multi-site functionality in Textpattern, get the .tar.gz or .tar.xz archive.

### Development version
| | textpattern.com | GitHub |
|--------|:-------:|:-----:|
| .zip | [Download](https://textpattern.com/file_download/124/textpattern-4.9.0.zip) | [Download](https://github.com/textpattern/textpattern/releases/download/4.9.0/textpattern-4.9.0.zip) |
| .tar.gz | [Download](https://textpattern.com/file_download/125/textpattern-4.9.0.tar.gz) | [Download](https://github.com/textpattern/textpattern/releases/download/4.9.0/textpattern-4.9.0.tar.gz) |
| .tar.xz | [Download](https://textpattern.com/file_download/126/textpattern-4.9.0.tar.xz) | [Download](https://github.com/textpattern/textpattern/releases/download/4.9.0/textpattern-4.9.0.tar.xz) |

The development version can be obtained from the [Textpattern repository on
GitHub](https://github.com/textpattern/textpattern). Note that development
versions are works-in-progress and not recommended for use on live production
servers.

## Install Textpattern

Please see
[README.txt](https://github.com/textpattern/textpattern/blob/master/README.txt)
for details on installing Textpattern.
Please see [README.txt](https://github.com/textpattern/textpattern/blob/main/README.txt) for details on installing Textpattern.

## Upgrade Textpattern

Please see
[README.txt](https://github.com/textpattern/textpattern/blob/master/README.txt)
for details on upgrading Textpattern.
Please see [UPGRADE.txt](https://github.com/textpattern/textpattern/blob/main/UPGRADE.txt) for details on upgrading Textpattern.

## Help and Support

The [Textpattern support forum](https://forum.textpattern.com) is home to a friendly and helpful community of Textpattern users and experts. Textpattern also has a social network presence on [Mastodon](https://textpattern.com/mastodon) and [X](https://textpattern.com/x).

## Development

The development snapshot can be obtained from the [Textpattern repository on GitHub](https://github.com/textpattern/textpattern).

### Anticipated changes to future system requirements

As a development version approaches release, minimum and recommended system requirements are confirmed and the production release system requirements is updated accordingly.

The following table outlines anticipated forthcoming changes to system requirements. It takes into account vendor support, security considerations, overall performance and other factors. Note that minimum and/or recommended versions listed may change multiple times during the development process.

#### Textpattern development versions

We are targeting Textpattern 5 as the next major release. Refer to the following table for anticipated changes to system requirements for Textpattern 5.

## Help and support
We generally recommend running Textpattern on platforms with active vendor support where possible, though we also maintain a minimum system requirements list for situations where that isn't viable.

The [Textpattern support forum](https://forum.textpattern.io) is home to
a friendly and helpful community of Textpattern users and experts.
Textpattern also has social network presences on
[Twitter](http://textpattern.com/@textpattern),
[Facebook](http://textpattern.com/facebook) and
[Google+](http://textpattern.com/+).
Note that versions listed may change multiple times during the development process.

| | Minimum | Recommended |
|--------|:-------:|:-----:|
| PHP | &mdash; | [vendor supported](https://php.net/supported-versions.php) |
| MySQL | &mdash; | [vendor supported LTS](https://www.mysql.com/support/supportedplatforms/database.html) |
| Apache | &mdash; | vendor supported |
| Nginx | &mdash; | mainline or stable |

## Contributing

Want to help out with the development of Textpattern CMS? Please refer to the
[Contributing documentation](https://docs.textpattern.io/development/contributing)
for full details.
Please refer to the [contributing documentation](https://github.com/textpattern/textpattern/blob/dev/CONTRIBUTING.md) for more details of Textpattern development.

## Additional development tools

Please refer to the [additional devevelopment tools](https://github.com/textpattern/textpattern/blob/dev/DEVTOOLS.md) document.

## GitHub topic tags

If you use GitHub for Textpattern-related development please consider adding
some of the following [topic](https://help.github.com/articles/about-topics/)
keywords to your public project repositories, so we can build a network of
discoverable resources:
If you use GitHub for Textpattern-related development please consider adding some of the following [topic](https://help.github.com/articles/about-topics/) keywords to your public project repositories, so we can expand the network of discoverable resources:

* [`textpattern`](https://github.com/topics/textpattern)
* [`textpattern-plugin`](https://github.com/topics/textpattern-plugin)
* [`textpattern-theme`](https://github.com/topics/textpattern-theme)
* [`textpattern-website`](https://github.com/topics/textpattern-website) (for websites built with Textpattern)
* [`textpattern-development`](https://github.com/topics/textpattern-development) (for development resources)

## Thank You

* `textpattern`
* `textpattern-plugin`
* `textpattern-theme`
* `textpattern-website` (for websites built with Textpattern)
* `textpattern-development` (for development resources)
Thank you to our [GitHub sponsors](https://github.com/sponsors/textpattern). Your continued support is greatly appreciated!

We are grateful to [DigitalOcean](https://www.digitalocean.com/?utm_source=opensource&utm_campaign=textpattern), [BrowserStack](https://www.browserstack.com) and [1Password](https://1password.com) for their kind considerations in supporting Textpattern CMS development by way of web hosting infrastructure (DigitalOcean), cross-browser testing platform (BrowserStack) and secure password management (1Password). Thank you!

This project is supported by:

<a href="https://www.digitalocean.com/?utm_source=opensource&utm_campaign=textpattern"><img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="201px"></a>

## Legal

Released under the GNU General Public License. See
[LICENSE.txt](https://github.com/textpattern/textpattern/blob/master/LICENSE.txt)
for terms and conditions.
Released under the GNU General Public License. See [LICENSE.txt](https://github.com/textpattern/textpattern/blob/main/LICENSE.txt) for terms and conditions.

Includes contributions licensed under the GNU Lesser General Public License. See [LICENSE-LESSER.txt](https://github.com/textpattern/textpattern/blob/main/textpattern/lib/LICENSE-LESSER.txt) for terms and conditions.

Includes contributions licensed under the GNU Lesser General Public License. See
[LICENSE-LESSER.txt](https://github.com/textpattern/textpattern/blob/dev/textpattern/lib/LICENSE-LESSER.txt)
for terms and conditions.
Includes contributions licensed under the New BSD License. See [LICENSE-BSD-3.txt](https://github.com/textpattern/textpattern/blob/main/textpattern/lib/LICENSE-BSD-3.txt) for terms and conditions.

Includes contributions licensed under the New BSD License. See
[LICENSE-BSD-3.txt](https://github.com/textpattern/textpattern/blob/dev/textpattern/lib/LICENSE-BSD-3.txt)
for terms and conditions.
![Textpattern CMS blogging illustration](https://textpattern.com/assets/img/com/readme-footer.png)
41 changes: 37 additions & 4 deletions textpattern/lib/txplib_misc.php
Original file line number Diff line number Diff line change
Expand Up @@ -5027,21 +5027,54 @@ function getCustomFields()
* Build a query qualifier to filter non-matching custom fields from the
* result set.
*
* @param array $custom An array of 'custom_field_name' => field_number tupels
* @param array $pairs Filter criteria: An array of 'name' => value tupels
* @param array $custom An array of 'custom_field_name' => field_number tupels
* @param array $pairs Filter criteria: An array of 'name' => value tupels
* @param string $match Match criteria: 'name1,name2[1|3]'
* @return bool|string An SQL qualifier for a query's 'WHERE' part
* @package CustomField
*/

function buildCustomSql($custom, $pairs)
function buildCustomSql($custom, $pairs, $match = null)
{
if ($pairs) {
$pairs = doSlash($pairs);
$match = $match ? do_list_unique($match) : array();
$sep = doSlash(',');

foreach ($pairs as $k => $v) {
if (in_array($k, $custom)) {
$no = array_keys($custom, $k);
$out[] = "and custom_".$no[0]." like '$v'";
$custom_n = 'custom_'.$no[0];
$val = do_list($v, $sep);
$matched = false;

foreach ($match as $chunk) {
if (preg_match("/^{$k}\[(.*)\]$/", $chunk, $matches)) {
$matched = true;
$var = array();
$neg = '';

switch ($matches[1]) {
case 0 : $neg = 'NOT';
case '' :
foreach ($val as $item) {
$var[] = "CONCAT('".$sep."', {$custom_n}, '".$sep."') LIKE '%{$sep}{$item}{$sep}%'";
}
break;
default :
$ind = array_map('intval', do_list_unique($matches[1], '|'));
foreach ($ind as $i) {
if (isset($val[$j = abs($i)-1])) {
$var[] = ($i < 0 ? 'NOT ' : '')."CONCAT('".$sep."', {$custom_n}, '".$sep."') LIKE '%{$sep}{$val[$j]}{$sep}%'";
}
}
}

$out[] = "AND $neg (".implode(' OR ', $var).")";
}
}

if (empty($matched)) $out[] = "AND {$custom_n} LIKE '$v'";
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion textpattern/publish.php
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ function doArticles($atts, $iscustom, $thing = null)
}

if (!empty($customPairs)) {
$custom = buildCustomSql($customFields, $customPairs);
$custom = buildCustomSql($customFields, $customPairs, $atts['match']);
}
}

Expand Down
23 changes: 19 additions & 4 deletions textpattern/publish/taghandlers.php
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,7 @@ function recent_comments($atts, $thing = null)
function related_articles($atts, $thing = null)
{
global $thisarticle, $prefs;
static $fields = null;

assert_article();

Expand All @@ -1055,7 +1056,12 @@ function related_articles($atts, $thing = null)
'wraptag' => '',
), $atts);

$match = array_intersect(do_list_unique(strtolower($atts['match'])), array_merge(array('category1', 'category2', 'author', 'keywords'), getCustomFields()));
if (!isset($fields)) {
$fields = array_merge(array('category1', 'category2', 'author', 'keywords'), getCustomFields());
}

$match = do_list_unique(strtolower($atts['match']));
$matches = array_intersect($match, $fields);
$categories = $cats = array();

foreach ($match as $cf) {
Expand All @@ -1072,6 +1078,8 @@ function related_articles($atts, $thing = null)
$atts['author'] = $thisarticle['authorid'];
break;
default:
$cf = strtok($cf, '[');

if (empty($thisarticle[$cf])) {
return;
}
Expand All @@ -1087,7 +1095,7 @@ function related_articles($atts, $thing = null)
return;
}

$atts['match'] = implode(',', $categories);
$atts['match'] = implode(',', array_merge(array_diff($match, $fields), $categories));
$atts['exclude'] = $thisarticle['thisid'];

if ($atts['form'] === '' && $thing === null) {
Expand Down Expand Up @@ -4132,7 +4140,8 @@ function custom_field($atts)

extract(lAtts(array(
'name' => get_pref('custom_1_set'),
'escape' => 'html',
'item' => null,
'escape' => null,
'default' => '',
), $atts));

Expand All @@ -4152,9 +4161,15 @@ function custom_field($atts)

$was_article_body = $is_article_body;
$is_article_body = 1;
$out = ($escape == 'html' ? txpspecialchars($out) : parse($out));
$out = ($escape === null ? txpspecialchars($out) : parse($out));
$is_article_body = $was_article_body;

if (isset($item)) {
$item = intval($item) - 1;
$out = do_list($out);
$out = isset($out[$item]) ? $out[$item] : false;
}

return $out;
}

Expand Down