예제 #1
0
 /// <summary>
 /// Start listing of a directory (intended to be used from C#).
 /// </summary>
 /// <param name="ctx">Runtime context.</param>
 /// <param name="directory">The path to the directory.</param>
 public Directory(Context ctx, string directory)
 {
     this.path   = (PhpValue)directory;
     this.handle = PhpValue.FromClass(PhpDirectory.opendir(ctx, directory));
 }
예제 #2
0
 PhpValue Iterator.current() => PhpValue.FromClass(_list[_element]);
예제 #3
0
        public PhpAlias GetAlias(ref PhpValue value, Context ctx, Type classContext)
        {
            var receiver = PhpValue.EnsureObject(ref value);
            var t        = receiver.GetPhpTypeInfo();

            PhpValue tmp;

            if (BinderHelpers.TryResolveDeclaredProperty(t, classContext, false, Name, out var prop))
            {
                switch (Next.Operation)
                {
                case RuntimeChainOperation.Property:
                    tmp = PhpValue.FromClass(prop.EnsureObject(ctx, receiver));
                    break;

                case RuntimeChainOperation.ArrayItem:
                    tmp = PhpValue.Create(prop.EnsureArray(ctx, receiver));
                    break;

                case RuntimeChainOperation.End:
                    return(prop.EnsureAlias(ctx, receiver));

                default:
                    throw new InvalidOperationException();
                }
            }
            else
            {
                // Template: runtimeflds.Contains(key) ? runtimeflds.EnsureObject(key) : ( __get(key) ?? runtimeflds.EnsureObject(key))

                var runtimeFields = t.GetRuntimeFields(receiver);
                if (runtimeFields == null || !runtimeFields.Contains(Name))
                {
                    //
                    var __get = t.RuntimeMethods[TypeMethods.MagicMethods.__get];
                    if (__get != null)
                    {
                        // NOTE: magic methods must have public visibility, therefore the visibility check is unnecessary

                        // int subkey1 = access.Write() ? 1 : access.Unset() ? 2 : access.Isset() ? 3 : 4;
                        int subkey = Name.GetHashCode() ^ (1 << 4 /*subkey1*/);

                        using (var token = new Context.RecursionCheckToken(ctx, receiver, subkey))
                        {
                            if (!token.IsInRecursion)
                            {
                                tmp = __get.Invoke(ctx, receiver, Name);
                                return(Next.GetAlias(ref tmp, ctx, classContext));
                            }
                        }
                    }
                }

                if (runtimeFields == null)
                {
                    runtimeFields = t.EnsureRuntimeFields(receiver);
                }

                //

                switch (Next.Operation)
                {
                case RuntimeChainOperation.Property:
                    tmp = PhpValue.FromClass(runtimeFields.EnsureItemObject(Name));
                    break;

                case RuntimeChainOperation.ArrayItem:
                    tmp = PhpValue.Create(runtimeFields.EnsureItemArray(Name));
                    break;

                case RuntimeChainOperation.End:
                    return(runtimeFields.EnsureItemAlias(Name));

                default:
                    throw new InvalidOperationException();
                }
            }

            // chain:
            return(Next.GetAlias(ref tmp, ctx, classContext));
        }
예제 #4
0
        public RecursiveFilterIterator getChildren()
        {
            var    childrenIt = ((RecursiveIterator)getInnerIterator()).getChildren();
            object result     = _ctx.Create(default(RuntimeTypeHandle), this.GetPhpTypeInfo(), PhpValue.FromClass(childrenIt));

            return((RecursiveFilterIterator)result);
        }
예제 #5
0
                /// <summary>
                /// Parses the <B>O</B> and <B>C</B> tokens.
                /// </summary>
                /// <param name="serializable">If <B>true</B>, the last token eaten was <B>C</B>, otherwise <B>O</B>.</param>
                object ParseObject(bool serializable)
                {
                    Debug.Assert(_ctx != null);

                    var seq = AddSeq();

                    // :{length}:"{classname}":
                    Consume(Tokens.Colon);                       // :
                    string class_name = ReadString().AsString(); // <length>:"classname"
                    var    tinfo      = _ctx?.GetDeclaredType(class_name, true);

                    // :{count}:
                    Consume(Tokens.Colon);  // :
                    var count = (unchecked ((int)ReadInteger()));

                    if (count < 0)
                    {
                        ThrowInvalidLength();
                    }
                    Consume(Tokens.Colon);

                    // bind to the specified class
                    object obj;

                    if (tinfo != null)
                    {
                        obj = tinfo.GetUninitializedInstance(_ctx);
                        if (obj == null)
                        {
                            throw new ArgumentException(string.Format(LibResources.class_instantiation_failed, class_name));
                        }
                    }
                    else
                    {
                        // TODO: DeserializationCallback
                        // __PHP_Incomplete_Class
                        obj = new __PHP_Incomplete_Class();
                        throw new NotImplementedException("__PHP_Incomplete_Class");
                    }

                    Consume(Tokens.BraceOpen);

                    if (serializable)
                    {
                        // check whether the instance is PHP5.1 Serializable
                        if (!(obj is global::Serializable))
                        {
                            throw new ArgumentException(string.Format(LibResources.class_has_no_unserializer, class_name));
                        }

                        PhpString serializedBytes;
                        if (count > 0)
                        {
                            // add serialized representation to be later passed to unserialize
                            var buffer = new byte[count];
                            if (_stream.Read(buffer, 0, count) < count)
                            {
                                ThrowEndOfStream();
                            }

                            serializedBytes = new PhpString(buffer);
                        }
                        else
                        {
                            serializedBytes = PhpString.Empty;
                        }

                        // Template: Serializable::unserialize(data)
                        ((global::Serializable)obj).unserialize(serializedBytes);
                    }
                    else
                    {
                        // parse properties
                        while (--count >= 0)
                        {
                            // parse property name
                            var nameval = Parse();
                            var pname   = nameval.ToStringOrNull();
                            if (pname == null)
                            {
                                if (!nameval.IsInteger())
                                {
                                    ThrowInvalidDataType();
                                }
                                pname = nameval.ToStringOrThrow(_ctx);
                            }

                            // parse property value
                            var pvalue = Parse();

                            // set property
                            SetProperty(obj, tinfo, pname, pvalue, _ctx);
                        }

                        // __wakeup
                        var __wakeup = tinfo.RuntimeMethods[TypeMethods.MagicMethods.__wakeup];
                        if (__wakeup != null)
                        {
                            __wakeup.Invoke(_ctx, obj);
                        }
                    }

                    Consume(Tokens.BraceClose);

                    //
                    seq.Value = PhpValue.FromClass(obj);
                    return(obj);
                }
예제 #6
0
 void InvokeDefaultHandler(string value = "")
 {
     DefaultHandler?.Invoke(_ctx, PhpValue.FromClass(this), (PhpValue)value);
 }
예제 #7
0
 public override bool accept() => _callback.Invoke(_ctx, current(), key(), PhpValue.FromClass(this)).ToBoolean();
 public virtual PhpValue current() => PhpValue.FromClass(this);
