Commit c9edea3d by AlexGx

merge

parents 32d07689 10f1283d
...@@ -45,5 +45,7 @@ script: ...@@ -45,5 +45,7 @@ script:
- cd apps/basic && php vendor/bin/codecept run - cd apps/basic && php vendor/bin/codecept run
after_script: after_script:
- cd ../..
- pwd
- wget https://scrutinizer-ci.com/ocular.phar - wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
...@@ -381,6 +381,7 @@ the `self` link, for example: ...@@ -381,6 +381,7 @@ the `self` link, for example:
```php ```php
use yii\db\ActiveRecord; use yii\db\ActiveRecord;
use yii\web\Link;
use yii\web\Linkable; use yii\web\Linkable;
use yii\helpers\Url; use yii\helpers\Url;
......
...@@ -93,7 +93,7 @@ class ApiMarkdown extends GithubMarkdown ...@@ -93,7 +93,7 @@ class ApiMarkdown extends GithubMarkdown
} }
} }
protected function highlight($code, $language) public static function highlight($code, $language)
{ {
if ($language !== 'php') { if ($language !== 'php') {
return htmlspecialchars($code, ENT_NOQUOTES, 'UTF-8'); return htmlspecialchars($code, ENT_NOQUOTES, 'UTF-8');
......
...@@ -58,3 +58,8 @@ blockquote { ...@@ -58,3 +58,8 @@ blockquote {
td p { td p {
margin: 0; margin: 0;
} }
table.detailTable .paramNameCol { width: 15%; min-width: 100px; }
table.detailTable .paramTypeCol { width: 15%; min-width: 150px; }
table.detailTable .paramDescCol { width: 70%; }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace yii\apidoc\templates\html; namespace yii\apidoc\templates\html;
use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\MethodDoc; use yii\apidoc\models\MethodDoc;
use yii\apidoc\models\PropertyDoc; use yii\apidoc\models\PropertyDoc;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
...@@ -225,7 +226,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface ...@@ -225,7 +226,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface
} }
return implode('<br />', $sig); return implode('<br />', $sig);
} }
return $this->createTypeLink($property->types) . ' ' . $property->name . ' = ' . ($property->defaultValue === null ? 'null' : $property->defaultValue); return $this->createTypeLink($property->types) . ' ' . $this->createSubjectLink($property, $property->name) . ' '
. ApiMarkdown::highlight('= ' . ($property->defaultValue === null ? 'null' : $property->defaultValue), 'php');
} }
/** /**
...@@ -244,9 +246,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface ...@@ -244,9 +246,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface
return ($method->isReturnByReference ? '<b>&</b>' : '') return ($method->isReturnByReference ? '<b>&</b>' : '')
. ($method->returnType === null ? 'void' : $this->createTypeLink($method->returnTypes)) . ($method->returnType === null ? 'void' : $this->createTypeLink($method->returnTypes))
. ' ' . $this->createSubjectLink($method, $method->name) . '( ' . ' ' . $this->createSubjectLink($method, $method->name)
. implode(', ', $params) . ApiMarkdown::highlight('( ' . implode(', ', $params) . ' )', 'php');
. ' )';
} }
public function generateApiUrl($typeName) public function generateApiUrl($typeName)
......
...@@ -34,28 +34,28 @@ ArrayHelper::multisort($methods, 'name'); ...@@ -34,28 +34,28 @@ ArrayHelper::multisort($methods, 'name');
</span> </span>
</div> </div>
<table class="summaryTable table table-striped table-bordered table-hover"> <table class="detailTable table table-striped table-bordered table-hover">
<tr><td colspan="3"> <tr><td colspan="3">
<div class="signature2"><?= $renderer->renderMethodSignature($method) ?></div> <div class="signature2"><?= $renderer->renderMethodSignature($method) ?></div>
</td></tr> </td></tr>
<?php if (!empty($method->params) || !empty($method->return) || !empty($method->exceptions)): ?> <?php if (!empty($method->params) || !empty($method->return) || !empty($method->exceptions)): ?>
<?php foreach ($method->params as $param): ?> <?php foreach ($method->params as $param): ?>
<tr> <tr>
<td class="paramNameCol"><?= $param->name ?></td> <td class="paramNameCol"><?= ApiMarkdown::highlight($param->name, 'php') ?></td>
<td class="paramTypeCol"><?= $renderer->createTypeLink($param->types) ?></td> <td class="paramTypeCol"><?= $renderer->createTypeLink($param->types) ?></td>
<td class="paramDescCol"><?= ApiMarkdown::process($param->description, $type) ?></td> <td class="paramDescCol"><?= ApiMarkdown::process($param->description, $type) ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
<?php if (!empty($method->return)): ?> <?php if (!empty($method->return)): ?>
<tr> <tr>
<td class="paramNameCol"><?= 'return'; ?></td> <th class="paramNameCol"><?= 'return'; ?></th>
<td class="paramTypeCol"><?= $renderer->createTypeLink($method->returnTypes); ?></td> <td class="paramTypeCol"><?= $renderer->createTypeLink($method->returnTypes); ?></td>
<td class="paramDescCol"><?= ApiMarkdown::process($method->return, $type); ?></td> <td class="paramDescCol"><?= ApiMarkdown::process($method->return, $type); ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
<?php foreach ($method->exceptions as $exception => $description): ?> <?php foreach ($method->exceptions as $exception => $description): ?>
<tr> <tr>
<td class="paramNameCol"><?= 'throws' ?></td> <th class="paramNameCol"><?= 'throws' ?></th>
<td class="paramTypeCol"><?= $renderer->createTypeLink($exception) ?></td> <td class="paramTypeCol"><?= $renderer->createTypeLink($exception) ?></td>
<td class="paramDescCol"><?= ApiMarkdown::process($description, $type) ?></td> <td class="paramDescCol"><?= ApiMarkdown::process($description, $type) ?></td>
</tr> </tr>
......
...@@ -107,12 +107,70 @@ class Collection extends Object ...@@ -107,12 +107,70 @@ class Collection extends Object
{ {
$parts = []; $parts = [];
foreach ($arguments as $argument) { foreach ($arguments as $argument) {
$parts[] = is_scalar($argument) ? $argument : Json::encode($argument); $parts[] = is_scalar($argument) ? $argument : $this->encodeLogData($argument);
} }
return $this->getFullName() . '.' . $command . '(' . implode(', ', $parts) . ')'; return $this->getFullName() . '.' . $command . '(' . implode(', ', $parts) . ')';
} }
/** /**
* Encodes complex log data into JSON format string.
* @param mixed $data raw data.
* @return string encoded data string.
*/
protected function encodeLogData($data)
{
return json_encode($this->processLogData($data));
}
/**
* Pre-processes the log data before sending it to `json_encode()`.
* @param mixed $data raw data.
* @return mixed the processed data.
*/
protected function processLogData($data)
{
if (is_object($data)) {
if ($data instanceof \MongoId ||
$data instanceof \MongoRegex ||
$data instanceof \MongoDate ||
$data instanceof \MongoInt32 ||
$data instanceof \MongoInt64 ||
$data instanceof \MongoTimestamp
) {
$data = get_class($data) . '(' . $data->__toString() . ')';
} elseif ($data instanceof \MongoCode) {
$data = 'MongoCode( ' . $data->__toString() . ' )';
} elseif ($data instanceof \MongoBinData) {
$data = 'MongoBinData(...)';
} elseif ($data instanceof \MongoDBRef) {
$data = 'MongoDBRef(...)';
} elseif ($data instanceof \MongoMinKey || $data instanceof \MongoMaxKey) {
$data = get_class($data);
} else {
$result = [];
foreach ($data as $name => $value) {
$result[$name] = $value;
}
$data = $result;
}
if ($data === []) {
return new \stdClass();
}
}
if (is_array($data)) {
foreach ($data as $key => $value) {
if (is_array($value) || is_object($value)) {
$data[$key] = $this->processLogData($value);
}
}
}
return $data;
}
/**
* Drops this collection. * Drops this collection.
* @throws Exception on failure. * @throws Exception on failure.
* @return boolean whether the operation successful. * @return boolean whether the operation successful.
...@@ -733,7 +791,13 @@ class Collection extends Object ...@@ -733,7 +791,13 @@ class Collection extends Object
$rawId = (string)$rawId; $rawId = (string)$rawId;
} }
} }
return new \MongoId($rawId); try {
$mongoId = new \MongoId($rawId);
} catch (\MongoException $e) {
// invalid id format
$mongoId = $rawId;
}
return $mongoId;
} }
/** /**
......
...@@ -184,6 +184,37 @@ $models = $provider->getModels(); ...@@ -184,6 +184,37 @@ $models = $provider->getModels();
``` ```
Working with embedded documents
-------------------------------
This extension does not provide any special way to work with embedded documents (sub-documents).
General recommendation is avoiding it if possible.
For example: instead of:
```
{
content: "some content",
author: {
name: author1,
email: author1@domain.com
}
}
```
use following:
```
{
content: "some content",
author_name: author1,
author_email: author1@domain.com
}
```
Yii Model designed assuming single attribute is a scalar. Validation and attribute processing based on this suggestion.
Still any attribute can be an array of any depth and complexity, however you should handle its validation on your own.
Using GridFS Using GridFS
------------ ------------
......
...@@ -178,6 +178,16 @@ abstract class ActiveRecord extends \yii\mongodb\ActiveRecord ...@@ -178,6 +178,16 @@ abstract class ActiveRecord extends \yii\mongodb\ActiveRecord
unset($values['file']); unset($values['file']);
} }
if (isset($newFileContent) || isset($newFile)) { if (isset($newFileContent) || isset($newFile)) {
$fileAssociatedAttributeNames = [
'filename',
'uploadDate',
'length',
'chunkSize',
'md5',
'file',
'newFileContent'
];
$values = array_merge($this->getAttributes(null, $fileAssociatedAttributeNames), $values);
$rows = $this->deleteInternal(); $rows = $this->deleteInternal();
$insertValues = $values; $insertValues = $values;
$insertValues['_id'] = $this->getAttribute('_id'); $insertValues['_id'] = $this->getAttribute('_id');
......
...@@ -33,8 +33,8 @@ class TwigSimpleFileLoader implements \Twig_LoaderInterface ...@@ -33,8 +33,8 @@ class TwigSimpleFileLoader implements \Twig_LoaderInterface
/** /**
* Compare a file's freshness with previously stored timestamp * Compare a file's freshness with previously stored timestamp
* *
* @param $name string file name to check * @param string $name file name to check
* @param $time int timestamp to compare with * @param integer $time timestamp to compare with
* @return boolean true if file is still fresh and not changes, false otherwise * @return boolean true if file is still fresh and not changes, false otherwise
*/ */
public function isFresh($name, $time) public function isFresh($name, $time)
......
...@@ -31,7 +31,7 @@ class Widget extends Component implements ViewContextInterface ...@@ -31,7 +31,7 @@ class Widget extends Component implements ViewContextInterface
public static $counter = 0; public static $counter = 0;
/** /**
* @var string the prefix to the automatically generated widget IDs. * @var string the prefix to the automatically generated widget IDs.
* @see [[getId()]] * @see getId()
*/ */
public static $autoIdPrefix = 'w'; public static $autoIdPrefix = 'w';
......
...@@ -419,4 +419,48 @@ class CollectionTest extends MongoDbTestCase ...@@ -419,4 +419,48 @@ class CollectionTest extends MongoDbTestCase
$this->assertNotEmpty($result); $this->assertNotEmpty($result);
$this->assertCount(2, $result); $this->assertCount(2, $result);
} }
/**
* @depends testInsert
* @depends testFind
*/
public function testFindByNotObjectId()
{
$collection = $this->getConnection()->getCollection('customer');
$data = [
'name' => 'customer 1',
'address' => 'customer 1 address',
];
$id = $collection->insert($data);
$cursor = $collection->find(['_id' => (string)$id]);
$this->assertTrue($cursor instanceof \MongoCursor);
$row = $cursor->getNext();
$this->assertEquals($id, $row['_id']);
$cursor = $collection->find(['_id' => 'fake']);
$this->assertTrue($cursor instanceof \MongoCursor);
$this->assertEquals(0, $cursor->count());
}
/**
* @depends testInsert
*
* @see https://github.com/yiisoft/yii2/issues/2548
*/
public function testInsertMongoBin()
{
$collection = $this->getConnection()->getCollection('customer');
$fileName = realpath(__DIR__ . '/../../../../extensions/gii/assets/logo.png');
$data = [
'name' => 'customer 1',
'address' => 'customer 1 address',
'binData' => new \MongoBinData(file_get_contents($fileName), 2),
];
$id = $collection->insert($data);
$this->assertTrue($id instanceof \MongoId);
$this->assertNotEmpty($id->__toString());
}
} }
...@@ -248,6 +248,7 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -248,6 +248,7 @@ class ActiveRecordTest extends MongoDbTestCase
$record2 = CustomerFile::find($record->_id); $record2 = CustomerFile::find($record->_id);
$this->assertEquals($record->status, $record2->status); $this->assertEquals($record->status, $record2->status);
$this->assertEquals(file_get_contents($updateFileName), $record2->getFileContent()); $this->assertEquals(file_get_contents($updateFileName), $record2->getFileContent());
$this->assertEquals($record->tag, $record2->tag);
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment