Skip to content

Commit 2fe3ee4

Browse files
committed
By EbraSha
1 parent 7de36f4 commit 2fe3ee4

8 files changed

Lines changed: 498 additions & 4 deletions

File tree

README.fa.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ composer require abdal/phpian-render
8080
```json
8181
{
8282
"require": {
83-
"abdal/phpian-render": "^1.0"
83+
"abdal/phpian-render": "^1.1"
8484
}
8585
}
8686
```
@@ -216,6 +216,40 @@ if (!$renderer->isRTL($text2)) {
216216
}
217217
```
218218

219+
### استفاده از Static Methods (بدون نیاز به ایجاد نمونه)
220+
221+
```php
222+
<?php
223+
224+
use Abdal\PhpianRender\PhpianRender;
225+
226+
// استفاده از متدهای static بدون نیاز به ایجاد نمونه
227+
$text = 'سلام دنیا';
228+
229+
// پردازش کامل
230+
$processed = PhpianRender::processStatic($text, [
231+
'reshape' => true,
232+
'bidi' => true,
233+
'convertNumbers' => true,
234+
]);
235+
236+
// Reshape
237+
$reshaped = PhpianRender::reshapeStatic($text);
238+
239+
// تبدیل اعداد
240+
$converted = PhpianRender::convertNumbersStatic('عدد 123', 'persian');
241+
242+
// تشخیص RTL
243+
$isRTL = PhpianRender::isRTLStatic($text);
244+
245+
// Word Wrap
246+
$wrapped = PhpianRender::wordWrapStatic('متن طولانی', 20);
247+
248+
// دریافت نسخه پکیج
249+
$version = PhpianRender::getVersion();
250+
echo "Version: $version";
251+
```
252+
219253
### استفاده از کلاس‌های مستقل
220254

221255
```php

README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Or add to `composer.json`:
8080
```json
8181
{
8282
"require": {
83-
"abdal/phpian-render": "^1.0"
83+
"abdal/phpian-render": "^1.1"
8484
}
8585
}
8686
```
@@ -216,6 +216,40 @@ if (!$renderer->isRTL($text2)) {
216216
}
217217
```
218218

219+
### Using Static Methods (No Instance Required)
220+
221+
```php
222+
<?php
223+
224+
use Abdal\PhpianRender\PhpianRender;
225+
226+
// Use static methods without creating an instance
227+
$text = 'سلام دنیا';
228+
229+
// Full processing
230+
$processed = PhpianRender::processStatic($text, [
231+
'reshape' => true,
232+
'bidi' => true,
233+
'convertNumbers' => true,
234+
]);
235+
236+
// Reshape
237+
$reshaped = PhpianRender::reshapeStatic($text);
238+
239+
// Convert numbers
240+
$converted = PhpianRender::convertNumbersStatic('عدد 123', 'persian');
241+
242+
// RTL detection
243+
$isRTL = PhpianRender::isRTLStatic($text);
244+
245+
// Word wrap
246+
$wrapped = PhpianRender::wordWrapStatic('متن طولانی', 20);
247+
248+
// Get package version
249+
$version = PhpianRender::getVersion();
250+
echo "Version: $version";
251+
```
252+
219253
### Using Standalone Classes
220254

221255
```php

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "abdal/phpian-render",
33
"description": "Comprehensive PHP package for Persian/Arabic text rendering in graphical environments with RTL support",
44
"type": "library",
5+
"version": "1.2.0",
56
"keywords": [
67
"persian",
78
"arabic",

examples/basic-usage.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,27 @@
7878
'clean' => true,
7979
]);
8080
echo "Original: $text\n";
81-
echo "Fully Processed: $processed\n";
81+
echo "Fully Processed: $processed\n\n";
82+
83+
// Example 8: Static method calls (no need to instantiate)
84+
echo "=== Example 8: Static Method Calls ===\n";
85+
$text = 'سلام دنیا';
86+
87+
// Using static methods directly
88+
$processed = PhpianRender::processStatic($text);
89+
echo "Static Process: $processed\n";
90+
91+
$reshaped = PhpianRender::reshapeStatic($text);
92+
echo "Static Reshape: $reshaped\n";
93+
94+
$isRTL = PhpianRender::isRTLStatic($text) ? 'Yes' : 'No';
95+
echo "Static IsRTL: $isRTL\n";
96+
97+
$converted = PhpianRender::convertNumbersStatic('عدد 123', 'persian');
98+
echo "Static Convert: $converted\n\n";
99+
100+
// Example 9: Get version
101+
echo "=== Example 9: Get Version ===\n";
102+
$version = PhpianRender::getVersion();
103+
echo "Package Version: $version\n";
82104

src/PhpianRender.php

Lines changed: 174 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
/**
2323
* PhpianRender main class
2424
* Provides a unified interface for all RTL text processing features
25+
* Supports both instance and static method calls
2526
*/
2627
class PhpianRender
2728
{
@@ -31,6 +32,11 @@ class PhpianRender
3132
private DiacriticsHandler $diacriticsHandler;
3233
private Helper $helper;
3334

35+
/**
36+
* Static instance for static method calls
37+
*/
38+
private static ?PhpianRender $staticInstance = null;
39+
3440
/**
3541
* Constructor
3642
*/
@@ -43,6 +49,19 @@ public function __construct()
4349
$this->helper = new Helper();
4450
}
4551

52+
/**
53+
* Get or create static instance
54+
*
55+
* @return PhpianRender
56+
*/
57+
private static function getStaticInstance(): PhpianRender
58+
{
59+
if (self::$staticInstance === null) {
60+
self::$staticInstance = new self();
61+
}
62+
return self::$staticInstance;
63+
}
64+
4665
/**
4766
* Process text with all RTL features
4867
*
@@ -59,6 +78,7 @@ public function process(string $text, array $options = []): string
5978
'numberLocale' => 'persian', // 'persian' or 'arabic'
6079
'preserveDiacritics' => true,
6180
'clean' => false,
81+
'reverse' => true, // Reverse text for RTL display (like PersianRender)
6282
];
6383

6484
$options = array_merge($defaultOptions, $options);
@@ -77,6 +97,9 @@ public function process(string $text, array $options = []): string
7797
$diacritics = $extracted['diacritics'];
7898
}
7999

100+
// Check if text is mixed (RTL + LTR) or pure RTL
101+
$isMixed = $this->isMixedText($text);
102+
80103
// Reshape characters
81104
$reshapedText = $text;
82105
if ($options['reshape']) {
@@ -94,8 +117,17 @@ public function process(string $text, array $options = []): string
94117
}
95118

96119
// Process bidirectional text
120+
// For mixed texts (RTL + LTR), use BiDi algorithm
121+
// For pure RTL texts, just reverse the entire text (like PersianRender)
97122
if ($options['bidi']) {
98-
$text = $this->bidi->process($text);
123+
if ($isMixed) {
124+
// Mixed text: use BiDi algorithm
125+
$text = $this->bidi->process($text);
126+
} elseif ($options['reverse'] && $this->helper->isRTL($text)) {
127+
// Pure RTL text: reverse entire text (like PersianRender.php)
128+
$chars = mb_str_split($text, 1, 'UTF-8');
129+
$text = implode('', array_reverse($chars));
130+
}
99131
}
100132

101133
// Convert numbers
@@ -109,6 +141,64 @@ public function process(string $text, array $options = []): string
109141
return $text;
110142
}
111143

144+
/**
145+
* Check if text contains both RTL and LTR characters
146+
*
147+
* @param string $text Input text
148+
* @return bool True if text is mixed
149+
*/
150+
private function isMixedText(string $text): bool
151+
{
152+
$hasRTL = false;
153+
$hasLTR = false;
154+
$chars = mb_str_split($text, 1, 'UTF-8');
155+
156+
foreach ($chars as $char) {
157+
if (ctype_space($char) || ctype_punct($char)) {
158+
continue;
159+
}
160+
161+
// Check if it's RTL
162+
$codePoint = $this->getCharCodePoint($char);
163+
if (($codePoint >= 0x0590 && $codePoint <= 0x08FF) ||
164+
($codePoint >= 0x0600 && $codePoint <= 0x06FF) ||
165+
in_array($codePoint, [0x067E, 0x0686, 0x06AF, 0x0698])) {
166+
$hasRTL = true;
167+
} else {
168+
// Check if it's LTR (Latin characters or numbers)
169+
if (($codePoint >= 0x0041 && $codePoint <= 0x007A) ||
170+
($codePoint >= 0x0030 && $codePoint <= 0x0039)) {
171+
$hasLTR = true;
172+
}
173+
}
174+
175+
if ($hasRTL && $hasLTR) {
176+
return true;
177+
}
178+
}
179+
180+
return false;
181+
}
182+
183+
/**
184+
* Get Unicode code point of a character
185+
*
186+
* @param string $char Character
187+
* @return int Code point
188+
*/
189+
private function getCharCodePoint(string $char): int
190+
{
191+
$bytes = unpack('C*', mb_convert_encoding($char, 'UTF-32BE', 'UTF-8'));
192+
if (empty($bytes)) {
193+
return 0;
194+
}
195+
$codePoint = 0;
196+
foreach ($bytes as $byte) {
197+
$codePoint = ($codePoint << 8) | $byte;
198+
}
199+
return $codePoint;
200+
}
201+
112202
/**
113203
* Reshape text only
114204
*
@@ -217,5 +307,88 @@ public function getHelper(): Helper
217307
{
218308
return $this->helper;
219309
}
310+
311+
/**
312+
* Get package version
313+
*
314+
* @return string Package version
315+
*/
316+
public static function getVersion(): string
317+
{
318+
return Version::getVersion();
319+
}
320+
321+
// ========== Static Methods ==========
322+
323+
/**
324+
* Process text with all RTL features (static)
325+
*
326+
* @param string $text Input text
327+
* @param array $options Processing options
328+
* @return string Processed text
329+
*/
330+
public static function processStatic(string $text, array $options = []): string
331+
{
332+
return self::getStaticInstance()->process($text, $options);
333+
}
334+
335+
/**
336+
* Reshape text only (static)
337+
*
338+
* @param string $text Input text
339+
* @return string Reshaped text
340+
*/
341+
public static function reshapeStatic(string $text): string
342+
{
343+
return self::getStaticInstance()->reshape($text);
344+
}
345+
346+
/**
347+
* Process bidirectional text only (static)
348+
*
349+
* @param string $text Input text
350+
* @return string Processed text
351+
*/
352+
public static function processBiDiStatic(string $text): string
353+
{
354+
return self::getStaticInstance()->processBiDi($text);
355+
}
356+
357+
/**
358+
* Convert numbers (static)
359+
*
360+
* @param string $text Input text
361+
* @param string $locale Target locale ('persian' or 'arabic')
362+
* @return string Text with converted numbers
363+
*/
364+
public static function convertNumbersStatic(string $text, string $locale = 'persian'): string
365+
{
366+
return self::getStaticInstance()->convertNumbers($text, $locale);
367+
}
368+
369+
/**
370+
* Word wrap for RTL text (static)
371+
*
372+
* @param string $text Text to wrap
373+
* @param int $width Maximum line width
374+
* @param string $break Line break character
375+
* @param bool $cut Whether to cut words
376+
* @return string Wrapped text
377+
*/
378+
public static function wordWrapStatic(string $text, int $width = 75, string $break = "\n", bool $cut = false): string
379+
{
380+
return self::getStaticInstance()->wordWrap($text, $width, $break, $cut);
381+
}
382+
383+
/**
384+
* Check if text is RTL (static)
385+
*
386+
* @param string $text Text to check
387+
* @return bool True if RTL
388+
*/
389+
public static function isRTLStatic(string $text): bool
390+
{
391+
return self::getStaticInstance()->isRTL($text);
392+
}
220393
}
221394

0 commit comments

Comments
 (0)