예제 #9
0
        /// <inheritDoc />
        public PhpValue fetch(PDO.PDO_FETCH fetch_style = PDO.PDO_FETCH.FETCH_USE_DEFAULT, int cursor_orientation = default(int), int cursor_offet = 0)
        {
            this.m_pdo.ClearError();

            if (storedQueryResult != null)
            {
                return(FetchFromStored());
            }
            else
            {
                try
                {
                    PDO.PDO_FETCH style = this.m_fetchStyle;

                    if ((int)fetch_style != -1 && Enum.IsDefined(typeof(PDO.PDO_FETCH), fetch_style))
                    {
                        style = (PDO.PDO_FETCH)fetch_style;
                    }
                    PDO.PDO_FETCH_ORI ori = PDO.PDO_FETCH_ORI.FETCH_ORI_NEXT;
                    if (Enum.IsDefined(typeof(PDO.PDO_FETCH_ORI), cursor_orientation))
                    {
                        ori = (PDO.PDO_FETCH_ORI)cursor_orientation;
                    }

                    switch (ori)
                    {
                    case PDO.PDO_FETCH_ORI.FETCH_ORI_NEXT:
                        break;

                    default:
                        throw new NotSupportedException();
                    }

                    if (!this.m_dr.Read())
                    {
                        return(PhpValue.False);
                    }

                    // Get the column schema, if possible, for the associative fetch
                    if (this.m_dr_names == null)
                    {
                        this.m_dr_names = new string[m_dr.FieldCount];

                        if (this.m_dr.CanGetColumnSchema())
                        {
                            var columnSchema = this.m_dr.GetColumnSchema();

                            for (int i = 0; i < m_dr.FieldCount; i++)
                            {
                                this.m_dr_names[i] = columnSchema[i].ColumnName;
                            }
                        }
                        else
                        {
                            for (int i = 0; i < m_dr.FieldCount; i++)
                            {
                                this.m_dr_names[i] = this.m_dr.GetName(i);
                            }
                        }
                    }

                    switch (style)
                    {
                    case PDO.PDO_FETCH.FETCH_OBJ:
                        return(this.ReadObj());

                    case PDO.PDO_FETCH.FETCH_ASSOC:
                        return(PhpValue.Create(this.ReadArray(true, false)));

                    case PDO.PDO_FETCH.FETCH_BOTH:
                    case PDO.PDO_FETCH.FETCH_USE_DEFAULT:
                        return(PhpValue.Create(this.ReadArray(true, true)));

                    case PDO.PDO_FETCH.FETCH_NUM:
                        return(PhpValue.Create(this.ReadArray(false, true)));

                    case PDO.PDO_FETCH.FETCH_COLUMN:
                        if (FetchColNo != -1)
                        {
                            m_pdo.HandleError(new PDOException("The column number for FETCH_COLUMN mode is not set."));
                            return(PhpValue.False);
                        }

                        return(this.ReadArray(false, true)[FetchColNo].GetValue());

                    case PDO.PDO_FETCH.FETCH_CLASS:
                        if (FetchClassName == null)
                        {
                            m_pdo.HandleError(new PDOException("The className for FETCH_CLASS mode is not set."));
                            return(PhpValue.False);
                        }

                        var obj = _ctx.Create(FetchClassName, FetchClassCtorArgs ?? Array.Empty <PhpValue>());
                        return(PhpValue.FromClass(obj));

                    default:
                        throw new NotImplementedException();
                    }
                }
                catch (System.Exception ex)
                {
                    this.m_pdo.HandleError(ex);
                    return(PhpValue.False);
                }
            }
        }
예제 #10
0
        PhpValue /*object|array|WP_Error*/ PluginsApi(PhpValue result, string action, object args)
        {
            var arr = (PhpArray)PhpValue.FromClass(args);
            var log = NuGet.Common.NullLogger.Instance;

            switch (action)
            {
            case "query_plugins":

                var results = SearchFeed(arr, WpPluginPackageType, out var page, out var per_page, out var totalHits).ToList();

                return(PhpValue.FromClass(new QueryPluginsResult
                {
                    info = new PhpArray()
                    {
                        { "page", page },
                        { "pages", (totalHits / per_page) + ((totalHits % per_page) == 0 ? 0 : 1) },
                        { "results", results.Count },
                    },
                    plugins = new PhpArray(results.Select(_ => new PluginResult(_))),
                }));

            case "plugin_information":

                var versions = RegistrationResourceV3.GetPackageMetadata(PluginResult.SlugToId(arr["slug"].ToString()), true, true, log, CancellationToken.None)
                               .Result
                               .Select(PackageSearchMetadataFromJObject);
                var p = versions.LastOrDefault();

                //var p = PackageMetadataResource.GetMetadataAsync(new PackageIdentity(arr["slug"].ToString(), new NuGet.Versioning.NuGetVersion("")), log, CancellationToken.None).Result;
                if (p != null)
                {
                    var packageBaseAddress = ServiceIndexResourceV3.GetServiceEntryUri(ServiceTypes.PackageBaseAddress)?.AbsoluteUri;
                    var id      = p.Identity.Id.ToLowerInvariant();
                    var version = p.Identity.Version.ToNormalizedString().ToLowerInvariant();
                    var url     = $"{packageBaseAddress}/{id}/{version}/{id}.{version}.nupkg";

                    return(PhpValue.FromClass(new PluginResult(p)
                    {
                        download_link = url
                    }));
                }
                else
                {
                    return(PhpValue.Null);
                }

            case "hot_tags":
            case "hot_categories":
                // // stdClass { "name" => array("name", "slug", "count") }
                // return PhpValue.FromClass(
                //     new PhpArray()
                //     {

                //     }.AsStdClass()
                // );
                return(false);    // -> use regular WP API

            default:
                throw new ArgumentException(nameof(action));
            }
        }
