Skip to content

Commit 2b085d9

Browse files
authored
Merge pull request #125 from j4mie/develop
Release 1.5.5
2 parents 6cd7a3d + 185e574 commit 2b085d9

10 files changed

Lines changed: 298 additions & 23 deletions

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
*.swp
22
*.sqlite
33
docs/_build
4-
nbproject/
4+
nbproject/
5+
/vendor
6+
/composer.lock

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
language: php
22
php:
3-
- 5.2
43
- 5.3
54
- 5.4
5+
- 5.6
6+
- 7.0
67
script: "phpunit --colors --coverage-text"

README.markdown

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ foreach ($tweets as $tweet) {
7474
Changelog
7575
---------
7676

77+
#### 1.5.5 - released 2016-12-14
78+
79+
* Fix join table name not generated correclty [[Ralphunter](https://github.com/Ralphunter)] - [issue #109](https://github.com/j4mie/paris/pull/109)
80+
* Add phpunit as dev dependency and composer script (`composer test`) to easily run tests [[Treffynnon](https://github.com/Treffynnon)]
81+
* Global setting to allow static requests to avoid being forced in to using the namespace + class as the auto table name [[michaelward82](https://github.com/michaelward82)] - [issue #100](https://github.com/j4mie/paris/issues/100)
82+
* Document conflict between static Model calling and auto_prefix_models [[michaelward82](https://github.com/michaelward82)] - [issue #102](https://github.com/j4mie/paris/issues/102)
83+
* Added @method tags for magic methods [[stellis](https://github.com/stellis)] - [issue #104](https://github.com/j4mie/paris/issues/104)
84+
* Add missing `__unset()` magic method [[qyanu](https://github.com/qyanu)] - [issue #106](https://github.com/j4mie/paris/issues/106)
85+
* Remove PHP 5.2 from travis-ci containers to test against (**note** Idiorm still supports PHP 5.2 despite this) [[Treffynnon](https://github.com/treffynnon)]
86+
7787
#### 1.5.4 - released 2014-09-23
7888

7989
* Corrects return value in docblock for 2 Model functions [[michaelward82](https://github.com/michaelward82)] - [issue #99](https://github.com/j4mie/paris/pull/99)

composer.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
"php": ">=5.2.0",
3838
"j4mie/idiorm": "1.5.*"
3939
},
40+
"scripts": {
41+
"test": "vendor/bin/phpunit"
42+
},
43+
"require-dev": {
44+
"phpunit/phpunit": "^5.6"
45+
},
4046
"autoload": {
4147
"classmap": ["paris.php"]
4248
}

docs/configuration.rst

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,40 @@ Here is a namespaced example to make it clearer:
5656
Model::factory('Simple')->find_many(); // SQL executed: SELECT * FROM `tests_simple`
5757
Model::factory('SimpleUser')->find_many(); // SQL executed: SELECT * FROM `tests_simple_user`
5858
59+
Model prefixes are only compatible with the ``Model::factory()`` methods described above.
60+
Where the shorter ``SimpleUser::find_many()`` style syntax is used, the addition of a
61+
Model prefix will cause ``Class not found`` errors.
62+
5963
.. note::
6064

61-
It is possible to define the table name by setting ``$_table`` in your
62-
individual model classes. As documented in the :doc:`Models` section of
63-
the documentation.
65+
Model class property ``$_table`` sets an explicit table name, ignoring the
66+
``$auto_prefix_models`` property in your individual model classes. See documentation in
67+
the :doc:`Models` section of the documentation.
68+
69+
Model prefixing
70+
~~~~~~~~~~~~~~~
71+
72+
Setting: ``Model::$short_table_names``
73+
74+
Set as ``true`` to disregard namespace information when computing table names
75+
from class names.
76+
77+
By default the class ``\Models\CarTyre`` expects the table name ``models_car_tyre``.
78+
With ``Model::$short_table_names = true`` the class ``\Models\CarTyre`` expects the
79+
table name ``car_tyre``.
80+
81+
.. code-block:: php
82+
83+
<?php
84+
85+
Model::$short_table_names = true;
86+
Model::factory('CarTyre')->find_many(); // SQL executed: SELECT * FROM `car_tyre`
87+
88+
namespace Models {
89+
class CarTyre extends Model {
6490
91+
}
92+
}
6593
6694
Further Configuration
6795
~~~~~~~~~~~~~~~~~~~~~

docs/models.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,14 @@ in a similar way. For example ``\Models\CarTyre`` would be converted to
3737
``models_car_tyre``. Note here that backslashes are replaced with underscores
3838
in addition to the *CapWords* replacement discussed in the previous paragraph.
3939

40-
To disregard namespace information when calculating the table name, set a
41-
**public static** property named ``$_table_use_short_name`` on your class.
42-
This would result in ``\Models\CarTyre`` being converted to ``car_tyre``.
40+
To disregard namespace information when calculating the table name, set
41+
``Model::$short_table_names = true;``. Optionally this may be set or overridden at
42+
class level with the **public static** property ``$_table_use_short_name``. The
43+
44+
``$_table_use_short_name`` takes precedence over ``Model::$short_table_names``
45+
unless ``$_table_use_short_name`` is ``null`` (default).
46+
47+
Either setting results in ``\Models\CarTyre`` being converted to ``car_tyre``.
4348

4449
.. code-block:: php
4550

paris.php

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@
4848
* You shouldn't need to interact with this class
4949
* directly. It is used internally by the Model base
5050
* class.
51+
*
52+
*
53+
* The methods documented below are magic methods that conform to PSR-1.
54+
* This documentation exposes these methods to doc generators and IDEs.
55+
* @see http://www.php-fig.org/psr/psr-1/
56+
*
57+
* @method void setClassName($class_name)
58+
* @method static \ORMWrapper forTable($table_name, $connection_name = parent::DEFAULT_CONNECTION)
59+
* @method \Model findOne($id=null)
60+
* @method Array findMany()
5161
*/
5262
class ORMWrapper extends ORM {
5363

@@ -155,7 +165,7 @@ public function find_many() {
155165
* empty instance of the class associated with
156166
* this wrapper instead of the raw ORM class.
157167
*
158-
* return ORMWrapper|bool
168+
* @return ORMWrapper|bool
159169
*/
160170
public function create($data=null) {
161171
return $this->_create_model_instance(parent::create($data));
@@ -169,6 +179,16 @@ public function create($data=null) {
169179
* class Widget extends Model {
170180
* }
171181
*
182+
*
183+
* The methods documented below are magic methods that conform to PSR-1.
184+
* This documentation exposes these methods to doc generators and IDEs.
185+
* @see http://www.php-fig.org/psr/psr-1/
186+
*
187+
* @method void setOrm($orm)
188+
* @method $this setExpr($property, $value = null)
189+
* @method bool isDirty($property)
190+
* @method bool isNew()
191+
* @method Array asArray()
172192
*/
173193
class Model {
174194

@@ -190,6 +210,17 @@ class Model {
190210
*/
191211
public static $auto_prefix_models = null;
192212

213+
/**
214+
* Set true to to ignore namespace information when computing table names
215+
* from class names.
216+
*
217+
* @example Model::$short_table_names = true;
218+
* @example Model::$short_table_names = false; // default
219+
*
220+
* @var bool $short_table_names
221+
*/
222+
public static $short_table_names = false;
223+
193224
/**
194225
* The ORM instance used by this model
195226
* instance to communicate with the database.
@@ -225,17 +256,18 @@ protected static function _get_static_property($class_name, $property, $default=
225256
* If not, the class name will be converted using
226257
* the _class_name_to_table_name method method.
227258
*
228-
* If public static property $_table_use_short_name == true
229-
* then $class_name passed to _class_name_to_table_name is
230-
* stripped of namespace information.
259+
* If Model::$short_table_names == true or public static
260+
* property $_table_use_short_name == true then $class_name passed
261+
* to _class_name_to_table_name is stripped of namespace information.
231262
*
232263
* @param string $class_name
233-
* @return string
264+
*
265+
*@return string
234266
*/
235267
protected static function _get_table_name($class_name) {
236268
$specified_table_name = self::_get_static_property($class_name, '_table');
237-
$use_short_class_name =
238-
self::_get_static_property($class_name, '_table_use_short_name');
269+
270+
$use_short_class_name = self::_use_short_table_name($class_name);
239271

240272
if ($use_short_class_name) {
241273
$exploded_class_name = explode('\\', $class_name);
@@ -248,6 +280,20 @@ protected static function _get_table_name($class_name) {
248280
return $specified_table_name;
249281
}
250282

283+
/**
284+
* Should short table names, disregarding class namespaces, be computed?
285+
*
286+
* $class_property overrides $global_option, unless $class_property is null
287+
*
288+
* @param string $class_name
289+
* @return bool
290+
*/
291+
protected static function _use_short_table_name($class_name) {
292+
$global_option = self::$short_table_names;
293+
$class_property = self::_get_static_property($class_name, '_table_use_short_name');
294+
return is_null($class_property) ? $global_option : $class_property;
295+
}
296+
251297
/**
252298
* Convert a namespace to the standard PEAR underscore format.
253299
*
@@ -439,12 +485,19 @@ protected function has_many_through($associated_class_name, $join_class_name=nul
439485
// formed by concatenating the names of the base class
440486
// and the associated class, in alphabetical order.
441487
if (is_null($join_class_name)) {
442-
$model = explode('\\', $base_class_name);
443-
$model_name = end($model);
444-
if (substr($model_name, 0, strlen(self::$auto_prefix_models)) == self::$auto_prefix_models) {
445-
$model_name = substr($model_name, strlen(self::$auto_prefix_models), strlen($model_name));
488+
$base_model = explode('\\', $base_class_name);
489+
$base_model_name = end($base_model);
490+
if (substr($base_model_name, 0, strlen(self::$auto_prefix_models)) == self::$auto_prefix_models) {
491+
$base_model_name = substr($base_model_name, strlen(self::$auto_prefix_models), strlen($base_model_name));
492+
}
493+
// Paris wasn't checking the name settings for the associated class.
494+
$associated_model = explode('\\', $associated_class_name);
495+
$associated_model_name = end($associated_model);
496+
if (substr($associated_model_name, 0, strlen(self::$auto_prefix_models)) == self::$auto_prefix_models) {
497+
$associated_model_name = substr($associated_model_name, strlen(self::$auto_prefix_models), strlen($associated_model_name));
446498
}
447-
$class_names = array($model_name, $associated_class_name);
499+
$class_names = array($base_model_name, $associated_model_name);
500+
448501
sort($class_names, SORT_STRING);
449502
$join_class_name = join("", $class_names);
450503
}
@@ -510,6 +563,16 @@ public function __set($property, $value) {
510563
$this->orm->set($property, $value);
511564
}
512565

566+
/**
567+
* Magic unset method, allows unset($model->property)
568+
*
569+
* @param string $property
570+
* @return void
571+
*/
572+
public function __unset($property) {
573+
$this->orm->__unset($property);
574+
}
575+
513576
/**
514577
* Magic isset method, allows isset($model->property) to work correctly.
515578
*

test/HasManyThroughTest53.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
namespace
3+
{
4+
class HasManyThroughTest extends PHPUnit_Framework_TestCase
5+
{
6+
private $sql = '
7+
CREATE TABLE post (
8+
id INTEGER PRIMARY KEY AUTOINCREMENT,
9+
title TEXT
10+
);
11+
12+
CREATE TABLE tag (
13+
id INTEGER PRIMARY KEY AUTOINCREMENT,
14+
name TEXT
15+
);
16+
17+
CREATE TABLE post_tag (
18+
post_id INTEGER,
19+
tag_id INTEGER,
20+
21+
FOREIGN KEY(post_id) REFERENCES post(id),
22+
FOREIGN KEY(tag_id) REFERENCES tag(id)
23+
);
24+
25+
INSERT INTO post (title)
26+
VALUES ("A Blog Post Title: PHPUnit Testing");
27+
28+
INSERT INTO tag (name) VALUES ("php");
29+
INSERT INTO tag (name) VALUES ("programming");
30+
INSERT INTO tag (name) VALUES ("github");
31+
32+
INSERT INTO post_tag (post_id, tag_id) VALUES (1, 1);
33+
INSERT INTO post_tag (post_id, tag_id) VALUES (1, 2);
34+
INSERT INTO post_tag (post_id, tag_id) VALUES (1, 3);
35+
';
36+
37+
public function setUp () {
38+
$db_handle = new PDO('sqlite::memory:');
39+
$db_handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
40+
$db_handle->exec($this->sql);
41+
42+
ORM::set_db($db_handle);
43+
ORM::configure('logging', true);
44+
}
45+
46+
public function tearDown ()
47+
{
48+
ORM::configure('logging', false);
49+
ORM::set_db(null);
50+
}
51+
52+
public function testHasManyThrough () {
53+
$video = \PHPProject\Models\Post::find_one(1);
54+
$tags = $video->tags()->find_many();
55+
$this->assertArrayHasKey('id', $tags[0]->as_array());
56+
$this->assertArrayHasKey('name', $tags[0]->as_array());
57+
}
58+
}
59+
}
60+
61+
// We need to use the namespaces here to test whether
62+
// the table names are being correctly generated when
63+
// using $_table_use_short_name = true;
64+
namespace PHPProject\Models
65+
{
66+
class Post extends \Model
67+
{
68+
public static $_table_use_short_name = true;
69+
70+
public function tags ()
71+
{
72+
return $this->has_many_through('\\PHPProject\\Models\\Tag');
73+
}
74+
}
75+
class Tag extends \Model
76+
{
77+
public static $_table_use_short_name = true;
78+
79+
public function posts ()
80+
{
81+
return $this->has_many_through('\\PHPProject\\Models\\Post');
82+
}
83+
}
84+
class PostTag extends \Model
85+
{
86+
public static $_table_use_short_name = true;
87+
}
88+
}
89+
?>

test/MagicMethodsTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
class MagicMethodsTest extends PHPUnit_Framework_TestCase {
4+
5+
public function setUp() {
6+
// Set up the dummy database connection
7+
ORM::set_db(new MockPDO('sqlite::memory:'));
8+
9+
// Enable logging
10+
ORM::configure('logging', true);
11+
12+
Model::$auto_prefix_models = null;
13+
}
14+
15+
public function tearDown() {
16+
ORM::configure('logging', false);
17+
ORM::set_db(null);
18+
19+
Model::$auto_prefix_models = null;
20+
}
21+
22+
public function testMagicMethodUnset() {
23+
$model = Model::factory("Simple")->create();
24+
$model->property = "test";
25+
unset($model->property);
26+
$this->assertFalse(isset($model->property));
27+
$this->assertTrue($model->get("property")!="test");
28+
}
29+
}

0 commit comments

Comments
 (0)