Как стать автором
Обновить

Комментарии 16

Занятная штука :)
Спасибо, Александр! :) Надеюсь с вашей стороны претензий по правам не будет :-)
Лично с моей нет, но вообще вы умудрились, конечно, нарушить, единственный запрещающий пункт лицензии BSD :)
Признаться, так и не понял, что именно в лицензии нарушено.
Думаю имелся ввиду этот пункт:
Neither the name of Yii Software LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

Запрещено использовать имя Yii для продвижения своего проекта без письменного разрешения
Это при условии, что derived — то есть производный продукт. Похожий API — это никак не производный продукт. Вот если там есть блоки кода, выглядящие как 1 в 1 спортированные с РНР на JS — тогда ага, ой.:-)
Вот если там есть блоки кода, выглядящие как 1 в 1 спортированные с РНР на JS — тогда ага, ой.:-)

Я Вам больше скажу, там даже комментарии 1 в 1. Вот пример:
Jii.js
/**
     * Translates a path alias into an actual path.
     *
     * The translation is done according to the following procedure:
     *
     * 1. If the given alias does not start with '@', it is returned back without change;
     * 2. Otherwise, look for the longest registered alias that matches the beginning part
     *    of the given alias. If it exists, replace the matching part of the given alias with
     *    the corresponding registered path.
     * 3. Throw an exception or return false, depending on the `$throwException` parameter.
     *
     * For example, by default '@jii' is registered as the alias to the Jii framework directory,
     * say '/path/to/jii'. The alias '@jii/web' would then be translated into '/path/to/jii/web'.
     *
     * If you have registered two aliases '@foo' and '@foo/bar'. Then translating '@foo/bar/config'
     * would replace the part '@foo/bar' (instead of '@foo') with the corresponding registered path.
     * This is because the longest alias takes precedence.
     *
     * However, if the alias to be translated is '@foo/barbar/config', then '@foo' will be replaced
     * instead of '@foo/bar', because '/' serves as the boundary character.
     *
     * Note, this method does not check if the returned path exists or not.
     *
     * @param {string} alias the alias to be translated.
     * @param {boolean} [throwException] whether to throw an exception if the given alias is invalid.
     * If this is false and an invalid alias is given, false will be returned by this method.
     * @return {string|boolean} the path corresponding to the alias, false if the root alias is not previously registered.
     * @throws {Jii.exceptions.InvalidParamException} if the alias is invalid while throwException is true.
     * @see setAlias()
     */
     getAlias: function (alias, throwException) {
          if (Jii._.isUndefined(throwException)) {
               throwException = true;
          }

          if (alias.indexOf('@') !== 0) {
               return alias;
          }

          var index = alias.indexOf('/');
          var root = index === -1 ? alias : alias.substr(0, index);

          if (Jii._.has(this.aliases, root)) {
               if (Jii._.isString(this.aliases[root])) {
                    return this.aliases[root] + (index !== -1 ? alias.substr(index) : '');
               }

               var finedPath = null;
               Jii._.each(this.aliases[root], function (path, name) {
                    var testAlias = alias + '/';
                    if (testAlias.indexOf(name + '/') === 0) {
                         finedPath = path + alias.substr(name.length);
                         return false;
                    }
               });
               if (finedPath !== null) {
                    return finedPath;
               }
          }

          if (throwException) {
               throw new Jii.exceptions.InvalidParamException('Invalid path alias: ' + alias);
          }
          return false;
     }