예제 #11
0
        /// <summary>
        /// Defines WordPress configuration constants and initializes runtime before proceeding to <c>index.php</c>.
        /// </summary>
        static void Apply(Context ctx, WordPressConfig config, WpLoader loader)
        {
            // see wp-config.php:

            // WordPress Database Table prefix.
            ctx.Globals["table_prefix"] = (PhpValue)config.DbTablePrefix; // $table_prefix  = 'wp_';

            // SALT
            ctx.DefineConstant("AUTH_KEY", (PhpValue)config.SALT.AUTH_KEY);
            ctx.DefineConstant("SECURE_AUTH_KEY", (PhpValue)config.SALT.SECURE_AUTH_KEY);
            ctx.DefineConstant("LOGGED_IN_KEY", (PhpValue)config.SALT.LOGGED_IN_KEY);
            ctx.DefineConstant("NONCE_KEY", (PhpValue)config.SALT.NONCE_KEY);
            ctx.DefineConstant("AUTH_SALT", (PhpValue)config.SALT.AUTH_SALT);
            ctx.DefineConstant("SECURE_AUTH_SALT", (PhpValue)config.SALT.SECURE_AUTH_SALT);
            ctx.DefineConstant("LOGGED_IN_SALT", (PhpValue)config.SALT.LOGGED_IN_SALT);
            ctx.DefineConstant("NONCE_SALT", (PhpValue)config.SALT.NONCE_SALT);

            if (!string.IsNullOrEmpty(config.SiteUrl))
            {
                ctx.DefineConstant("WP_SITEURL", config.SiteUrl);
            }

            if (!string.IsNullOrEmpty(config.HomeUrl))
            {
                ctx.DefineConstant("WP_HOME", config.HomeUrl);
            }

            // multisite
            if (config.Multisite.Allow)
            {
                ctx.DefineConstant("WP_ALLOW_MULTISITE", (PhpValue)config.Multisite.Allow);
            }

            if (config.Multisite.Enable)
            {
                ctx.DefineConstant("MULTISITE", (PhpValue)config.Multisite.Enable);
                ctx.DefineConstant("SUBDOMAIN_INSTALL", (PhpValue)config.Multisite.DomainCurrentSite);
                ctx.DefineConstant("DOMAIN_CURRENT_SITE", (PhpValue)config.Multisite.DomainCurrentSite);
                ctx.DefineConstant("PATH_CURRENT_SITE", (PhpValue)config.Multisite.PathCurrentSite);
                ctx.DefineConstant("SITE_ID_CURRENT_SITE", (PhpValue)config.Multisite.SiteIDCurrentSite);
                ctx.DefineConstant("BLOG_ID_CURRENT_SITE", (PhpValue)config.Multisite.BlogIDCurrentSite);
            }

            // Additional constants
            if (config.Constants != null)
            {
                foreach (var pair in config.Constants)
                {
                    ctx.DefineConstant(pair.Key, pair.Value);
                }
            }

            // $peachpie-wp-loader : WpLoader
            ctx.Globals["peachpie_wp_loader"] = PhpValue.FromClass(loader);

            // workaround HTTPS under proxy,
            // set $_SERVER['HTTPS'] = 'on'
            // https://wordpress.org/support/article/administration-over-ssl/#using-a-reverse-proxy
            if (ctx.IsWebApplication && ctx.GetHttpContext().Request.Headers["X-Forwarded-Proto"] == "https")
            {
                ctx.Server["HTTPS"] = "on";
            }
        }
 PhpValue IPhpCallable.ToPhpValue() => PhpValue.FromClass(this);
예제 #13
0
 public static void DashboardWidget(this WpApp app, string widget_id, string widget_name, Action <TextWriter> htmlwriter)
 {
     app.AddFilter(
         "wp_dashboard_setup",
         new Action(() => app.Context.Call("wp_add_dashboard_widget",
                                           (PhpValue)widget_id, (PhpValue)widget_name, PhpValue.FromClass(new Action(() => htmlwriter(app.Context.Output))))));
 }
예제 #14
0
            private void ParseStep(XmlReader reader, Stack <ElementRecord> elementStack, ref TextRecord textChunk, PhpArray values, PhpArray indices)
            {
                string        elementName;
                bool          emptyElement;
                ElementRecord currentElementRecord = null;

                switch (reader.NodeType)
                {
                case XmlNodeType.Element:
                    elementName  = reader.Name;
                    emptyElement = reader.IsEmptyElement;
                    PhpArray attributeArray = new PhpArray();

                    //if (_processNamespaces && elementName.IndexOf(":") >= 0)
                    //{
                    //    string localName = elementName.Substring(elementName.IndexOf(":") + 1);
                    //    elementName = reader.NamespaceURI + _namespaceSeparator + localName;
                    //}

                    if (reader.MoveToFirstAttribute())
                    {
                        do
                        {
                            if (_processNamespaces && reader.Name.StartsWith("xmlns:"))
                            {
                                string namespaceID  = reader.Name.Substring(6);
                                string namespaceUri = reader.Value;

                                if (StartNamespaceDeclHandler != null)
                                {
                                    StartNamespaceDeclHandler.Invoke(_ctx, PhpValue.FromClass(this), (PhpValue)namespaceID, (PhpValue)namespaceUri);
                                }

                                continue;
                            }

                            attributeArray.Add(EnableCaseFolding ? reader.Name.ToUpperInvariant() : reader.Name, reader.Value);
                        }while (reader.MoveToNextAttribute());
                    }

                    // update current top of stack
                    if (elementStack.Count != 0)
                    {
                        currentElementRecord = elementStack.Peek();

                        UpdateValueAndIndexArrays(currentElementRecord, ref textChunk, values, indices, true);

                        if (currentElementRecord.State == ElementState.Beginning)
                        {
                            currentElementRecord.State = ElementState.Interior;
                        }
                    }

                    // push the element into the stack (needed for parse_into_struct)
                    elementStack.Push(
                        new ElementRecord()
                    {
                        ElementName = elementName,
                        Level       = reader.Depth,
                        State       = ElementState.Beginning,
                        Attributes  = (PhpArray)attributeArray.DeepCopy()
                    });

                    if (StartElementHandler != null)
                    {
                        StartElementHandler.Invoke(_ctx, PhpValue.FromClass(this), (PhpValue)(EnableCaseFolding ? elementName.ToUpperInvariant() : elementName), (PhpValue)attributeArray);
                    }
                    else
                    {
                        InvokeDefaultHandler();
                    }

                    if (emptyElement)
                    {
                        goto case XmlNodeType.EndElement;                      // and end the element immediately (<element/>, XmlNodeType.EndElement will not be called)
                    }
                    break;


                case XmlNodeType.EndElement:
                    elementName = reader.Name;

                    //if (_processNamespaces && elementName.IndexOf(":") >= 0)
                    //{
                    //    string localName = elementName.Substring(elementName.IndexOf(":") + 1);
                    //    elementName = reader.NamespaceURI + _namespaceSeparator + localName;
                    //}

                    // pop the top element record
                    currentElementRecord = elementStack.Pop();

                    UpdateValueAndIndexArrays(currentElementRecord, ref textChunk, values, indices, false);

                    if (EndElementHandler != null)
                    {
                        EndElementHandler.Invoke(_ctx, PhpValue.FromClass(this), (PhpValue)(EnableCaseFolding ? elementName.ToUpperInvariant() : elementName));
                    }
                    else
                    {
                        InvokeDefaultHandler();
                    }
                    break;


                case XmlNodeType.Whitespace:
                case XmlNodeType.Text:
                case XmlNodeType.CDATA:
                    if (textChunk == null)
                    {
                        textChunk = new TextRecord()
                        {
                            Text = reader.Value
                        };
                    }
                    else
                    {
                        textChunk.Text += reader.Value;
                    }

                    if (CharacterDataHandler != null)
                    {
                        CharacterDataHandler.Invoke(_ctx, PhpValue.FromClass(this), (PhpValue)reader.Value);
                    }
                    else
                    {
                        InvokeDefaultHandler(reader.Value);
                    }
                    break;

                case XmlNodeType.ProcessingInstruction:

                    if (ProcessingInstructionHandler != null)
                    {
                        ProcessingInstructionHandler.Invoke(_ctx, PhpValue.FromClass(this), (PhpValue)reader.Name, (PhpValue)reader.Value);
                    }
                    else
                    {
                        InvokeDefaultHandler();
                    }
                    break;
                }
            }
