text:
<?php namespace CodeIgniter\Database\Live;

use BadMethodCallException;
use CodeIgniter\Config\Config;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\Exceptions\DataException;
use CodeIgniter\Entity;
use CodeIgniter\I18n\Time;
use CodeIgniter\Model;
use CodeIgniter\Test\CIDatabaseTestCase;
use CodeIgniter\Test\ReflectionHelper;
use Config\Services;
use Tests\Support\Models\EntityModel;
use Tests\Support\Models\EventModel;
use Tests\Support\Models\JobModel;
use Tests\Support\Models\SecondaryModel;
use Tests\Support\Models\SimpleEntity;
use Tests\Support\Models\StringifyPkeyModel;
use Tests\Support\Models\UserModel;
use Tests\Support\Models\ValidErrorsModel;
use Tests\Support\Models\ValidModel;

/**
 * @group DatabaseLive
 */
class ModelTest extends CIDatabaseTestCase
{
	use ReflectionHelper;

	protected $refresh = true;

	protected $seed = 'Tests\Support\Database\Seeds\CITestSeeder';

	protected function setUp(): void
	{
		parent::setUp();

		$this->model = new Model($this->db);
	}

	//--------------------------------------------------------------------

	public function tearDown(): void
	{
		parent::tearDown();

		Services::reset();
		Config::reset();
	}

	//--------------------------------------------------------------------

	public function testFindReturnsRow()
	{
		$model = new JobModel($this->db);

		$job = $model->find(4);

		$this->assertEquals('Musician', $job->name);
	}

	//--------------------------------------------------------------------

	public function testFindReturnsMultipleRows()
	{
		$model = new JobModel($this->db);

		$job = $model->find([1, 4]);

		$this->assertEquals('Developer', $job[0]->name);
		$this->assertEquals('Musician', $job[1]->name);
	}

	//--------------------------------------------------------------------

	public function testGetColumnWithStringColumnName()
	{
		$model = new JobModel($this->db);

		$job = $model->findColumn('name');

		$this->assertEquals('Developer', $job[0]);
		$this->assertEquals('Politician', $job[1]);
		$this->assertEquals('Accountant', $job[2]);
		$this->assertEquals('Musician', $job[3]);
	}

	//--------------------------------------------------------------------

	public function testGetColumnsWithMultipleColumnNames()
	{
		$model = new JobModel($this->db);

		$this->expectException(DataException::class);
		$this->expectExceptionMessage('Only single column allowed in Column name.');

		$job = $model->findColumn('name,description');
	}

	//--------------------------------------------------------------------

	public function testFindActsAsGetWithNoParams()
	{
		$model = new JobModel($this->db);

		$jobs = $model->asArray()
					  ->find();

		$this->assertCount(4, $jobs);

		$names = array_column($jobs, 'name');
		$this->assertTrue(in_array('Developer', $names));
		$this->assertTrue(in_array('Politician', $names));
		$this->assertTrue(in_array('Accountant', $names));
		$this->assertTrue(in_array('Musician', $names));
	}

	//--------------------------------------------------------------------

	public function testFindRespectsReturnArray()
	{
		$model = new JobModel($this->db);

		$job = $model->asArray()
					 ->find(4);

		$this->assertIsArray($job);
	}

	//--------------------------------------------------------------------

	public function testFindRespectsReturnObject()
	{
		$model = new JobModel($this->db);

		$job = $model->asObject()
					 ->find(4);

		$this->assertIsObject($job);
	}

	//--------------------------------------------------------------------

	public function testFindRespectsSoftDeletes()
	{
		$this->db->table('user')
				 ->where('id', 4)
				 ->update(['deleted_at' => date('Y-m-d H:i:s')]);

		$model = new UserModel($this->db);

		$user = $model->asObject()
					  ->find(4);

		$this->assertEmpty($user);

		$user = $model->withDeleted()
					  ->find(4);

		// fix for PHP7.2
		$count = is_array($user) ? count($user) : 1;
		$this->assertEquals(1, $count);
	}

	//--------------------------------------------------------------------

	public function testFindClearsBinds()
	{
		$model = new JobModel($this->db);

		$model->find(1);
		$model->find(1);

		// Binds should be reset to 0 after each one
		$binds = $model->builder()
					   ->getBinds();
		$this->assertCount(0, $binds);

		$query = $model->getLastQuery();
		$this->assertCount(1, $this->getPrivateProperty($query, 'binds'));
	}

	//--------------------------------------------------------------------

	public function testFindAllReturnsAllRecords()
	{
		$model = new UserModel($this->db);

		$users = $model->findAll();

		$this->assertCount(4, $users);
	}

	//--------------------------------------------------------------------

	public function testFindAllRespectsLimits()
	{
		$model = new UserModel($this->db);

		$users = $model->findAll(2);

		$this->assertCount(2, $users);
		$this->assertEquals('Derek Jones', $users[0]->name);
	}

	//--------------------------------------------------------------------

	public function testFindAllRespectsLimitsAndOffset()
	{
		$model = new UserModel($this->db);

		$users = $model->findAll(2, 2);

		$this->assertCount(2, $users);
		$this->assertEquals('Richard A Causey', $users[0]->name);
	}

	//--------------------------------------------------------------------

	public function testFindAllRespectsSoftDeletes()
	{
		$this->db->table('user')
				 ->where('id', 4)
				 ->update(['deleted_at' => date('Y-m-d H:i:s')]);

		$model = new UserModel($this->db);

		$user = $model->findAll();

		$this->assertCount(3, $user);

		$user = $model->withDeleted()
					  ->findAll();

		$this->assertCount(4, $user);
	}

	//--------------------------------------------------------------------

	public function testFirst()
	{
		$model = new UserModel();

		$user = $model->where('id >', 2)
					  ->first();

		// fix for PHP7.2
		$count = is_array($user) ? count($user) : 1;
		$this->assertEquals(1, $count);
		$this->assertEquals(3, $user->id);
	}

	//--------------------------------------------------------------------

	public function provideGroupBy()
	{
		return [
			[
				true,
				3,
			],
			[
				false,
				7,
			],
		];
	}

	/**
	 * @dataProvider provideGroupBy
	 */
	public function testFirstAggregate($groupBy, $total)
	{
		$model = new UserModel();

		if ($groupBy)
		{
			$model->groupBy('id');
		}

		$user = $model->select('SUM(id) as total')
					  ->where('id >', 2)
					  ->first();

		$this->assertEquals($total, $user->total);
	}

	//--------------------------------------------------------------------

	public function provideAggregateAndGroupBy()
	{
		return [
			[
				true,
				true,
			],
			[
				false,
				false,
			],
			[
				true,
				false,
			],
			[
				false,
				true,
			],
		];
	}

	/**
	 * @dataProvider provideAggregateAndGroupBy
	 */
	public function testFirstRespectsSoftDeletes($aggregate, $groupBy)
	{
		$this->db->table('user')
				 ->where('id', 1)
				 ->update(['deleted_at' => date('Y-m-d H:i:s')]);

		$model = new UserModel();
		if ($aggregate)
		{
			$model->select('SUM(id) as id');
		}

		if ($groupBy)
		{
			$model->groupBy('id');
		}

		$user = $model->first();

		if (! $aggregate || $groupBy)
		{
			// fix for PHP7.2
			$count = is_array($user) ? count($user) : 1;
			$this->assertEquals(1, $count);
			$this->assertEquals(2, $user->id);
		}
		else
		{
			$this->assertEquals(9, $user->id);
		}

		$user = $model->withDeleted()
					  ->first();

		$this->assertEquals(1, $user->id);
	}

	//--------------------------------------------------------------------

	public function testFirstWithNoPrimaryKey()
	{
		$model = new SecondaryModel();

		$this->db->table('secondary')
				 ->insert([
					 'id'    => 1,
					 'key'   => 'foo',
					 'value' => 'bar',
				 ]);
		$this->db->table('secondary')
				 ->insert([
					 'id'    => 2,
					 'key'   => 'bar',
					 'value' => 'baz',
				 ]);

		$record = $model->first();

		$this->assertInstanceOf('stdClass', $record);
		$this->assertEquals('foo', $record->key);
	}

	//--------------------------------------------------------------------

	public function testSaveNewRecordObject()
	{
		$model = new JobModel();

		$data              = new \stdClass();
		$data->name        = 'Magician';
		$data->description = 'Makes peoples things dissappear.';

		$model->protect(false)
			  ->save($data);

		$this->seeInDatabase('job', ['name' => 'Magician']);
	}

	//--------------------------------------------------------------------

	public function testSaveNewRecordArray()
	{
		$model = new JobModel();

		$data = [
			'name'        => 'Apprentice',
			'description' => 'That thing you do.',
		];

		$model->protect(false)
			  ->save($data);

		$this->seeInDatabase('job', ['name' => 'Apprentice']);
	}

	//--------------------------------------------------------------------

	public function testSaveUpdateRecordObject()
	{
		$model = new JobModel();

		$data = [
			'id'          => 1,
			'name'        => 'Apprentice',
			'description' => 'That thing you do.',
		];

		$result = $model->protect(false)
						->save($data);

		$this->seeInDatabase('job', ['name' => 'Apprentice']);
		$this->assertTrue($result);
	}

	//--------------------------------------------------------------------

	public function testSaveUpdateRecordArray()
	{
		$model = new JobModel();

		$data              = new \stdClass();
		$data->id          = 1;
		$data->name        = 'Engineer';
		$data->description = 'A fancier term for Developer.';

		$result = $model->protect(false)
						->save($data);

		$this->seeInDatabase('job', ['name' => 'Engineer']);
		$this->assertTrue($result);
	}

	//--------------------------------------------------------------------

	public function testSaveProtected()
	{
		$model = new JobModel();

		$data               = new \stdClass();
		$data->id           = 1;
		$data->name         = 'Engineer';
		$data->description  = 'A fancier term for Developer.';
		$data->random_thing = 'Something wicked'; // If not protected, this would kill the script.

		$result = $model->protect(true)
						->save($data);

		$this->assertTrue($result);
	}

	//--------------------------------------------------------------------

	public function testDeleteBasics()
	{
		$model = new JobModel();

		$this->seeInDatabase('job', ['name' => 'Developer']);

		$model->delete(1);

		$this->dontSeeInDatabase('job', ['name' => 'Developer']);
	}

	//--------------------------------------------------------------------

	public function testDeleteStringPrimaryKey()
	{
		$model = new StringifyPkeyModel();

		$this->seeInDatabase('stringifypkey', ['value' => 'test']);

		$model->delete('A01');

		$this->dontSeeInDatabase('stringifypkey', ['value' => 'test']);
	}

	//--------------------------------------------------------------------

	public function testDeleteWithSoftDeletes()
	{
		$model = new UserModel();

		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at IS NULL' => null]);

		$model->delete(1);

		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at IS NOT NULL' => null]);
	}

	//--------------------------------------------------------------------

	public function testDeleteWithSoftDeletesPurge()
	{
		$model = new UserModel();

		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at IS NULL' => null]);

		$model->delete(1, true);

		$this->dontSeeInDatabase('user', ['name' => 'Derek Jones']);
	}

	//--------------------------------------------------------------------

	public function testDeleteMultiple()
	{
		$model = new JobModel();

		$this->seeInDatabase('job', ['name' => 'Developer']);
		$this->seeInDatabase('job', ['name' => 'Politician']);

		$model->delete([1, 2]);

		$this->dontSeeInDatabase('job', ['name' => 'Developer']);
		$this->dontSeeInDatabase('job', ['name' => 'Politician']);
		$this->seeInDatabase('job', ['name' => 'Accountant']);
	}

	//--------------------------------------------------------------------

	public function testDeleteNoParams()
	{
		$model = new JobModel();

		$this->seeInDatabase('job', ['name' => 'Developer']);

		$model->where('id', 1)
			  ->delete();

		$this->dontSeeInDatabase('job', ['name' => 'Developer']);
	}

	//--------------------------------------------------------------------

	public function testPurgeDeleted()
	{
		$model = new UserModel();

		$this->db->table('user')
				 ->where('id', 1)
				 ->update(['deleted_at' => date('Y-m-d H:i:s')]);

		$model->purgeDeleted();

		$users = $model->withDeleted()
					   ->findAll();

		$this->assertCount(3, $users);
	}

	//--------------------------------------------------------------------

	public function testOnlyDeleted()
	{
		$model = new UserModel($this->db);

		$this->db->table('user')
				 ->where('id', 1)
				 ->update(['deleted_at' => date('Y-m-d H:i:s')]);

		$users = $model->onlyDeleted()
					   ->findAll();

		$this->assertCount(1, $users);
	}
	/**
	 * If where condition is set, beyond the value was empty (0,'', NULL, etc.),
	 * Exception should not be thrown because condition was explicity set
	 *
	 * @dataProvider emptyPkValues
	 * @return       void
	 */
	public function testDontThrowExceptionWhenSoftDeleteConditionIsSetWithEmptyValue($emptyValue)
	{
		$model = new UserModel();
		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at IS NULL' => null]);
		$model->where('id', $emptyValue)->delete();
		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at IS NULL' => null]);
		unset($model);
	}    //--------------------------------------------------------------------

	/**
	 * @dataProvider emptyPkValues
	 * @return       void
	 */
	public function testThrowExceptionWhenSoftDeleteParamIsEmptyValue($emptyValue)
	{
		$this->expectException('CodeIgniter\Database\Exceptions\DatabaseException');
		$this->expectExceptionMessage('Deletes are not allowed unless they contain a "where" or "like" clause.');

		$model = new UserModel();
		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at IS NULL' => null]);
		$model->delete($emptyValue);
	}

	//--------------------------------------------------------------------

	/**
	 * @dataProvider emptyPkValues
	 * @return       void
	 */
	public function testDontDeleteRowsWhenSoftDeleteParamIsEmpty($emptyValue)
	{
		$this->expectException('CodeIgniter\Database\Exceptions\DatabaseException');
		$this->expectExceptionMessage('Deletes are not allowed unless they contain a "where" or "like" clause.');

		$model = new UserModel();
		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at IS NULL' => null]);
		$model->delete($emptyValue);
		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at IS NULL' => null]);
		unset($model);
	}

	public function emptyPkValues()
	{
		return [
			[0],
			[null],
			['0'],
		];
	}
	//--------------------------------------------------------------------

	public function testChunk()
	{
		$model = new UserModel();

		$rowCount = 0;

		$model->chunk(2, function ($row) use (&$rowCount) {
			$rowCount++;
		});

		$this->assertEquals(4, $rowCount);
	}

	//--------------------------------------------------------------------

	public function testValidationBasics()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'        => null,
			'description' => 'some great marketing stuff',
		];

		$this->assertFalse($model->insert($data));

		$errors = $model->errors();

		$this->assertEquals('You forgot to name the baby.', $errors['name']);
	}

	//--------------------------------------------------------------------

	public function testValidationWithSetValidationRule()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'        => 'some name',
			'description' => 'some great marketing stuff',
		];

		$model->setValidationRule('description', [
			'rules'  => 'required|min_length[50]',
			'errors' => [
				'min_length' => 'Description is too short baby.',
			],
		]);
		$this->assertFalse($model->insert($data));

		$errors = $model->errors();

		$this->assertEquals('Description is too short baby.', $errors['description']);
	}

	//--------------------------------------------------------------------

	public function testValidationWithSetValidationRules()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'        => '',
			'description' => 'some great marketing stuff',
		];

		$model->setValidationRules([
			'name'        => [
				'rules'  => 'required',
				'errors' => [
					'required' => 'Give me a name baby.',
				],
			],
			'description' => [
				'rules'  => 'required|min_length[50]',
				'errors' => [
					'min_length' => 'Description is too short baby.',
				],
			],
		]);
		$this->assertFalse($model->insert($data));

		$errors = $model->errors();

		$this->assertEquals('Give me a name baby.', $errors['name']);
		$this->assertEquals('Description is too short baby.', $errors['description']);
	}

	//--------------------------------------------------------------------

	public function testValidationWithSetValidationMessage()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'        => null,
			'description' => 'some great marketing stuff',
		];

		$model->setValidationMessage('name', [
			'required'   => 'Your baby name is missing.',
			'min_length' => 'Too short, man!',
		]);
		$this->assertFalse($model->insert($data));

		$errors = $model->errors();

		$this->assertEquals('Your baby name is missing.', $errors['name']);
	}

	//--------------------------------------------------------------------

	public function testValidationWithSetValidationMessages()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'        => null,
			'description' => 'some great marketing stuff',
		];

		$model->setValidationMessages([
			'name' => [
				'required'   => 'Your baby name is missing.',
				'min_length' => 'Too short, man!',
			],
		]);

		$this->assertFalse($model->insert($data));

		$errors = $model->errors();

		$this->assertEquals('Your baby name is missing.', $errors['name']);
	}
	//--------------------------------------------------------------------

	public function testValidationPlaceholdersSuccess()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'  => 'abc',
			'id'    => 13,
			'token' => 13,
		];

		$this->assertTrue($model->validate($data));
	}

	//--------------------------------------------------------------------

	public function testValidationPlaceholdersFail()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'  => 'abc',
			'id'    => 13,
			'token' => 12,
		];

		$this->assertFalse($model->validate($data));
	}

	//--------------------------------------------------------------------

	public function testSkipValidation()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'        => '2',
			'description' => 'some great marketing stuff',
		];

		$this->assertIsNumeric($model->skipValidation(true)->insert($data));
	}

	//--------------------------------------------------------------------

	public function testCleanValidationRemovesAllWhenNoDataProvided()
	{
		$model   = new Model($this->db);
		$cleaner = $this->getPrivateMethodInvoker($model, 'cleanValidationRules');

		$rules = [
			'name' => 'required',
			'foo'  => 'bar',
		];

		$rules = $cleaner($rules, null);

		$this->assertEmpty($rules);
	}

	//--------------------------------------------------------------------

	public function testCleanValidationRemovesOnlyForFieldsNotProvided()
	{
		$model   = new Model($this->db);
		$cleaner = $this->getPrivateMethodInvoker($model, 'cleanValidationRules');

		$rules = [
			'name' => 'required',
			'foo'  => 'required',
		];

		$data = [
			'foo' => 'bar',
		];

		$rules = $cleaner($rules, $data);

		$this->assertTrue(array_key_exists('foo', $rules));
		$this->assertFalse(array_key_exists('name', $rules));
	}

	//--------------------------------------------------------------------

	public function testCleanValidationReturnsAllWhenAllExist()
	{
		$model   = new Model($this->db);
		$cleaner = $this->getPrivateMethodInvoker($model, 'cleanValidationRules');

		$rules = [
			'name' => 'required',
			'foo'  => 'required',
		];

		$data = [
			'foo'  => 'bar',
			'name' => null,
		];

		$rules = $cleaner($rules, $data);

		$this->assertTrue(array_key_exists('foo', $rules));
		$this->assertTrue(array_key_exists('name', $rules));
	}

	//--------------------------------------------------------------------

	public function testValidationPassesWithMissingFields()
	{
		$model = new ValidModel();

		$data = [
			'foo' => 'bar',
		];

		$result = $model->validate($data);

		$this->assertTrue($result);
	}

	//--------------------------------------------------------------------

	public function testValidationWithGroupName()
	{
		$config            = new \Config\Validation();
		$config->grouptest = [
			'name'  => [
				'required',
				'min_length[3]',
			],
			'token' => 'in_list[{id}]',
		];

		$data = [
			'name'  => 'abc',
			'id'    => 13,
			'token' => 13,
		];

		\CodeIgniter\Config\Config::injectMock('Validation', $config);

		$model = new ValidModel($this->db);
		$this->setPrivateProperty($model, 'validationRules', 'grouptest');

		$this->assertTrue($model->validate($data));
	}

	//--------------------------------------------------------------------

	public function testCanCreateAndSaveEntityClasses()
	{
		$model = new EntityModel($this->db);

		$entity = $model->where('name', 'Developer')
						->first();

		$this->assertInstanceOf(SimpleEntity::class, $entity);
		$this->assertEquals('Developer', $entity->name);
		$this->assertEquals('Awesome job, but sometimes makes you bored', $entity->description);

		$time = time();

		$entity->name       = 'Senior Developer';
		$entity->created_at = $time;

		$this->assertTrue($model->save($entity));

		$result = $model->where('name', 'Senior Developer')
						->get()
						->getFirstRow();

		$this->assertEquals(date('Y-m-d', $time), date('Y-m-d', $result->created_at));
	}

	//--------------------------------------------------------------------

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/580
	 */
	public function testPasswordsStoreCorrectly()
	{
		$model = new UserModel();

		$pass = password_hash('secret123', PASSWORD_BCRYPT);

		$data = [
			'name'    => $pass,
			'email'   => 'foo@example.com',
			'country' => 'US',
		];

		$model->insert($data);

		$this->seeInDatabase('user', $data);
	}

	//--------------------------------------------------------------------

	public function testInsertEvent()
	{
		$model = new EventModel();

		$data = [
			'name'    => 'Foo',
			'email'   => 'foo@example.com',
			'country' => 'US',
			'deleted' => 0,
		];

		$model->insert($data);

		$this->assertTrue($model->hasToken('beforeInsert'));
		$this->assertTrue($model->hasToken('afterInsert'));
	}

	//--------------------------------------------------------------------

	public function testUpdateEvent()
	{
		$model = new EventModel();

		$data = [
			'name'    => 'Foo',
			'email'   => 'foo@example.com',
			'country' => 'US',
			'deleted' => 0,
		];

		$id = $model->insert($data);
		$model->update($id, $data);

		$this->assertTrue($model->hasToken('beforeUpdate'));
		$this->assertTrue($model->hasToken('afterUpdate'));
	}

	//--------------------------------------------------------------------

	public function testFindEvent()
	{
		$model = new EventModel();

		$model->find(1);

		$this->assertTrue($model->hasToken('afterFind'));
	}

	//--------------------------------------------------------------------

	public function testDeleteEvent()
	{
		$model = new EventModel();

		$model->delete(1);

		$this->assertTrue($model->hasToken('afterDelete'));
	}

	//--------------------------------------------------------------------

	public function testSetWorksWithInsert()
	{
		$model = new EventModel();

		$this->dontSeeInDatabase('user', [
			'email' => 'foo@example.com',
		]);

		$model->set([
			'email'   => 'foo@example.com',
			'name'    => 'Foo Bar',
			'country' => 'US',
		])
			  ->insert();

		$this->seeInDatabase('user', [
			'email' => 'foo@example.com',
		]);
	}

	//--------------------------------------------------------------------

	public function testSetWorksWithUpdate()
	{
		$model = new EventModel();

		$this->dontSeeInDatabase('user', [
			'email' => 'foo@example.com',
		]);

		$userId = $model->insert([
			'email'   => 'foo@example.com',
			'name'    => 'Foo Bar',
			'country' => 'US',
		]);

		$model->set([
			'name' => 'Fred Flintstone',
		])
			  ->update($userId);

		$this->seeInDatabase('user', [
			'id'    => $userId,
			'email' => 'foo@example.com',
			'name'  => 'Fred Flintstone',
		]);
	}

	//--------------------------------------------------------------------

	public function testSetWorksWithUpdateNoId()
	{
		$model = new EventModel();

		$this->dontSeeInDatabase('user', [
			'email' => 'foo@example.com',
		]);

		$userId = $model->insert([
			'email'   => 'foo@example.com',
			'name'    => 'Foo Bar',
			'country' => 'US',
		]);

		$model
			->where('id', $userId)
			->set([
				'name' => 'Fred Flintstone',
			])
			->update();

		$this->seeInDatabase('user', [
			'id'    => $userId,
			'email' => 'foo@example.com',
			'name'  => 'Fred Flintstone',
		]);
	}

	//--------------------------------------------------------------------

	public function testUpdateArray()
	{
		$model = new EventModel();

		$data = [
			'name'    => 'Foo',
			'email'   => 'foo@example.com',
			'country' => 'US',
			'deleted' => 0,
		];

		$id = $model->insert($data);
		$model->update([1, 2], ['name' => 'Foo Bar']);

		$this->seeInDatabase('user', ['id' => 1, 'name' => 'Foo Bar']);
		$this->seeInDatabase('user', ['id' => 2, 'name' => 'Foo Bar']);
	}

	//--------------------------------------------------------------------

	public function testInsertBatchSuccess()
	{
		$job_data = [
			[
				'name'        => 'Comedian',
				'description' => 'Theres something in your teeth',
			],
			[
				'name'        => 'Cab Driver',
				'description' => 'Iam yellow',
			],
		];

		$model = new JobModel($this->db);
		$model->insertBatch($job_data);

		$this->seeInDatabase('job', ['name' => 'Comedian']);
		$this->seeInDatabase('job', ['name' => 'Cab Driver']);
	}

	//--------------------------------------------------------------------

	public function testInsertBatchValidationFail()
	{
		$job_data = [
			[
				'name'        => 'Comedian',
				'description' => null,
			],
		];

		$model = new JobModel($this->db);

		$this->setPrivateProperty($model, 'validationRules', ['description' => 'required']);

		$this->assertFalse($model->insertBatch($job_data));

		$error = $model->errors();
		$this->assertTrue(isset($error['description']));
	}

	//--------------------------------------------------------------------

	public function testUpdateBatchSuccess()
	{
		$data = [
			[
				'name'    => 'Derek Jones',
				'country' => 'Greece',
			],
			[
				'name'    => 'Ahmadinejad',
				'country' => 'Greece',
			],
		];

		$model = new EventModel($this->db);

		$model->updateBatch($data, 'name');

		$this->seeInDatabase('user', [
			'name'    => 'Derek Jones',
			'country' => 'Greece',
		]);
		$this->seeInDatabase('user', [
			'name'    => 'Ahmadinejad',
			'country' => 'Greece',
		]);
	}

	//--------------------------------------------------------------------

	public function testUpdateBatchValidationFail()
	{
		$data = [
			[
				'name'    => 'Derek Jones',
				'country' => null,
			],
		];

		$model = new EventModel($this->db);
		$this->setPrivateProperty($model, 'validationRules', ['country' => 'required']);

		$this->assertFalse($model->updateBatch($data, 'name'));

		$error = $model->errors();
		$this->assertTrue(isset($error['country']));
	}

	//--------------------------------------------------------------------

	public function testSelectAndEntitiesSaveOnlyChangedValues()
	{
		// Insert value in job table
		$this->hasInDatabase('job', [
			'name'        => 'Rocket Scientist',
			'description' => 'Plays guitar for Queen',
			'created_at'  => time(),
		]);

		$model = new EntityModel();

		// get only id, name column
		$job = $model->select('id, name')
					 ->where('name', 'Rocket Scientist')
					 ->first();

		// Hence getting Null as description column not in select clause
		$this->assertNull($job->description);

		// Equals with name to check, correct record fetched or not.
		$this->assertEquals('Rocket Scientist', $job->name);

		$job->description = 'Some guitar description';

		// saving the result set with description as empty
		$model->save($job);

		// check for the record to same entry exists or not
		$this->seeInDatabase('job', [
			'id'   => $job->id,
			'name' => 'Rocket Scientist',
		]);

		// select all columns from job table
		$job = $model->select('id, name, description')
					 ->where('name', 'Rocket Scientist')
					 ->first();

		// check whether the Null value successfully updated or not
		$this->assertEquals('Some guitar description', $job->description);
	}

	//--------------------------------------------------------------------

	public function testUpdateNoPrimaryKey()
	{
		$model = new SecondaryModel();

		$this->db->table('secondary')
				 ->insert([
					 'id'    => 1,
					 'key'   => 'foo',
					 'value' => 'bar',
				 ]);

		$this->dontSeeInDatabase('secondary', [
			'key'   => 'bar',
			'value' => 'baz',
		]);

		$model->where('key', 'foo')
			  ->update(null, ['key' => 'bar', 'value' => 'baz']);

		$this->seeInDatabase('secondary', [
			'key'   => 'bar',
			'value' => 'baz',
		]);
	}

	//--------------------------------------------------------------------

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1617
	 */
	public function testCountAllResultsRespectsSoftDeletes()
	{
		$model = new UserModel();

		// testSeeder has 4 users....
		$this->assertEquals(4, $model->countAllResults());

		$model->where('name', 'Derek Jones')
			  ->delete();

		$this->assertEquals(3, $model->countAllResults());
	}

	//--------------------------------------------------------------------

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1584
	 */
	public function testUpdateWithValidation()
	{
		$model = new ValidModel($this->db);

		$data = [
			'description' => 'This is a first test!',
			'name'        => 'valid',
			'id'          => 42,
			'token'       => 42,
		];

		$id = $model->insert($data);

		$this->assertTrue((bool)$id);

		$data['description'] = 'This is a second test!';
		unset($data['name']);

		$result = $model->update($id, $data);
		$this->assertTrue($result);
	}

	//--------------------------------------------------------------------

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1717
	 */
	public function testRequiredWithValidationEmptyString()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name' => '',
		];

		$this->assertFalse($model->insert($data));
	}

	//--------------------------------------------------------------------

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1717
	 */
	public function testRequiredWithValidationNull()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name' => null,
		];

		$this->assertFalse($model->insert($data));
	}

	//--------------------------------------------------------------------

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1717
	 */
	public function testRequiredWithValidationTrue()
	{
		$model = new ValidModel($this->db);

		$data = [
			'name'        => 'foobar',
			'description' => 'just because we have to',
		];

		$this->assertTrue($model->insert($data) !== false);
	}

	//--------------------------------------------------------------------

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1574
	 */
	public function testValidationIncludingErrors()
	{
		$model = new ValidErrorsModel($this->db);

		$data = [
			'description' => 'This is a first test!',
			'name'        => 'valid',
			'id'          => 42,
			'token'       => 42,
		];

		$id = $model->insert($data);

		$this->assertFalse((bool)$id);

		$errors = $model->errors();

		$this->assertEquals('Minimum Length Error', $model->errors()['name']);
	}

	//--------------------------------------------------------------------

	public function testThrowsWithNoPrimaryKey()
	{
		$this->expectException('CodeIgniter\Exceptions\ModelException');
		$this->expectExceptionMessage('`Tests\Support\Models\UserModel` model class does not specify a Primary Key.');

		$model = new UserModel();
		$this->setPrivateProperty($model, 'primaryKey', '');

		$model->find(1);
	}

	//--------------------------------------------------------------------

	public function testThrowsWithNoDateFormat()
	{
		$this->expectException('CodeIgniter\Exceptions\ModelException');
		$this->expectExceptionMessage('`Tests\Support\Models\UserModel` model class does not have a valid dateFormat.');

		$model = new UserModel();
		$this->setPrivateProperty($model, 'dateFormat', '');

		$model->delete(1);
	}

	//--------------------------------------------------------------------

	public function testInsertID()
	{
		$model = new JobModel();

		$data = [
			'name'        => 'Apprentice',
			'description' => 'That thing you do.',
		];

		$model->protect(false)
			  ->save($data);

		$lastInsertId = $model->getInsertID();

		$this->seeInDatabase('job', ['id' => $lastInsertId]);
	}

	//--------------------------------------------------------------------

	public function testSetTable()
	{
		$model = new JobModel();

		$model->setTable('db_job');

		$data = [
			'name'        => 'Apprentice',
			'description' => 'That thing you do.',
		];

		$model->protect(false)
			  ->save($data);

		$lastInsertId = $model->getInsertID();

		$this->seeInDatabase('job', ['id' => $lastInsertId]);
	}

	//--------------------------------------------------------------------

	public function testPaginate()
	{
		$model = new ValidModel($this->db);

		$data = $model->paginate();

		$this->assertEquals(4, count($data));
	}

	//--------------------------------------------------------------------

	public function testPaginateChangeConfigPager()
	{
		$perPage                 = config('Pager')->perPage;
		config('Pager')->perPage = 1;

		$model = new ValidModel($this->db);

		$data = $model->paginate();

		$this->assertEquals(1, count($data));

		config('Pager')->perPage = $perPage;
	}

	//--------------------------------------------------------------------

	public function testPaginatePassPerPageParameter()
	{
		$model = new ValidModel($this->db);

		$data = $model->paginate(2);

		$this->assertEquals(2, count($data));
	}

	//--------------------------------------------------------------------

	public function testPaginateForQueryWithGroupBy()
	{
		$model = new ValidModel($this->db);
		$model->groupBy('id');

		$model->paginate();
		$this->assertEquals(4, $model->pager->getDetails()['total']);
	}

	//--------------------------------------------------------------------

	public function testPaginateWithDeleted()
	{
		$model = new UserModel($this->db);
		$model->delete(1);

		$data = $model->withDeleted()->paginate();

		$this->assertEquals(4, count($data));
		$this->assertEquals(4, $model->pager->getDetails()['total']);
	}

	//--------------------------------------------------------------------

	public function testPaginateWithoutDeleted()
	{
		$model = new UserModel($this->db);
		$model->delete(1);

		$data = $model->withDeleted(false)->paginate();

		$this->assertEquals(3, count($data));
		$this->assertEquals(3, $model->pager->getDetails()['total']);
	}

	//--------------------------------------------------------------------

	public function testValidationByObject()
	{
		$model = new ValidModel($this->db);

		$data = new class
		{
			public $name  = '';
			public $id    = '';
			public $token = '';
		};

		$data->name  = 'abc';
		$data->id    = '13';
		$data->token = '13';

		$this->assertTrue($model->validate($data));
	}

	//--------------------------------------------------------------------

	public function testGetValidationRules()
	{
		$model = new JobModel($this->db);

		$this->setPrivateProperty($model, 'validationRules', ['description' => 'required']);

		$rules = $model->getValidationRules();

		$this->assertEquals('required', $rules['description']);
	}

	//--------------------------------------------------------------------

	public function testGetValidationMessages()
	{
		$job_data = [
			[
				'name'        => 'Comedian',
				'description' => null,
			],
		];

		$model = new JobModel($this->db);

		$this->setPrivateProperty($model, 'validationRules', ['description' => 'required']);
		$this->setPrivateProperty($model, 'validationMessages', ['description' => 'Description field is required.']);

		$this->assertFalse($model->insertBatch($job_data));

		$error = $model->getValidationMessages();
		$this->assertEquals('Description field is required.', $error['description']);
	}

	//--------------------------------------------------------------------

	public function testGetGetModelDetails()
	{
		$model = new JobModel($this->db);

		$this->assertEquals('job', $model->table);
		$this->assertEquals('id', $model->primaryKey);
		$this->assertEquals('object', $model->returnType);
		$this->assertNull($model->DBGroup);
	}

	//--------------------------------------------------------------------

	public function testSaveObject()
	{
		$model = new ValidModel($this->db);

		$testModel = new JobModel();

		$testModel->name        = 'my name';
		$testModel->description = 'some description';

		$this->setPrivateProperty($model, 'useTimestamps', true);

		$model->insert($testModel);

		$lastInsertId = $model->getInsertID();

		$this->seeInDatabase('job', ['id' => $lastInsertId]);
	}

	//--------------------------------------------------------------------

	public function testEmptySaveData()
	{
		$model = new JobModel();

		$data = [];

		$data = $model->protect(false)
					  ->save($data);

		$this->assertTrue($data);
	}

	//--------------------------------------------------------------------

	public function testUpdateObject()
	{
		$model = new ValidModel($this->db);

		$testModel = new JobModel();

		$testModel->name        = 'my name';
		$testModel->description = 'some description';

		$this->setPrivateProperty($model, 'useTimestamps', true);

		$model->update(1, $testModel);

		$this->seeInDatabase('job', ['id' => 1]);
	}

	//--------------------------------------------------------------------

	public function testDeleteWithSoftDelete()
	{
		$model = new JobModel();

		$this->setPrivateProperty($model, 'useTimestamps', true);
		$this->setPrivateProperty($model, 'useSoftDeletes', true);

		$model->delete(1);

		$this->seeInDatabase('job', ['id' => 1, 'deleted_at IS NOT NULL' => null]);
	}

	//--------------------------------------------------------------------

	public function testPurgeDeletedWithSoftDeleteFalse()
	{
		$model = new JobModel();

		$this->db->table('job')
				 ->where('id', 1)
				 ->update(['deleted_at' => time()]);

		$model->purgeDeleted();

		$jobs = $model->findAll();

		$this->assertCount(4, $jobs);
	}

	//--------------------------------------------------------------------

	public function testReplaceObject()
	{
		$model = new ValidModel($this->db);

		$data = [
			'id'          => 1,
			'name'        => 'my name',
			'description' => 'some description',
		];

		$model->replace($data);

		$this->seeInDatabase('job', ['id' => 1, 'name' => 'my name']);
	}

	//--------------------------------------------------------------------

	public function testGetValidationMessagesForReplace()
	{
		$job_data = [
			'name'        => 'Comedian',
			'description' => null,
		];

		$model = new JobModel($this->db);

		$this->setPrivateProperty($model, 'validationRules', ['description' => 'required']);

		$this->assertFalse($model->replace($job_data));

		$error = $model->errors();
		$this->assertTrue(isset($error['description']));
	}

	//--------------------------------------------------------------------

	public function testSaveNewEntityWithDateTime()
	{
		$entity    = new class extends Entity{
			protected $id;
			protected $name;
			protected $email;
			protected $country;
			protected $deleted;
			protected $created_at;
			protected $updated_at;

			protected $_options = [
				'datamap' => [],
				'dates'   => [
					'created_at',
					'updated_at',
					'deleted_at',
				],
				'casts'   => [],
			];
		};
		$testModel = new UserModel();

		$entity->name       = 'Mark';
		$entity->email      = 'mark@example.com';
		$entity->country    = 'India';
		$entity->deleted    = 0;
		$entity->created_at = new Time('now');

		$this->setPrivateProperty($testModel, 'useTimestamps', true);

		$this->assertTrue($testModel->save($entity));
	}

	//--------------------------------------------------------------------

	public function testSaveNewEntityWithDate()
	{
		$entity    = new class extends Entity
		{
			protected $id;
			protected $name;
			protected $created_at;
			protected $updated_at;
			protected $_options = [
				'datamap' => [],
				'dates'   => [
					'created_at',
					'updated_at',
					'deleted_at',
				],
				'casts'   => [],
			];
		};
		$testModel = new class extends Model
		{
			protected $table          = 'empty';
			protected $allowedFields  = [
				'name',
			];
			protected $returnType     = 'object';
			protected $useSoftDeletes = true;
			protected $dateFormat     = 'date';
			public $name              = '';
		};

		$entity->name       = 'Mark';
		$entity->created_at = new Time('now');

		$this->setPrivateProperty($testModel, 'useTimestamps', true);

		$this->assertTrue($testModel->save($entity));

		$testModel->truncate();
	}

	//--------------------------------------------------------------------

	public function testUndefinedEntityPropertyReturnsNull()
	{
		$entity = new class extends Entity {};

		$this->assertNull($entity->undefinedProperty);
	}

	//--------------------------------------------------------------------

	public function testInsertArrayWithNoDataException()
	{
		$model = new UserModel();
		$data  = [];
		$this->expectException(DataException::class);
		$this->expectExceptionMessage('There is no data to insert.');
		$model->insert($data);
	}

	//--------------------------------------------------------------------

	public function testUpdateArrayWithNoDataException()
	{
		$model = new EventModel();

		$data = [
			'name'    => 'Foo',
			'email'   => 'foo@example.com',
			'country' => 'US',
			'deleted' => 0,
		];

		$id = $model->insert($data);

		$data = [];

		$this->expectException(DataException::class);
		$this->expectExceptionMessage('There is no data to update.');

		$model->update($id, $data);
	}

	//--------------------------------------------------------------------

	public function testInsertObjectWithNoDataException()
	{
		$model = new UserModel();
		$data  = new \stdClass();
		$this->expectException(DataException::class);
		$this->expectExceptionMessage('There is no data to insert.');
		$model->insert($data);
	}

	//--------------------------------------------------------------------

	public function testUpdateObjectWithNoDataException()
	{
		$model = new EventModel();

		$data = (object) [
							 'name'    => 'Foo',
							 'email'   => 'foo@example.com',
							 'country' => 'US',
							 'deleted' => 0,
						 ];

		$id = $model->insert($data);

		$data = new \stdClass();

		$this->expectException(DataException::class);
		$this->expectExceptionMessage('There is no data to update.');

		$model->update($id, $data);
	}

	//--------------------------------------------------------------------

	public function testInvalidAllowedFieldException()
	{
		$model = new JobModel();

		$data = [
			'name'        => 'Apprentice',
			'description' => 'That thing you do.',
		];

		$this->setPrivateProperty($model, 'allowedFields', []);

		$this->expectException(DataException::class);
		$this->expectExceptionMessage('Allowed fields must be specified for model: Tests\Support\Models\JobModel');

		$model->save($data);
	}

	//--------------------------------------------------------------------

	public function testInvalidEventException()
	{
		$model = new EventModel();

		$data = [
			'name'    => 'Foo',
			'email'   => 'foo@example.com',
			'country' => 'US',
			'deleted' => 0,
		];

		$this->setPrivateProperty($model, 'beforeInsert', ['anotherBeforeInsertMethod']);

		$this->expectException(DataException::class);
		$this->expectExceptionMessage('anotherBeforeInsertMethod is not a valid Model Event callback.');

		$model->insert($data);
	}

	//--------------------------------------------------------------------

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1881
	 */
	public function testSoftDeleteWithTableJoinsFindAll()
	{
		$model = new UserModel();

		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at' => null]);

		$results = $model->join('job', 'job.id = user.id')
			->findAll();

		// Just making sure it didn't throw ambiguous delete error
		$this->assertCount(4, $results);
	}

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1881
	 */
	public function testSoftDeleteWithTableJoinsFind()
	{
		$model = new UserModel();

		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at' => null]);

		$results = $model->join('job', 'job.id = user.id')
						 ->find(1);

		// Just making sure it didn't throw ambiguous deleted error
		$this->assertEquals(1, $results->id);
	}

	/**
	 * @see https://github.com/codeigniter4/CodeIgniter4/issues/1881
	 */
	public function testSoftDeleteWithTableJoinsFirst()
	{
		$model = new UserModel();

		$this->seeInDatabase('user', ['name' => 'Derek Jones', 'deleted_at' => null]);

		$results = $model->join('job', 'job.id = user.id')
						 ->first(1);

		// Just making sure it didn't throw ambiguous deleted error
		$this->assertEquals(1, $results->id);
	}

	//--------------------------------------------------------------------

	public function testMagicIssetTrue()
	{
		$model = new UserModel();

		$this->assertTrue(isset($model->table));
	}

	public function testMagicIssetFalse()
	{
		$model = new UserModel();

		$this->assertFalse(isset($model->foobar));
	}

	public function testMagicIssetWithNewProperty()
	{
		$model = new UserModel();

		$model->flavor = 'chocolate';

		$this->assertTrue(isset($model->flavor));
	}

	public function testMagicIssetFromDb()
	{
		$model = new UserModel();

		$this->assertTrue(isset($model->DBPrefix));
	}

	public function testMagicIssetFromBuilder()
	{
		$model = new UserModel();

		$this->assertTrue(isset($model->QBNoEscape));
	}

	public function testMagicGet()
	{
		$model = new UserModel();

		$this->assertEquals('user', $model->table);
	}

	public function testMagicGetMissing()
	{
		$model = new UserModel();

		$this->assertNull($model->foobar);
	}

	public function testMagicGetFromDB()
	{
		$model = new UserModel();

		$this->assertEquals('utf8', $model->charset);
	}

	public function testMagicGetFromBuilder()
	{
		$model = new UserModel();

		$this->assertIsArray($model->QBNoEscape);
	}

	public function testUndefinedModelMethod()
	{
		$model = new UserModel($this->db);
		$this->expectException(BadMethodCallException::class);
		$this->expectExceptionMessage('Call to undefined method Tests\Support\Models\UserModel::undefinedMethodCall');
		$model->undefinedMethodCall();
	}

	public function testUndefinedMethodInBuilder()
	{
		$model = new JobModel($this->db);

		$model->find(1);

		$this->expectException(BadMethodCallException::class);
		$this->expectExceptionMessage('Call to undefined method Tests\Support\Models\JobModel::getBindings');

		$binds = $model->builder()
			->getBindings();
	}

	/**
	 * @dataProvider provideAggregateAndGroupBy
	 */
	public function testFirstRecoverTempUseSoftDeletes($aggregate, $groupBy)
	{
		$model = new UserModel($this->db);
		$model->delete(1);
		if ($aggregate)
		{
			$model->select('sum(id) as id');
		}

		if ($groupBy)
		{
			$model->groupBy('id');
		}

		$user = $model->withDeleted()->first();
		$this->assertEquals(1, $user->id);

		$user2 = $model->first();
		$this->assertEquals(2, $user2->id);
	}

	public function testcountAllResultsRecoverTempUseSoftDeletes()
	{
		$model = new UserModel($this->db);
		$model->delete(1);
		$this->assertEquals(4, $model->withDeleted()->countAllResults());
		$this->assertEquals(3, $model->countAllResults());
	}

	public function testcountAllResultsFalseWithDeletedTrue()
	{
		$builder     = new BaseBuilder('user', $this->db);
		$expectedSQL = $builder->testMode()->countAllResults();

		$model = new UserModel($this->db);
		$model->delete(1);

		$this->assertEquals(4, $model->withDeleted()->countAllResults(false));

		$this->assertEquals($expectedSQL, (string)$this->db->getLastQuery());

		$this->assertFalse($this->getPrivateProperty($model, 'tempUseSoftDeletes'));

		$this->assertEquals(4, $model->countAllResults());

		$this->assertEquals($expectedSQL, (string)$this->db->getLastQuery());

		$this->assertTrue($this->getPrivateProperty($model, 'tempUseSoftDeletes'));
	}

	public function testcountAllResultsFalseWithDeletedFalse()
	{
		$builder     = new BaseBuilder('user', $this->db);
		$expectedSQL = $builder->testMode()->where('user.deleted_at', null)->countAllResults();

		$model = new UserModel($this->db);
		$model->delete(1);

		$this->assertEquals(3, $model->withDeleted(false)->countAllResults(false));

		$this->assertEquals($expectedSQL, (string)$this->db->getLastQuery());

		$this->assertFalse($this->getPrivateProperty($model, 'tempUseSoftDeletes'));

		$this->assertEquals(3, $model->countAllResults());

		$this->assertEquals($expectedSQL, (string)$this->db->getLastQuery());

		$this->assertTrue($this->getPrivateProperty($model, 'tempUseSoftDeletes'));
	}

	public function testcountAllResultsFalseWithDeletedTrueUseSoftDeletesFalse()
	{
		$builder     = new BaseBuilder('user', $this->db);
		$expectedSQL = $builder->testMode()->countAllResults();

		$model = new UserModel($this->db);
		$model->delete(1);

		$this->setPrivateProperty($model, 'useSoftDeletes', false);

		$this->assertEquals(4, $model->withDeleted()->countAllResults(false));

		$this->assertEquals($expectedSQL, (string)$this->db->getLastQuery());

		$this->assertFalse($this->getPrivateProperty($model, 'tempUseSoftDeletes'));

		$this->assertEquals(4, $model->countAllResults());

		$this->assertEquals($expectedSQL, (string)$this->db->getLastQuery());

		$this->assertFalse($this->getPrivateProperty($model, 'tempUseSoftDeletes'));
	}

	public function testcountAllResultsFalseWithDeletedFalseUseSoftDeletesFalse()
	{
		$builder     = new BaseBuilder('user', $this->db);
		$expectedSQL = $builder->testMode()->where('user.deleted_at', null)->countAllResults();

		$model = new UserModel($this->db);
		$model->delete(1);

		$this->setPrivateProperty($model, 'useSoftDeletes', false);

		$this->assertEquals(3, $model->withDeleted(false)->countAllResults(false));

		$this->assertEquals($expectedSQL, (string)$this->db->getLastQuery());

		$this->assertFalse($this->getPrivateProperty($model, 'tempUseSoftDeletes'));

		$this->assertEquals(3, $model->countAllResults());

		$this->assertEquals($expectedSQL, (string)$this->db->getLastQuery());

		$this->assertFalse($this->getPrivateProperty($model, 'tempUseSoftDeletes'));
	}

}


text:
proposes
Microsoft has distributed a modest bunch of serene specialized articles covering the spic and span rules, yet a portion of those subtleties have moved over the long run. The most extreme span for conceding trademark refreshes, for instance, was eight months when the capacity appeared in November 2015, however shrank to 180 days while in the July 2016 Anniversary Update.
In any event, for those of us who routinely go to IT-centered meetings and hold up with arrangement news, dealing with a Windows-based association in this new time may be befuddling. For the people who are just working with Windows for everyday business, the progressions can show up out of the blue. Alongside the acknowledgment that proven work processes presently don't make a difference isn't agreeing with some IT aces.
To the previous year, I've been hearing a constant flow of grumblings from long-term Windows administrators and clients. Reliably, those protests all reduce to a solitary complaint: Because of "Windows just like a help," we're failing to keep a grip on our work area PCs.
It applied to be that you just could introduce your favored model of Windows and stick with it for almost 10 years. Any time you sent Windows 7 Service Pack one when it was delivered in February 2011, for instance, its list of capabilities has become consistent to the beyond six numerous years and can stay unaltered to the excess 3 numerous long stretches of its upheld life.
While in the new globe, that further develop cycle has contracted to about year and a half, on account of capacity refreshes (the spic and span term for redesigns) that will be conceded yet not rejected. This slide from a Microsoft show shows the help lifecycle for a Windows 10 trait update:
This is the closely guarded secret by and by: If you ought to moved up to Windows ten Pro a solitary year before, in February 2016, you got the most recent delivery, release 1511. A half year after the fact, Microsoft sent off the Anniversary Update, version 1607, for the Present Branch (CB). That adaptation was sent off to your Latest Branch for Online business (CBB) on November 29, 2016.
A choice offered distinctly in partnership variants (Pro/Enterprise/Education) will permit you to concede trademark refreshes until at long last they're delivered towards the Recent Branch for Business undertaking. Utilizing Group Policy, you might concede those updates by an extra eight months in release 1511. That proposes you'll be compelled to improve to adaptation 1607 or later in July 2017, under 18 months later your underlying organization.
Also that update cycle is probably going to get more tight. In rendition 1607, the Group Policy to concede refreshes shrivels from eight months to 180 days, by utilizing a 60-day effortlessness period toward the end. Furthermore, Microsoft has implied that it intends to deliver two element refreshes each year beginning in 2017. The end result is you ought to hope to work on each Computer in your association generally one time per year.
Microsoft, the engineer of Windows working framework, has an enrolled brand name which gives a group of Windows working framework determined for the specific part of registering. Microsoft has assembled Windows for each sort of clients. Windows is the quick working framework, which restricts to give vital necessities and better standard of clients. I […]
In understanding to Hot Hardware, countries surely is the most recent to introduce doubt relating to Microsoft online security arrangements in Windows 10. The 28 specialists that authorize information assurance laws while in the EU are brought together in a so particularly recognized as the substance 29 Working Party. The gathering is grumbling with respect […]
What is Android? Android is an OS (working framework) constrained by Google, used in cell phones and tablet PCs. Working System:- A working framework is the first and central programming that is introduced on your PC, PDA or any electronic contraption. It controls all of the tasks, other programming and mechanical assembly of your PC. […]

redpajama_set_name: RedPajamaCommonCrawl


text:
Q: Redirect After Certain Amount of Time ONLY It Traffic Coming From Particular Source So, I have an ecommerce site, we sell one product only.  We have a high conversion rate via Google Product Listing....however, their policy states that they can only link your ad DIRECTLY to the product page...for obvious reasons...but my company is an exception as we only provide one product..and our homepage is actually a better resource for the product, so we would love to find a way to get more traffic from the product listing campaigns back to the homepage...as we have a high bounce rate with good traffic, despite the strong conversion rate (we think it could be much higher)
I want to know if there's a way to redirect people from the product page back to our homepage after a certain amount of time.....but ONLY for traffic coming from the google PLA campaign.
Any suggestions would be helpful (aside from "make your product page better")
Thanks guys!
Gary

A: Try with something like that:
if(document.referrer.indexOf("http:urlYouwantToRedirect.com/path") > -1){
    document.location.href = "http:redirection.com";
}

redpajama_set_name: RedPajamaStackExchange


Thank you for making a gift to ACPM!
ACPM is dedicated to advancing the profession of preventive medicine through education, advocacy and professional development. Ultimately, your support helps us pursue our shared goal of preventing disease and promoting health and wellbeing among individuals and populations. Thank you for your support and generosity.
If you need assistance with your donation, please contact Margaret Tran at mtran@acpm.org or 1-202-466-2044, Ext. 123.
If you prefer to make a contribution by check, please print and complete this donation form and mail it to ACPM, 455 Massachusetts Avenue NW, Suite 200, Washington, DC 20001.


text:
> Document 2/74/1 (_Glas. Reg._, no. 98)
Permalink: www.poms.ac.uk/record/source/2228/
Document 2/74/1 (Glas. Reg., no. 98)
Abbot Nigel and convent of Kilwinning for their lord, Florence, bishop-elect of Glasgow; have given three stones of wax annually to be paid within the octave of St James the Apostle, at Roxburgh.
18 September 1202 X 15 May 1207
Postulation of Bishop William Malveisin to bishopric of St Andrews × resignation of Bishop-elect Florence
Glasgow Registrum, i, no. 98
Glas. Reg., no. 98
18 Sept. 1202 X 15 May 1207 Gift of three stones of wax yes Alexander, chaplain of Bishop Walter of Glasgow; David, person of Stevenston; Herbert, dean of Glasgow (fl.1179×89-1204×07); Idel, chaplain of Official John of Huntingdon; John of Huntingdon, master, official of Glasgow (fl.1179×1208); Michael, clerk of Dean Herbert of Glasgow; Robert of Heddon, master; Robert, archdeacon of Glasgow (d.1222); William, dean of Cunningham (d.1211)
18 Sept. 1202 X 15 May 1207 Clerk of Herbert, dean of Glasgow (fl.1179×89-1204×07)(Employment relationship) Michael, clerk of Dean Herbert of Glasgow Herbert, dean of Glasgow (fl.1179×89-1204×07)
18 Sept. 1202 X 15 May 1207 Lord (dominus) of Niall, abbot of Kilwinning (fl.1201-10)(Tenurial & lordship relationship) Florence, bishop-elect of Glasgow (d.1210) Nigellus (Níall), abbot of Kilwinning (fl.1201-10)
18 Sept. 1202 X 15 May 1207 abbot of Kilwinning Nigellus (Níall), abbot of Kilwinning (fl.1201-10)
18 Sept. 1202 X 15 May 1207 Dominus (Lord/Sir) Florence, bishop-elect of Glasgow (d.1210)
18 Sept. 1202 X 15 May 1207 bishop-elect Florence, bishop-elect of Glasgow (d.1210)
18 Sept. 1202 X 15 May 1207 dean of Glasgow Herbert, dean of Glasgow (fl.1179×89-1204×07)
18 Sept. 1202 X 15 May 1207 Dominus (Lord/Sir) Robert, archdeacon of Glasgow (d.1222)
18 Sept. 1202 X 15 May 1207 archdeacon of Glasgow Robert, archdeacon of Glasgow (d.1222)
18 Sept. 1202 X 15 May 1207 Dominus (Lord/Sir) John of Huntingdon, master, official of Glasgow (fl.1179×1208)
18 Sept. 1202 X 15 May 1207 official John of Huntingdon, master, official of Glasgow (fl.1179×1208)
18 Sept. 1202 X 15 May 1207 Master Robert of Heddon, master
18 Sept. 1202 X 15 May 1207 dean of Cunningham William, dean of Cunningham (d.1211)
18 Sept. 1202 X 15 May 1207 chaplain Alexander, chaplain of Bishop Walter of Glasgow
18 Sept. 1202 X 15 May 1207 chaplain Idel, chaplain of Official John of Huntingdon
18 Sept. 1202 X 15 May 1207 persona of Stevenston David, person of Stevenston
18 Sept. 1202 X 15 May 1207 clerk (dean's) Michael, clerk of Dean Herbert of Glasgow


text:
Cemetery Vandalism
Back around 1998, it wasn't as acceptable as it is in 2010 to walk around cemeteries taking pictures, at least in Philadelphia. Many cemeteries had been left to ruin and the rebuilding and re-branding of these Victorian era memorial parks as tourist destinations wasn't yet a national movement. In 1998, Historic Laurel Hill Cemetery (near Ridge Ave. and Roosevelt Blvd.) became a Certified National Historic Landmark--one of the few cemeteries in the United States to earn that designation.
But as I say, around 1998, these operations were still trying to figure out how to find the money to stem the vandalism and restore essentially a grand Victorian sculpture garden to its original splendor. The image you see above is a life-sized granite monument from Laurel Hill, depicting the Angel of Death opening a coffin lid and releasing the spirit of the newly departed to the heavens. It was sculpted by Alexander Calder, great grandfather of the famous mobile sculptor. The former Calder also sculpted the enormous William Penn statue that tops Philadelphia's City Hall (in 1893).
When I originally discovered this wonderful snow-covered statue in 1998 (known as the Warner Memorial), I was with my daughter. As we were photographing it, a park ranger came up to us and asked if we had signed in at the gatehouse. We had not. He asked for my drivers' license! As he copied down the information I nervously asked why. He told me people come into the cemetery, photograph what they want stolen, then give the photos to thieves. The thieves enter the cemetery at night and vandalize statues, ironwork, and mausoleums, breaking pieces off statues (note in the photo above that both of the statue's forearms are missing) and removing stained glass to be sold on the black market. Laurel Hill originally had seven Tiffany stained glass windows in various mausoleums, all of which were stolen in the 1970s. Such windows have been known to sell for over half a million dollars apiece in black market auctions! There are actually authorities that track such stolen artwork (e.g. Interpol, see link below).
With all this going on, it should become apparent that there really might be actual danger facing you if you venture into a cemetery at night. It's not uncommon (at least in Philadelphia) to see bullet holes in mausoleum windows. Recently a local mausoleum was broken into, with the iron door violently bent and broken.Thieves likely broke in to see what there was to steal. You always hear about people being buried with their jewelry, etc., and it doesn't take a rocket scientist to realize that only the wealthy can afford elaborate mausoleums. What the thieves don't realize, however, is that the ironwork of the gates and doors that they break are probably more valuable than anything inside!
Why are such artifacts of value? Aside from the fact that funerary sculpture, ironwork, and stained glass have aesthetic and historical value, there just isn't that much of it around. Not because its been stolen or vandalized, but because much of it was removed by family plot owners in the 1920s! People forget that the avant garde of the 1920s was Art Deco. Ornate Victorian design was viewed as being too gaudy, elaborate, and dated. In essence, an embarassment to the owners! Families would remove and discard such beautiful ironwork as this harp-shaped gate, along with all the associated fencing surrounding a dynasty plot.
Got Stolen Art?
For more information on theft of cemetery art, please see my interview with Ross Mitchell, then the Director of the Laurel Hill Cemetery, on my StoneAngels website.
Posted by StoneAngels: The Cemetery Traveler at 10:28 AM No comments:
Labels: Angel of Death, Laurel Hill Cemetery


text: Q: Is there a way to list the last date that a Notebook was run in Databricks? So I can identify and delete unused Notebooks? Is there a way to list the last date that a Notebook was run in Databricks?  So I can identify and delete unused Notebooks?


text:
<!DOCTYPE frameset SYSTEM "frameset.dtd">
<frameset>
    <predicate lemma="expose">
        <note>
            Frames file for 'expose' based on sentences in financial subcorpus.
            No Verbnet entry, no Framenet entry.  Comparison to show.
        </note>

        <roleset id="expose.01" name="cause to be visible" vncls="48.1.2">
            <roles>
                <role descr="exposer" n="0">
                    <vnrole vncls="48.1.2" vntheta="Agent"/>
                </role>
                <role descr="thing seen/shown" n="1">
                    <vnrole vncls="48.1.2" vntheta="Theme"/>
                </role>
                <role descr="seer" n="2">
                    <vnrole vncls="48.1.1" vntheta="Recipient"/>
                </role>
            </roles>

            <example name="passive, with seer">
                <inflection aspect="ns" form="participle" person="ns" tense="present" voice="passive"/>
                <text>
                    Also, it-1 isn't exposed *trace*-1 to the weakening newsprint
                    business, and is strong in the less-cyclical tissue business.
                </text>
                <arg f="DIS" n="M">Also</arg>
                <arg f="NEG" n="M">n't</arg>
                <rel>exposed</rel>
                <arg n="1">*trace*</arg>
                <arg n="2">to the weakening newsprint business</arg>
            </example>

            <example name="active, no seer">
                <inflection aspect="ns" form="full" person="ns" tense="past" voice="active"/>
                <text>
                    The predicament, he added, was similar to the Hong Kong 1982-83
                    property-price collapse, which *trace* exposed the involvement of
                    Bank Bumiputra's former subsidiary in the colony in the largest
                    banking scandal in Malaysia's history.
                </text>
                <arg n="0">*trace*</arg>
                <arg n="M" f="RCL">which ->  the Hong Kong 1982-83
                    property-price collapse
                </arg>
                <rel>exposed</rel>
                <arg n="1">the involvement of Bank Bumiputra's former
                    subsidiary in the colony in the largest banking scandal in
                    Malaysia's history
                </arg>
            </example>

            <note>
            </note>

        </roleset>
    </predicate>
</frameset>

redpajama_set_name: RedPajamaGithub


text:
VI. North Korea's nucl...
Shannon N. Kile
In 2010 no progress was made towards restarting the suspended Six-Party Talks over the future of North Korea's nuclear weapon programme.118 The talks had broken down in April 2009, when North Korea announced that it had permanently withdrawn from the negotiations and would no longer be bound by any previous agreements. At the same time, North Korea expelled IAEA inspectors from the country and informed the agency that it would restart its nuclear weapon production facilities at Yongbyon.119
Kile, Shannon N.. "8. Nuclear arms control and non-proliferation." SIPRI Yearbook. SIPRI. Oxford: Oxford University Press. 2016. Web. 18 Jan. 2020. <https://www.sipriyearbook.org/view/9780199695522/sipri-9780199695522-div1-91.xml>.
Kile, S. (2016). 8. Nuclear arms control and non-proliferation. In SIPRI, SIPRI Yearbook 2011: Armaments, Disarmament and International Security. Oxford: Oxford University Press. Retrieved 18 Jan. 2020, from https://www.sipriyearbook.org/view/9780199695522/sipri-9780199695522-div1-91.xml
Kile, Shannon N.. "8. Nuclear arms control and non-proliferation." In SIPRI Yearbook 2011: Armaments, Disarmament and International Security, SIPRI. (Oxford: Oxford University Press, 2016). Retrieved 18 Jan. 2020, from https://www.sipriyearbook.org/view/9780199695522/sipri-9780199695522-div1-91.xml


