Commit c9edea3d by AlexGx

merge

parents 32d07689 10f1283d
......@@ -45,5 +45,7 @@ script:
- cd apps/basic && php vendor/bin/codecept run
after_script:
- cd ../..
- pwd
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
......@@ -381,6 +381,7 @@ the `self` link, for example:
```php
use yii\db\ActiveRecord;
use yii\web\Link;
use yii\web\Linkable;
use yii\helpers\Url;
......
......@@ -93,7 +93,7 @@ class ApiMarkdown extends GithubMarkdown
}
}
protected function highlight($code, $language)
public static function highlight($code, $language)
{
if ($language !== 'php') {
return htmlspecialchars($code, ENT_NOQUOTES, 'UTF-8');
......
......@@ -58,3 +58,8 @@ blockquote {
td p {
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 @@
namespace yii\apidoc\templates\html;
use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\MethodDoc;
use yii\apidoc\models\PropertyDoc;
use yii\apidoc\models\ClassDoc;
......@@ -225,7 +226,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface
}
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
return ($method->isReturnByReference ? '<b>&</b>' : '')
. ($method->returnType === null ? 'void' : $this->createTypeLink($method->returnTypes))
. ' ' . $this->createSubjectLink($method, $method->name) . '( '
. implode(', ', $params)
. ' )';
. ' ' . $this->createSubjectLink($method, $method->name)
. ApiMarkdown::highlight('( ' . implode(', ', $params) . ' )', 'php');
}
public function generateApiUrl($typeName)
......
......@@ -34,28 +34,28 @@ ArrayHelper::multisort($methods, 'name');
</span>
</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">
<div class="signature2"><?= $renderer->renderMethodSignature($method) ?></div>
</td></tr>
<?php if (!empty($method->params) || !empty($method->return) || !empty($method->exceptions)): ?>
<?php foreach ($method->params as $param): ?>
<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="paramDescCol"><?= ApiMarkdown::process($param->description, $type) ?></td>
</tr>
<?php endforeach; ?>
<?php if (!empty($method->return)): ?>
<tr>
<td class="paramNameCol"><?= 'return'; ?></td>
<th class="paramNameCol"><?= 'return'; ?></th>
<td class="paramTypeCol"><?= $renderer->createTypeLink($method->returnTypes); ?></td>
<td class="paramDescCol"><?= ApiMarkdown::process($method->return, $type); ?></td>
</tr>
<?php endif; ?>
<?php foreach ($method->exceptions as $exception => $description): ?>
<tr>
<td class="paramNameCol"><?= 'throws' ?></td>
<th class="paramNameCol"><?= 'throws' ?></th>
<td class="paramTypeCol"><?= $renderer->createTypeLink($exception) ?></td>
<td class="paramDescCol"><?= ApiMarkdown::process($description, $type) ?></td>
</tr>
......
......@@ -107,12 +107,70 @@ class Collection extends Object
{
$parts = [];
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) . ')';
}
/**
* 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.
* @throws Exception on failure.
* @return boolean whether the operation successful.
......@@ -733,7 +791,13 @@ class Collection extends Object
$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();
```
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
------------
......
......@@ -178,6 +178,16 @@ abstract class ActiveRecord extends \yii\mongodb\ActiveRecord
unset($values['file']);
}
if (isset($newFileContent) || isset($newFile)) {
$fileAssociatedAttributeNames = [
'filename',
'uploadDate',
'length',
'chunkSize',
'md5',
'file',
'newFileContent'
];
$values = array_merge($this->getAttributes(null, $fileAssociatedAttributeNames), $values);
$rows = $this->deleteInternal();
$insertValues = $values;
$insertValues['_id'] = $this->getAttribute('_id');
......
......@@ -33,8 +33,8 @@ class TwigSimpleFileLoader implements \Twig_LoaderInterface
/**
* Compare a file's freshness with previously stored timestamp
*
* @param $name string file name to check
* @param $time int timestamp to compare with
* @param string $name file name to check
* @param integer $time timestamp to compare with
* @return boolean true if file is still fresh and not changes, false otherwise
*/
public function isFresh($name, $time)
......
......@@ -31,7 +31,7 @@ class Widget extends Component implements ViewContextInterface
public static $counter = 0;
/**
* @var string the prefix to the automatically generated widget IDs.
* @see [[getId()]]
* @see getId()
*/
public static $autoIdPrefix = 'w';
......
......@@ -419,4 +419,48 @@ class CollectionTest extends MongoDbTestCase
$this->assertNotEmpty($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
$record2 = CustomerFile::find($record->_id);
$this->assertEquals($record->status, $record2->status);
$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