예제 #15
0
        protected override void DoAction(int action)
        {
            switch (action)
            {
            case 2: // start -> value
            { Result = (PhpValue)value_stack.array[value_stack.top - 1].yyval.obj; }
                return;

            case 3: // object -> OBJECT_OPEN members OBJECT_CLOSE
            {
                var elements = (List <KeyValuePair <string, PhpValue> >)value_stack.array[value_stack.top - 2].yyval.obj;
                var arr      = new PhpArray(elements.Count);

                foreach (var item in elements)
                {
                    arr.Add(Core.Convert.StringToArrayKey(item.Key), item.Value);
                }

                if (decodeOptions.Assoc)
                {
                    yyval.obj = PhpValue.Create(arr);
                }
                else
                {
                    yyval.obj = PhpValue.FromClass(arr.ToClass());
                }
            }
                return;

            case 4: // object -> OBJECT_OPEN OBJECT_CLOSE
            { yyval.obj = PhpValue.FromClass(new stdClass()); }
                return;

            case 5: // members -> pair ITEMS_SEPARATOR members
            {
                var elements = (List <KeyValuePair <string, PhpValue> >)value_stack.array[value_stack.top - 1].yyval.obj;
                var result   = new List <KeyValuePair <string, PhpValue> >(elements.Count + 1)
                {
                    (KeyValuePair <string, PhpValue>)value_stack.array[value_stack.top - 3].yyval.obj
                };
                result.AddRange(elements);
                yyval.obj = result;
            }
                return;

            case 6: // members -> pair
            { yyval.obj = new List <KeyValuePair <string, PhpValue> >()
              {
                  (KeyValuePair <string, PhpValue>)value_stack.array[value_stack.top - 1].yyval.obj
              }; }
                return;

            case 7: // pair -> STRING NAMEVALUE_SEPARATOR value
            { yyval.obj = new KeyValuePair <string, PhpValue>((string)value_stack.array[value_stack.top - 3].yyval.obj, (PhpValue)value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 8: // array -> ARRAY_OPEN elements ARRAY_CLOSE
            {
                var elements = (List <PhpValue>)value_stack.array[value_stack.top - 2].yyval.obj;
                var arr      = new PhpArray(elements.Count);

                foreach (var item in elements)
                {
                    arr.Add(item);
                }

                yyval.obj = arr;
            }
                return;

            case 9: // array -> ARRAY_OPEN ARRAY_CLOSE
            { yyval.obj = PhpArray.NewEmpty(); }
                return;

            case 10: // elements -> value ITEMS_SEPARATOR elements
            {
                var elements = (List <PhpValue>)value_stack.array[value_stack.top - 1].yyval.obj;
                var result   = new List <PhpValue>(elements.Count + 1)
                {
                    (PhpValue)value_stack.array[value_stack.top - 3].yyval.obj
                };
                result.AddRange(elements);
                yyval.obj = result;
            }
                return;

            case 11: // elements -> value
            { yyval.obj = new List <PhpValue>()
              {
                  (PhpValue)value_stack.array[value_stack.top - 1].yyval.obj
              }; }
                return;

            case 12: // value -> STRING
            { yyval.obj = PhpValue.Create((string)value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 13: // value -> INTEGER
            { yyval.obj = PhpValue.FromClr(value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 14: // value -> DOUBLE
            { yyval.obj = PhpValue.FromClr(value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 15: // value -> object
            { yyval.obj = (PhpValue)value_stack.array[value_stack.top - 1].yyval.obj; }
                return;

            case 16: // value -> array
            { yyval.obj = PhpValue.Create((PhpArray)value_stack.array[value_stack.top - 1].yyval.obj); }
                return;

            case 17: // value -> TRUE
            { yyval.obj = PhpValue.True; }
                return;

            case 18: // value -> FALSE
            { yyval.obj = PhpValue.False; }
                return;

            case 19: // value -> NULL
            { yyval.obj = PhpValue.Null; }
                return;
            }
        }
예제 #16
0
 private PhpValue ReadObj()
 {
     return(PhpValue.FromClass(this.ReadArray(true, false).ToClass()));
 }
예제 #17
0
        static async Task <PhpValue> ProcessResponse(Context ctx, CURLResource ch, HttpWebResponse response)
        {
            // in case we are returning the response value
            var returnstream = ch.ProcessingResponse.Method == ProcessMethodEnum.RETURN
                ? new MemoryStream()
                : null;

            // handle headers
            if (!ch.ProcessingHeaders.IsEmpty)
            {
                var    statusHeaders       = HttpHeaders.StatusHeader(response) + HttpHeaders.HeaderSeparator; // HTTP/1.1 xxx xxx\r\n
                Stream outputHeadersStream = null;

                switch (ch.ProcessingHeaders.Method)
                {
                case ProcessMethodEnum.RETURN:
                case ProcessMethodEnum.STDOUT:
                    outputHeadersStream = (returnstream ?? ctx.OutputStream);
                    goto default;

                case ProcessMethodEnum.FILE:
                    outputHeadersStream = ch.ProcessingHeaders.Stream.RawStream;
                    goto default;

                case ProcessMethodEnum.USER:
                    // pass headers one by one,
                    // in original implementation we should pass them as they are read from socket:

                    ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                        PhpValue.FromClass(ch),
                        PhpValue.Create(statusHeaders)
                    });

                    for (int i = 0; i < response.Headers.Count; i++)
                    {
                        var key   = response.Headers.GetKey(i);
                        var value = response.Headers.Get(i);

                        if (key == null || key.Length != 0)
                        {
                            // header
                            ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                                PhpValue.FromClr(ch),
                                PhpValue.Create(key + ": " + value + HttpHeaders.HeaderSeparator),
                            });
                        }
                    }

                    // \r\n
                    ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                        PhpValue.FromClr(ch),
                        PhpValue.Create(HttpHeaders.HeaderSeparator)
                    });

                    break;

                default:
                    if (outputHeadersStream != null)
                    {
                        await outputHeadersStream.WriteAsync(Encoding.ASCII.GetBytes(statusHeaders));

                        await outputHeadersStream.WriteAsync(response.Headers.ToByteArray());
                    }
                    else
                    {
                        Debug.Fail("Unexpected ProcessingHeaders " + ch.ProcessingHeaders.Method);
                    }
                    break;
                }
            }

            var stream = response.GetResponseStream();

            // gzip decode if necessary
            if (response.ContentEncoding == "gzip") // TODO: // && ch.AcceptEncoding.Contains("gzip") ??
            {
                ch.VerboseOutput("Decompressing the output stream using GZipStream.");
                stream = new GZipStream(stream, CompressionMode.Decompress, leaveOpen: false);
            }

            // read into output stream:
            switch (ch.ProcessingResponse.Method)
            {
            case ProcessMethodEnum.STDOUT: await stream.CopyToAsync(ctx.OutputStream); break;

            case ProcessMethodEnum.RETURN: stream.CopyTo(returnstream); break;

            case ProcessMethodEnum.FILE: await stream.CopyToAsync(ch.ProcessingResponse.Stream.RawStream); break;

            case ProcessMethodEnum.USER:
                if (response.ContentLength != 0)
                {
                    // preallocate a buffer to read to,
                    // this should be according to PHP's behavior and slightly more effective than memory stream
                    byte[] buffer = new byte[ch.BufferSize > 0 ? ch.BufferSize : 2048];
                    int    bufferread;

                    while ((bufferread = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ch.ProcessingResponse.User.Invoke(ctx, new[]
                        {
                            PhpValue.FromClr(ch),
                            PhpValue.Create(new PhpString(buffer.AsSpan(0, bufferread).ToArray())),     // clone the array and pass to function
                        });
                    }
                }
                break;

            case ProcessMethodEnum.IGNORE: break;
            }

            //
            stream.Dispose();
            stream = null;

            //

            return((returnstream != null)
                ? PhpValue.Create(new PhpString(returnstream.ToArray()))
                : PhpValue.True);
        }
예제 #18
0
        PhpValue /*object|array|WP_Error*/ PluginsApi(PhpValue result, string action, object args)
        {
            var arr = (PhpArray)PhpValue.FromClass(args);
            var log = NuGet.Common.NullLogger.Instance;

            switch (action)
            {
            case "query_plugins":

                int page     = (int)arr["page"] - 1;
                int per_page = (int)arr["per_page"];

                var searchFilter = new SearchFilter(true);

                // arr[browse|search|author|tag]
                var browse     = arr["browse"].AsString();
                var searchTerm = arr["search"].AsString() ?? arr["author"].AsString() ?? arr["tag"].AsString() ?? string.Empty;

                if (browse != null)
                {
                    switch (browse)
                    {
                    case "beta":
                    case "featured":
                    //case "popular":
                    case "recommended":         // = premium
                    default:
                        break;
                    }

                    searchFilter = new SearchFilter(includePrerelease: browse == "beta");
                }

                searchFilter.PackageTypes = WpPluginPackageType;

                //var results = PackageSearchResource.SearchAsync(
                //    "", new SearchFilter(true),
                //    skip: page * per_page, take: per_page, log: null, cancellationToken: CancellationToken.None).Result.ToList();

                // TODO: list versions that are compatible with current wpdotnet ?

                var raw     = RawSearchResourceV3.SearchPage(searchTerm, searchFilter, page * per_page, per_page, log, CancellationToken.None).Result;
                var results = (raw[JsonProperties.Data] as JArray ?? Enumerable.Empty <JToken>())
                              .OfType <JObject>()
                              .Select(PackageSearchMetadataFromJObject)
                              .ToList();
                var totalHits = raw["totalHits"].ToObject <int>();

                return(PhpValue.FromClass(new QueryPluginsResult
                {
                    info = new PhpArray()
                    {
                        { "page", page },
                        { "pages", (totalHits / per_page) + ((totalHits % per_page) == 0 ? 0 : 1) },
                        { "results", results.Count },
                    },
                    plugins = new PhpArray(results.Select(_ => new PluginResult(_))),
                }));

            case "plugin_information":

                var p = RegistrationResourceV3.GetPackageMetadata(PluginResult.SlugToId(arr["slug"].ToString()), true, true, log, CancellationToken.None)
                        .Result
                        .Select(PackageSearchMetadataFromJObject)
                        .FirstOrDefault();

                //var p = PackageMetadataResource.GetMetadataAsync(new PackageIdentity(arr["slug"].ToString(), new NuGet.Versioning.NuGetVersion("")), log, CancellationToken.None).Result;
                if (p != null)
                {
                    var packageBaseAddress = ServiceIndexResourceV3.GetServiceEntryUri(ServiceTypes.PackageBaseAddress)?.AbsoluteUri;
                    var id      = p.Identity.Id.ToLowerInvariant();
                    var version = p.Identity.Version.ToNormalizedString().ToLowerInvariant();
                    var url     = $"{packageBaseAddress}/{id}/{version}/{id}.{version}.nupkg";

                    var plugin = new PluginResult(p);
                    plugin.download_link = url;
                    return(PhpValue.FromClass(plugin));
                }
                else
                {
                    return(PhpValue.Null);
                }

            case "hot_tags":
            case "hot_categories":
                return(PhpValue.Null);

            default:
                throw new ArgumentException(nameof(action));
            }
        }