text:
Please DONATE to help with maintenance and upkeep of the Wind Repertory Project!
Mise Éire
From Wind Repertory Project
Seán Ó Riada
This article is a stub. If you can help add information to it,
please join the WRP and visit the FAQ (left sidebar) for information.
The title translates from the Gaelic as "I Am Ireland."
1 General Info
3 Errata
4 Program Notes
6 State Ratings
8 Works for Winds by This Composer
Duration: c. 3:30
Difficulty: (see Ratings for explanation)
Publisher: Unknown
Cost: Score and Parts - Unknown
(Needed - please join the WRP if you can help.)
None discovered thus far.
Mise Éire (Irish for "I [am] Ireland") is a 1912 Irish-language poem by the Irish poet and Republican revolutionary leader Patrick Pearse. In the poem, Pearse personifies Ireland as an old woman whose glory is past and who has been sold by her children. The title of the poem was used as a title for a 1959 documentary film by George Morrison, which dealt with key figures and events in Irish Nationalism between the 1890s and the 1910s, including Pearse himself. A poem of the same name by Eavan Boland was written as a counter to Pearse's poem, and its treatment of Ireland and her children.
Seán Ó Riada composed and directed orchestral music for theatre and film, combining traditional Irish tunes and "sean-nós" (old style) songs in the classical tradition, similar to noted nationalist composers such as Dvořák (Czech), Bartók (Hungarian) and Ralph Vaughan Williams (English).
In 1959 he scored a documentary film by George Morrison called Mise Éire ("I am Ireland"), about the founding of the Irish Republic. The recording is conducted by Ó Riada himself. Mise Éire brought him national acclaim and allowed him to start a series of programmes on Irish radio called Our Musical Heritage. Ó Riada told people that one should listen to sean-nós song either as a child would listen or as if they were songs from India.
In 2016, the Pearse poem was translated to song for the score of the PBS documentary series 1916: An Irish Rebellion, curated by the Keough-Naughton Institute for Irish Studies at the University of Notre Dame. The song, also titled Mise Éire, was composed by Patrick Cassidy and performed by the RTÉ Concert Orchestra with vocals by Sibéal Ní Chasaide.
- Program Note from Wikipedia
State Ratings
To submit a performance please join The Wind Repertory Project
Washington and Lee University (Lexington, Va.) Wind Ensemble (R. Wayne Gallops, conductor) – 1 November 2016
Works for Winds by This Composer
Mise Éire (1959)
Mise Éire, Wikipedia Accessed 1 November 2016
Retrieved from "https://www.windrep.org/index.php?title=Mise_Éire&oldid=278004"
Composition Awards
Small Band Initiative
State Music Lists
About WRP
About Wind Repertory Project


text:
Book three of 'True Cover' series now available in Hillsdale
By Nancy Hastings
Twitter: @nhastingsHDN
HILLSDALE — Author Ruth Kyser is excited to announce her newest Christian inspirational novel, "Second Chances" — book three in the "True Cover" series, is now available at Vintage Chic Gift Shop, Hillsdale.
The shipment of paperbacks arrived recently, and Vintage Chic in downtown Hillsdale now has copies of all six of her books.
"It's the only place locally to get them," Kyser said.
Kyser was born in Michigan and moved to Hillsdale in 1969, graduating from Hillsdale High School in 1972. A current Hillsdale County resident, she and her husband, Alan, have two children and eight grandchildren.
She began writing early in life, but became serious about it around 20 years ago, when she published an e-book through an Internet e-book publisher. She later began to self-publish her books and encourages others to do the same.
"I always have a story building in my head," Kyser said, noting she loves doing research for her characters.
For her latest book, she traveled to Tennessee, where she hadn't been in 40 years, to get a feel for the setting. She plans to start another series based on a character named Sam and his ancestors. The new series is projected for 2015.
"I've actually been told that the series I've done should be a movie," Kyser said. "And radio personality Bob Flynn wants a cameo."
If that were to transpire, another local vying for a part is Crystal Giminez, co-owner of Vintage Chic Gift Shop. Giminez said she's reading book three of the "True Cover" series and can't put it down.
"You feel like you're a part of what's happening and it reminds you of places you've been," Giminez said.
Giminez would like to feature other local authors in her store as well. She and her mother, Karen Wilkin, sell hand-crafted items from local people, as well as furniture. She has Kyser's books on display near the entrance since they've been a big hit with customers, who've also become hooked on the books.
Kyser said the biggest compliment a writer can receive is for readers to say they can envision the characters.
"I like to give just enough information for them to use their imagination," Kyser said.
Readers can also find all six books available at Amazon.com and five at Barnes&Noble.com.
"My most recent one, 'Second Chances,' won't be available at Barnes&Noble.com for Nook until the first part of August, 2014," Kyser said.
Since "Second Chances" was published in early May, it has been in the Top 100 category for fiction and religious inspirational for Kindle most of the month of May and has received excellent reviews, Kyser said. It has also been listed in the Top 100 in the United Kingdom for the same category for Kindle.
"I've been very pleased with the local community's support of my books through the sales at Vintage Chic on Howell Street in downtown Hillsdale," Kyser said. "I'm very thankful for Crystal Gimenez and Karen Wilkin for giving me the opportunity to showcase my books in paperback in their beautiful store."
Kyser hopes to have more time to spend this summer with her family and also to work on her latest book in progress, another Christian Inspirational Novel set in the mountains of Tennessee.
"I'm getting to know my new characters, their hopes, dreams, and flaws – and have already fallen in love with their story," she said. "I'm hoping my readers will love them also!"


'Every day I just wake up and figure out how I can make myself better,' D.C. rapper says.
In 2009, we expect to hear big things from some up-and-coming rappers in the game. Each day we'll profile a new artist that we think you should keep your eyes and ears open for in the coming year. On Monday we brought you Atlanta's very own, very different B.o.B. — now we have D.C.'s best-kept secret, Wale.
[artist id="510062"]Lil Wayne[/artist], have claimed that title, but think about it: Before James played one game in the NBA, he was on the cover of Sports Illustrated, and ESPN broadcast his high school games. Wale has yet to release an album, but this is his second feature with MTV News.
James had various companies — including Nike — champing at the bit, waiting for him to graduate. Wale has appeared in ads for nearly every streetwear brand — including Nike — waiting for him to blow. They have both traveled the world, but they still rep their hometowns big-time (Cleveland Cavalier LeBron is from Akron, but it's close to Cleveland).
LeBron handled the pressure of being the "next big thing" better than anyone would have imagined, and Wale is taking it in stride as well.
"I really try not to get involved with thinking I'm the next big thing because it's, like, I've been doing this," said the Washington, D.C., rapper said. "Every day I just wake up and I figure out how I can make myself better."
Wale says he takes everything day-by-day — that before he sells a million records, he wants to remain the same person he was at the age of 15, running around D.C. and Maryland, just older and wiser.
Despite all the touring, D.C. hasn't left him. In fact, he brings his hometown to every show, because Wale's band is a go-go band — go-go music originated in D.C. in the mid-'70s, and is a staple of the region.
"Go-go music is essentially jazz on steroids," Wale explained. "That's what I like to think of it as. It's swing. It's heavy on the percussion.
"A lot of people have bands re-create their tracks 100 percent of the way, exactly how you hear it on the radio," he continued. "When we do my show, we twist the song a little bit, because we want to give the people something extra."
Wale says his band's signature sound has created a show those outside the D.C. area are not accustomed to. He attributed the show's success to the fact that he learned under the guidance of world-renowned DJ [artist id="1208352"]Mark Ronson[/artist].
"Mark gives me a whole different way to appreciate music," he said. "Especially going into my live show, I know what to want now. I know what to ask for and I know what to aim for."
While he hasn't released an album, the popularity of his Mixtape About Nothing has helped Wale establish his music outside of the mid-Atlantic region.
[artist id="1269"]Jay-Z[/artist] or the next [artist id="1000"]Nas[/artist]. I want my shows to be legendary like [artist id="900"]Daft Punk [/artist]shows, like [artist id="2455063"]Justice[/artist] shows."
Also check out Asher Roth, Kid Cudi, B.o.B. and Charles Hamilton in our "MCs to Watch in '09" series.


The mysteries of numerology... madness or reality?
Was the number 9 really significant in John Lennons life & death.... or is it just mumbo jumbo?
We have a thread on this somewhere but i cant find it.
I think this is what you are thinking about, mmm.
Joe's page on John Lennon and the number nine.
No but since i cant find it anywhere maybe i dreamed its existence. Who knows.
Is this what you were thinking about, mmm?
Nope. I did a google search and found the ones you linked to but not the one i'm thinking of. Maybe it was another forum, have no idea.
Yeah, that's all I could find in this forum.
Well if you can't no one here can. Thanks for looking.
I think there is some thing to numerology is similar to astrology. I did mine and got the number 9 which is weird because it has followed me around. You just ad up your birth date so example mine is 10/17/1989, 10=1, 1+7=8, 1+9=1, 8+9=17, 1=7=8 then ad all those up and reduce 8+8+1+1=18=1+8=9 for the life path which is birthdate. Usually they consider your 4 core numbers as the most important birthdate which is life path, destiny which is your names letters converted to numbers then added and reduced as I did above with birthdate, then your birthday day number is one of your core then your expression number which is the addition and reduction of the vowels in your full name. Interesting stuff me and my friends did it and it was all spot on.
"nine!!" shouted before the song.
"You just ad up your birth date so example mine is 10/17/1989, 10=1, 1+7=8, 1+9=1, 8+9=17, 1=7=8 then ad all those up and reduce 8+8+1+1=18=1+8=9 for the life path which is birthdate."
But why not for the year part add it this way: 1+9 (=10) + 8 (=18) + 9 (=27). Then you would have 9+9 = 18 which (1+8) resolves down to 9.
"I lived in 9 Newcastle Road. I was born on the ninth of October, the ninth month [sic]."


Double Consonant Endings (ll, Ss, Ff, Zz) Word Search By . Ss Ll Zz Ff Phonics Double Letters Youtube .. This word search on the ll, ss, ff, and zz double consonant endings also doubles as a coloring sheet! The solution to the puzzle is included. Vocabulary Terms Included: ♦ Ball ♦ Doll ♦ Bell. Double Constant Ending Worksheet Ll, Ff, Ss, Zz By Joop09 ... This website and its content is subject to our Terms and Conditions. Tes Global Ltd is registered in England (Company No 02017289) with its registered office at 26 Red Lion Square London WC1R 4HQ.
Double Consonant Endings (ll, Ss, Ff, Zz) Word Search By ... This word search on the ll, ss, ff, and zz double consonant endings also doubles as a coloring sheet! The solution to the puzzle is included. Vocabulary Terms Included: ♦ Ball ♦ Doll ♦ Bell. Double Constant Ending Worksheet Ll, Ff, Ss, Zz By Joop09 ... This website and its content is subject to our Terms and Conditions. Tes Global Ltd is registered in England (Company No 02017289) with its registered office at 26 Red Lion Square London WC1R 4HQ.
Words Ending In Double Letters Ff Ll Ss Zz Worksheets ... Words Ending In Double Letters Ff Ll Ss Zz. Showing top 8 worksheets in the category - Words Ending In Double Letters Ff Ll Ss Zz. Some of the worksheets displayed are Step 18 ff ll and ss, Floss word list, Double f s l and z, Learning happens when its fun, Words of one syllable ending in f l s or z usually end, Copywork passages, Phonics, Plurals. Words Ending In Double Letters Ff Ll Ss Zz Worksheets ... Words Ending In Double Letters Ff Ll Ss Zz. Showing top 8 worksheets in the category - Words Ending In Double Letters Ff Ll Ss Zz. Some of the worksheets displayed are Step 18 ff ll and ss, Floss word list, Double f s l and z, Learning happens when its fun, Words of one syllable ending in f l s or z usually end, Copywork passages, Phonics, Plurals.
Phonics Phase 2 Ff Ll Ss I-spy Treasure Hunt Game - Eyfs ... Play this fun phonics game to encourage children to practise identifying letter sounds. This resource focuses on the Phase 2 sounds: ff, ll and ss. Hide the picture cards around your setting and challenge children to find and draw the pictures next to the correct letter sound. A great way to practise phonics and have some fun. Bonus Letters Ll Ff Ss Worksheets - Printable Worksheets Bonus Letters Ll Ff Ss. Showing top 8 worksheets in the category - Bonus Letters Ll Ff Ss. Some of the worksheets displayed are Step 18 ff ll and ss, English spelling rules work, Ff ll ss zz, Level 2 sample, Spelling unit 15, Critical thinking skills for boxed words mixed up words, Chapter 1 closed syllable 21 lessons out of 30, Reading for life volume 1.
The Synthetic Phonics Sequence - Get Reading Right The Get Reading Right program follows a synthetic phonics teaching sequence which will take 2-3 years to complete. Here, we break down the sequence. Preschool Phonics Song Lessons Learn the 26 letters and 26 sounds of the alphabet through song. Also, learn how to write uppercase and lowercase letters. These lessons are excellent for teaching a combination of preschool and early kindergartener phonics skills.


The theme uses the WordPress Customizer feature for it's global/theme options. Customizer is a native WordPress feature which was added to WordPress back in 2012, so if you've ever used WordPress you won't have any problems.
You can access the customizer at WP Admin → Appearance → Customize.
To change the text on the logo or set an image logo go to the Identity section of Customizer. If setting an image logo make sure to uncheck the checkbox "Display Site Title and Tagline".
Site Title: This is the website name, it will appear if a logo is not available.
You can add a logo instead of the Site Title in Appearance → Theme Options.
Tagline: This is a short description of your site, which will appear under the logo or site title.
This section will allow you to manage navigation menus, such as the main theme navigation in the header. For more information regarding theme menus, please read the Menu chapter.
This section will allow you to manage all widgets areas and to add, remove or edit widgets. For more info regarding the widgets please read the Widgets chapter.
In the social URLs section of the theme options, you can set the URLs to your social website profiles. They will be used for the social elements/icons in the social widget.
In the toolbar section, you can change/add Search and Social Media.
In the footer section of the theme options, you can change the copyright text.
In the other section of the theme options are miscellaneous options such as changing the layout on search and archive pages.


That's the brutally honest opinion of Australian great Mark Waugh on battling opener Aaron Finch after the Victorian failed miserably in his first Test on home soil.
Finch managed just 11 runs in an underwhelming Adelaide performance and was lucky he didn't walk away with a pair as replays showed Ishant Sharma had bowled a no-ball by the barest of margins in the second innings.
Not even a second chance could save him and nor could the DRS after he opted to walk just before tea when it became evident on hot-spot that his bat missed a dipping Ravichandran Ashwin delivery.
Pressure is mounting on the 32-year-old, so too the entire Australian batting line-up, to respond in Perth before jobs quickly become in danger.
Waugh isn't expecting any changes to the current team, but he suggested Finch may be a better fit lower down the order in a position where he has spent most of his red-ball career at.
''He was saved by the DRS and remarkably didn't use the DRS when he should have in the second innings,'' Waugh told Sky Sports' Big Sports Breakfast.
''He didn't look that comfortable to be honest. I probably don't think he's an opener at Test level in Australia.
''I'd say the Australian selectors and the team management will stick with the order. I don't think they'll want to change after one Test.
''He'll have another chance. Hopefully he can get through that new ball and make some runs.
Waugh's crticism comes after former Australian skipper Ricky Ponting took aim at Finch for cheaply giving away his wicket just three balls into the first innings.
"I think the shot we saw today is not what a good Test match opener would do third ball of his innings," Ponting told cricket.com.au.
"The new ball on that wicket was always going to be the hardest time to bat.
"He's got a lot of work to do I think.
"I spoke to Graeme Hick in the drinks break in the second innings to ask what were the things they're working on to try and turn him into a good consistent Test match opener.
"I'm not here to bag or pot anyone about the way things are happening but you look at some of the shot selection today and it just makes you wonder a little bit."


text:
Bistum Warschau steht für:

 Erzbistum Warschau, römisch-katholisch (bis 1818 Bistum)
 Bistum Warschau-Praga, römisch-katholische Diözese
 Diözese Warschau, Evangelisch-Augsburgische (lutherische) Kirche in Polen
 Bistum Warschau (polnisch-katholisch), Polnisch-Katholische Kirche
 Erzdiözese Warschau-Bielsk Podlaski, Polnisch-Orthodoxe Kirche
 Erzeparchie Przemyśl-Warschau, ukrainische griechisch-katholische Kirche
 Diözese Warschau-Płock, Altkatholische Kirche der Mariaviten

redpajama_set_name: RedPajamaWikipedia


The six elementary schools in the Union School District lacked adequate space for hands-on learning and makerspace activities. To solve this problem, QKA designed an identical 1,920 square foot STEAM (science, technology, engineering, art, and mathematics) building on each school site that links to each school's existing Media Center via the creation of a new outdoor learning area. These outdoor learning spaces allow maker activities to be conducted outside, as well as provide space for individual, small group, and large group activities.
On the interior, each STEAM building is designed for flexibility, utilizing operable partitions to create either one large classroom or two separate activity spaces, a green screen/breakout space, moveable furniture, and floor-to-ceiling sliding doors that open up to the outdoor learning area. Additionally, the buildings were specially designed to be sustainable – equipped to be energy-efficient, they feature natural lighting, high quality indoor air and acoustics, and optimal thermal comfort.


text:
A record 65.3 million people were displaced last year: What does that number actually mean?
The need to divide "good" from "bad" renders the insecurities that drive migrants and refugees to move moot
By Jeffrey H. Cohen - Ibrahim Sirkeci
August 1, 2016 12:58PM (UTC)
In this photo released by the United Nations Mission in South Sudan (UNMISS), children wait to be served with roasted maize in a refugee camp Juba, South Sudan Friday July 22, 2016 . The United Nations refugee agency says thousands of people continue to flee South Sudan over violence between armed groups in the country, stretching the capacity of humanitarian efforts to look after the refugees. () (Isaac Billy UNMISS via AP)
We continue to witness violent attacks — bombings and murders in France, Germany, Turkey, Afghanistan and Iraq, and fighting in South Sudan and the continued civil war in Syria. These conflicts have renewed interest in the global refugee crisis and the movements of displaced persons around the globe.
The United Nations Human Rights Council announced in June that 65.3 million people were forcibly displaced from their homes in 2015. This is a record number and is equal in population to the United Kingdom or France.
People who have been forced to leave their homes, their nations and occupation against their will are often referred to as "displaced." And 65.3 million is a lot of displaced people. They are found across the globe in response to crises that range from the social to the environmental and include Syrian refugees fleeing civil war, Central American children crossing international borders to reach family and security in the United States, Colombians moving internally to avoid warfare and violence, and Filipinos who are forced to relocate in response to changing climates and environmental disasters.
The UNHRC's report identifies important global patterns that we must acknowledge. But, the overwhelming size of the displaced population reported confounds a complex issue and creates new fears. The numbers overwhelm and make it difficult to define potential solutions.
Conflict, insecurity and migration
In our book, "Cultures of Migration," we argue that all migrants, including refugees, face conflicts and insecurities. Conflicts and insecurity can be physical and violent as in the Syrian civil war or nonmaterial and discriminatory and based in social and cultural differences. These nonmaterial challenges included those faced by migrants and refugees as they settle in Europe and the United States. Insecurity complicates migration, and migration is no longer a decision made to in response to finding a good job or access to high wages. Migration, forced or otherwise, is complex and challenging. There is no guarantee of success, and over time new conflicts and insecurities arise.
Displaced people, like all migrants, balance conflicts and insecurities at places of origin and of destination. Two examples help illustrate our point. Since 2011 Syrian refugees have fled violence and civil war. Yet their desire to leave has a long history, and reflects dissatisfaction with the Assad regime, restrictive national laws and a weak economy.
In Sudan, refugees fled their homelands to escape violence during more than 40 years of civil war between South and North over food, natural resources, religion and political control. In 2013, a new civil war in the south brought a crisis, creating more than one million refugees fleeing the violence associated with the political struggles between competing strongmen.
Big numbers
Thinking in large numbers abstracts the challenges, conflicts and insecurities that displaced people face. About half of the world's refugees are living under the UNHCR's mandate and protection in Afghanistan and Somalia. Nevertheless, it is people fleeing smaller crises like the coup in Turkey, the drought in Central Asia and religious persecution in Myanmar among others that make up many of the displaced. In addition, more than 40 million refugees remain within their native homelands, including Colombians, Iraqis and South Sudanese who are fleeing their villages to escape violence, warfare and religious persecution.
How do we comprehend 65.3 million displaced people when they have little in common?
It is hard to envision so many displaced people. The mathematician Spencer Greenberg notes we have no problem thinking in small numbers. Even 100 things — a large crowd, for example — is manageable. Nevertheless, "when we're talking about millions of things our ability to visualize completely fails."
To cope, we use metaphors in place of statistics. Often, displaced people are described as waves crashing upon the beach or spreading like a cancer.
Critics who exaggerate the numbers of displaced people and refugees overwhelm and terrify their audience. Donald Trump warns U.S. citizens to lock their doors, lest they fall victim to terror. Milos Zeman, the Czech president, describes the movement of refugees to Europe as an "organized invasion." These arguments deny the realities that the displaced and refugees face and prey on a shared fear of outsiders.
Good, bad and the morality of migration
One way to confront our fears of large numbers is to reduce them to discrete, manageable categories. However, categories typically carry judgments and create expectations. And too often in the discussion of refugees the categories divide people into "good" and "bad" groups based in shared perceptions, and what Stephanie Pappas calls our "caveman instincts."
"Good" refugees are the people who flee their homelands to avoid violence and seek shelter and a new way of life. "Bad" refugees threaten our shared values and lifestyle.
The differences that define "good" and "bad" refugees misrepresent the conflicts that motivate movement. The need to divide "good" from "bad" renders the civil, social and environmental insecurities that drive migrants and refugees to move moot.
Victoria Armour-Hileman writes, "if the world measures a refugee according to the worst story, we will always excuse human suffering, saying it is not yet as bad as someone else's."
Knowing the numbers of displaced people globally captures the size of the crises driving people from their homes. However, it is more important to focus on the conflicts and insecurities that define specific crises. By identifying the causes of forced relocation, we can better address the outcomes and build toward solutions.
Jeffrey H. Cohen is a professor of Anthropology at the Ohio State University. Ibrahim Sirkeci is a professor of Transnational Studies and Marketing and Director of Regent's Centre for Transnational Studies at Regent's University London.
Jeffrey H. Cohen
MORE FROM Jeffrey H. Cohen
Ibrahim Sirkeci
MORE FROM Ibrahim Sirkeci
Donald Trump France Migration Refugees Syria Terror The Conversation