BaseYii.php
/**
     * Translates a path alias into an actual path.
     *
     * The translation is done according to the following procedure:
     *
     * 1. If the given alias does not start with '@', it is returned back without change;
     * 2. Otherwise, look for the longest registered alias that matches the beginning part
     *    of the given alias. If it exists, replace the matching part of the given alias with
     *    the corresponding registered path.
     * 3. Throw an exception or return false, depending on the `$throwException` parameter.
     *
     * For example, by default '@yii' is registered as the alias to the Yii framework directory,
     * say '/path/to/yii'. The alias '@yii/web' would then be translated into '/path/to/yii/web'.
     *
     * If you have registered two aliases '@foo' and '@foo/bar'. Then translating '@foo/bar/config'
     * would replace the part '@foo/bar' (instead of '@foo') with the corresponding registered path.
     * This is because the longest alias takes precedence.
     *
     * However, if the alias to be translated is '@foo/barbar/config', then '@foo' will be replaced
     * instead of '@foo/bar', because '/' serves as the boundary character.
     *
     * Note, this method does not check if the returned path exists or not.
     *
     * @param string $alias the alias to be translated.
     * @param boolean $throwException whether to throw an exception if the given alias is invalid.
     * If this is false and an invalid alias is given, false will be returned by this method.
     * @return string|boolean the path corresponding to the alias, false if the root alias is not previously registered.
     * @throws InvalidParamException if the alias is invalid while $throwException is true.
     * @see setAlias()
     */
    public static function getAlias($alias, $throwException = true)
    {
        if (strncmp($alias, '@', 1)) {
            // not an alias
            return $alias;
        }

        $pos = strpos($alias, '/');
        $root = $pos === false ? $alias : substr($alias, 0, $pos);

        if (isset(static::$aliases[$root])) {
            if (is_string(static::$aliases[$root])) {
                return $pos === false ? static::$aliases[$root] : static::$aliases[$root] . substr($alias, $pos);
            } else {
                foreach (static::$aliases[$root] as $name => $path) {
                    if (strpos($alias . '/', $name . '/') === 0) {
                        return $path . substr($alias, strlen($name));
                    }
                }
            }
        }

        if ($throwException) {
            throw new InvalidParamException("Invalid path alias: $alias");
        } else {
            return false;
        }
    }


Но тем не менее идея автора мне нравится.
Как я понимаю, программа на javascript никак не может быть производной от программы на php. Даже при наличии похожего кода — он не может по определению выглядеть 1 в 1. Лицензия BSD запрещает использование названия Yii Software LLC и имен сотрудников в качестве поддержки или продвижения продуктов, основанных на этом ПО (кстати, я и не вижу такого использования), но этот пункт тут не подходит — Jii по определению не основан на Yii.
Ждем Rubii, Pythii, Cii и Luii =)
Прикольно, помнится как то давно был такой фреймворк autodafe, тоже пытался повторить yii 1.x на ноде. Затух.
«для указания сложных индексов, вы можете передать в метод Jii.sql.Query.indexBy() анонимную функцию:… return row.id + row.username; „

А можете подробней расказать в каких случаях будет полезным использование таких кастомных индексов?

имхо:
Конструкции вида: “ORDER BY ((c_sent + 1) * online_coef * geo_coef * search_coef * premium_coef) ASC» хоть синтаксически правельны, но… мне жалко MySQL ((. Считаю, что такие конструкции в запросе нужно использовать «с пониманием» и если это действительно очень необходимо. Пока к сожалению я не придумал реальных случаев, когда это может быть полезным.

Мне кажется, вы не о тех индексах говорите. Здесь имеются ввиду индексы (ключи) объекта на выходе. Внутри это выглядит так:

populate: function (rows) {
		if (this._indexBy === null) {
			return rows;
		}

		var result = {};
		Jii._.each(rows, Jii._.bind(function(row) {
			var key = Jii._.isString(this._indexBy) ?
				row[this._indexBy] :
				this._indexBy(row);

			result[key] = row;
		}, this));

		return result;
	},


На само SQL выражение вызов indexBy() никак не влияет.
Тоесть метод indexBy выполняет лишь пост сортировку результатов выполнения запроса в базе?
Выходит, что бесмысленно использовать вместе методы orderBy и indexBy. Вроде как оба сортируют результат выборки, но… есть нюанс))
indexBy() не делает сортировку, он расставляет индексы в результат запроса. Без него на выходе — массив, а с ним — объект.
Но вообще да, обычно их оба использовать не имеет смысл.
Думаю проще сказать indexBy принимает функцию редьюсер
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории